package storage

import (
	"sync"
	"time"

	"github.com/google/uuid"
	"gorm.io/gorm"

	"mengyastore-backend/internal/database"
	"mengyastore-backend/internal/models"
)

type ChatStore struct {
	db       *gorm.DB
	mu       sync.Mutex
	lastSent map[string]time.Time
}

func NewChatStore(db *gorm.DB) (*ChatStore, error) {
	return &ChatStore{db: db, lastSent: make(map[string]time.Time)}, nil
}

func chatRowToModel(row database.ChatMessageRow) models.ChatMessage {
	return models.ChatMessage{
		ID:          row.ID,
		AccountID:   row.AccountID,
		AccountName: row.AccountName,
		Content:     row.Content,
		SentAt:      row.SentAt,
		FromAdmin:   row.FromAdmin,
	}
}

func (s *ChatStore) GetMessages(accountID string) ([]models.ChatMessage, error) {
	var rows []database.ChatMessageRow
	if err := s.db.Where("account_id = ?", accountID).Order("sent_at ASC").Find(&rows).Error; err != nil {
		return nil, err
	}
	msgs := make([]models.ChatMessage, len(rows))
	for i, r := range rows {
		msgs[i] = chatRowToModel(r)
	}
	return msgs, nil
}

func (s *ChatStore) ListConversations() (map[string][]models.ChatMessage, error) {
	var rows []database.ChatMessageRow
	if err := s.db.Order("account_id, sent_at ASC").Find(&rows).Error; err != nil {
		return nil, err
	}
	result := make(map[string][]models.ChatMessage)
	for _, r := range rows {
		result[r.AccountID] = append(result[r.AccountID], chatRowToModel(r))
	}
	return result, nil
}

func (s *ChatStore) SendUserMessage(accountID, accountName, content string) (models.ChatMessage, bool, error) {
	s.mu.Lock()
	defer s.mu.Unlock()

	if last, ok := s.lastSent[accountID]; ok && time.Since(last) < time.Second {
		return models.ChatMessage{}, true, nil
	}
	s.lastSent[accountID] = time.Now()

	row := database.ChatMessageRow{
		ID:          uuid.New().String(),
		AccountID:   accountID,
		AccountName: accountName,
		Content:     content,
		SentAt:      time.Now(),
		FromAdmin:   false,
	}
	if err := s.db.Create(&row).Error; err != nil {
		return models.ChatMessage{}, false, err
	}
	return chatRowToModel(row), false, nil
}

func (s *ChatStore) SendAdminMessage(accountID, content string) (models.ChatMessage, error) {
	row := database.ChatMessageRow{
		ID:          uuid.New().String(),
		AccountID:   accountID,
		AccountName: "管理员",
		Content:     content,
		SentAt:      time.Now(),
		FromAdmin:   true,
	}
	if err := s.db.Create(&row).Error; err != nil {
		return models.ChatMessage{}, err
	}
	return chatRowToModel(row), nil
}

func (s *ChatStore) ClearConversation(accountID string) error {
	return s.db.Where("account_id = ?", accountID).Delete(&database.ChatMessageRow{}).Error
}
