package inbox

import (
	"errors"

	"gorm.io/gorm"
	"senlinai-agent/backend/internal/models"
)

type CaptureInput struct {
	ProjectID  uint
	UserID     uint
	SourceType string
	Title      string
	Body       string
}

type Suggestion struct {
	Kind  string `json:"kind"`
	Title string `json:"title"`
	Body  string `json:"body"`
}

type Analyzer interface {
	Analyze(item models.SenlinAgentInboxItem, userID uint) ([]Suggestion, error)
}

type StaticAnalyzer struct {
	Suggestions []Suggestion
}

func (a StaticAnalyzer) Analyze(item models.SenlinAgentInboxItem, userID uint) ([]Suggestion, error) {
	return a.Suggestions, nil
}

type Service struct {
	analyzer Analyzer
}

func NewService(analyzer Analyzer) *Service {
	return &Service{analyzer: analyzer}
}

func (s *Service) Capture(input CaptureInput) (*models.SenlinAgentInboxItem, error) {
	if input.ProjectID == 0 || input.UserID == 0 {
		return nil, errors.New("project and user are required")
	}
	if input.SourceType == "" {
		return nil, errors.New("source type is required")
	}
	item := &models.SenlinAgentInboxItem{
		ProjectID:  input.ProjectID,
		CreatedBy:  input.UserID,
		SourceType: input.SourceType,
		Title:      input.Title,
		Body:       input.Body,
		Status:     "open",
	}
	return item, models.DBService.Create(item).Error
}

func (s *Service) Analyze(itemID uint, userID uint) ([]Suggestion, error) {
	var item models.SenlinAgentInboxItem
	if err := models.DBService.First(&item, itemID).Error; err != nil {
		return nil, err
	}
	if s.analyzer == nil {
		return []Suggestion{}, nil
	}
	return s.analyzer.Analyze(item, userID)
}

func (s *Service) Confirm(itemID uint, selected []Suggestion) error {
	return models.DBService.Transaction(func(tx *gorm.DB) error {
		var item models.SenlinAgentInboxItem
		if err := tx.First(&item, itemID).Error; err != nil {
			return err
		}
		sourceInboxItemID := item.ID
		// Inbox 建议只有在用户确认后才创建正式对象，并把来源 ID 写入每个对象以保留可追溯性。
		for _, suggestion := range selected {
			switch suggestion.Kind {
			case "task":
				if err := tx.Create(&models.SenlinAgentTask{ProjectID: item.ProjectID, CreatedBy: item.CreatedBy, SourceInboxItemID: &sourceInboxItemID, Title: suggestion.Title, Description: suggestion.Body}).Error; err != nil {
					return err
				}
			case "note":
				if err := tx.Create(&models.SenlinAgentNote{ProjectID: item.ProjectID, CreatedBy: item.CreatedBy, SourceInboxItemID: &sourceInboxItemID, Title: suggestion.Title, Markdown: suggestion.Body}).Error; err != nil {
					return err
				}
			case "source":
				if err := tx.Create(&models.SenlinAgentSource{ProjectID: item.ProjectID, CreatedBy: item.CreatedBy, SourceInboxItemID: &sourceInboxItemID, Kind: "link", Title: suggestion.Title, ContentText: suggestion.Body}).Error; err != nil {
					return err
				}
			default:
				return errors.New("unsupported suggestion kind")
			}
		}
		return tx.Model(&item).Update("status", "processed").Error
	})
}
