package ai

import (
	"fmt"
	"os"
	"strings"

	"inboxer/src/internal/imap"
)

// Classifier implements worker.AIClassifier using DeepSeek
type Classifier struct {
	api       *DeepSeekAPI
	prompt    string // loaded from prompt file
}

// NewClassifier creates a new AI classifier
func NewClassifier(api *DeepSeekAPI, promptFile string) (*Classifier, error) {
	prompt, err := loadPromptFile(promptFile)
	if err != nil {
		return nil, fmt.Errorf("failed to load prompt file: %w", err)
	}

	return &Classifier{
		api:    api,
		prompt: prompt,
	}, nil
}

// Classify classifies an email using DeepSeek
func (c *Classifier) Classify(email imap.EmailSummary) (string, int, error) {
	// Render the prompt with email data
	rendered := renderPrompt(c.prompt, email)

	messages := []chatMessage{
		{
			Role:    "user",
			Content: rendered,
		},
	}

	content, err := c.api.ChatCompletion(messages)
	if err != nil {
		return "", 0, fmt.Errorf("deepseek api error: %w", err)
	}

	result, err := ParseClassification(content)
	if err != nil {
		return "", 0, fmt.Errorf("failed to parse AI response: %w (raw: %s)", err, content)
	}

	// Map the folder name from the prompt template to actual IMAP folder
	// The prompt uses "Important", "eCommerce", "Spam", "Other" which
	// correspond to the configured folder names. We return the raw folder
	// name; the caller (worker) uses it directly to move.
	return result.Folder, result.Score, nil
}

// renderPrompt substitutes {sender}, {subject}, {body} placeholders
func renderPrompt(tmpl string, email imap.EmailSummary) string {
	result := strings.ReplaceAll(tmpl, "{sender}", email.From)
	result = strings.ReplaceAll(result, "{subject}", email.Subject)
	result = strings.ReplaceAll(result, "{body}", email.Body)
	return result
}

// loadPromptFile reads the prompt template from disk
func loadPromptFile(path string) (string, error) {
	// Try absolute path first, then relative to working directory
	data, err := os.ReadFile(path)
	if err != nil {
		// Try with bin/ prefix
		data, err = os.ReadFile("bin/" + path)
		if err != nil {
			return "", fmt.Errorf("prompt file not found at %q or bin/%s: %w", path, path, err)
		}
	}
	return strings.TrimSpace(string(data)), nil
}
