package store

type Message struct {
	ID        int64
	RoomID    string
	Agent     string
	Role      string
	Content   string
	Filename  string
	Title     string
	GroupID   *int64
	CreatedAt string
	PartType  string
}

type FileVersion struct {
	ID        int64
	RoomID    string
	Filename  string
	Content   string
	Agent     string
	Version   int
	CreatedAt string
}

func (s *Store) InsertMessage(msg *Message) (int64, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	partType := msg.PartType
	if partType == "" {
		partType = "text"
	}
	res, err := s.db.Exec(
		`INSERT INTO messages (room_id, agent, role, content, filename, title, group_id, part_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
		msg.RoomID, msg.Agent, msg.Role, msg.Content, nilIfEmpty(msg.Filename), nilIfEmpty(msg.Title), msg.GroupID, partType,
	)
	if err != nil {
		return 0, err
	}
	return res.LastInsertId()
}

func (s *Store) GetMessages(roomID string, limit, offset int) ([]Message, error) {
	if limit <= 0 {
		limit = 200
	}
	rows, err := s.db.Query(
		`SELECT id, room_id, agent, role, content, COALESCE(filename,''), COALESCE(title,''), group_id, created_at, COALESCE(part_type,'text')
		 FROM messages WHERE room_id = ? ORDER BY created_at ASC, id ASC LIMIT ? OFFSET ?`,
		roomID, limit, offset,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var msgs []Message
	for rows.Next() {
		var m Message
		if err := rows.Scan(&m.ID, &m.RoomID, &m.Agent, &m.Role, &m.Content, &m.Filename, &m.Title, &m.GroupID, &m.CreatedAt, &m.PartType); err != nil {
			return nil, err
		}
		msgs = append(msgs, m)
	}
	return msgs, nil
}

func (s *Store) InsertFileVersion(roomID, filename, content, agent string) (int64, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	// 获取当前最大版本号
	var maxVer int
	s.db.QueryRow(`SELECT COALESCE(MAX(version), 0) FROM file_versions WHERE room_id = ? AND filename = ?`, roomID, filename).Scan(&maxVer)
	res, err := s.db.Exec(
		`INSERT INTO file_versions (room_id, filename, content, agent, version) VALUES (?, ?, ?, ?, ?)`,
		roomID, filename, content, agent, maxVer+1,
	)
	if err != nil {
		return 0, err
	}
	return res.LastInsertId()
}

func (s *Store) GetFileVersions(roomID, filename string) ([]FileVersion, error) {
	rows, err := s.db.Query(
		`SELECT id, room_id, filename, content, agent, version, created_at FROM file_versions WHERE room_id = ? AND filename = ? ORDER BY version DESC`,
		roomID, filename,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var versions []FileVersion
	for rows.Next() {
		var v FileVersion
		if err := rows.Scan(&v.ID, &v.RoomID, &v.Filename, &v.Content, &v.Agent, &v.Version, &v.CreatedAt); err != nil {
			return nil, err
		}
		versions = append(versions, v)
	}
	return versions, nil
}

func (s *Store) GetFileVersion(roomID, filename string, version int) (*FileVersion, error) {
	var v FileVersion
	err := s.db.QueryRow(
		`SELECT id, room_id, filename, content, agent, version, created_at FROM file_versions WHERE room_id = ? AND filename = ? AND version = ?`,
		roomID, filename, version,
	).Scan(&v.ID, &v.RoomID, &v.Filename, &v.Content, &v.Agent, &v.Version, &v.CreatedAt)
	if err != nil {
		return nil, err
	}
	return &v, nil
}

func nilIfEmpty(s string) interface{} {
	if s == "" {
		return nil
	}
	return s
}
