package personacopy

import (
	"context"
	"fmt"
	"strings"
	"time"

	libformula "haixun-backend/internal/library/formula"
	"haixun-backend/internal/library/style8d"
	domai "haixun-backend/internal/model/ai/domain/usecase"
	aiusecase "haixun-backend/internal/model/ai/usecase"
	cfentity "haixun-backend/internal/model/content_formula/domain/entity"
	contentformuladomain "haixun-backend/internal/model/content_formula/domain/usecase"
	copydraftdomain "haixun-backend/internal/model/copy_draft/domain/usecase"
	personadomain "haixun-backend/internal/model/persona/domain/usecase"
	placementusecase "haixun-backend/internal/model/placement/usecase"
	threadsaccountdomain "haixun-backend/internal/model/threads_account/domain/usecase"
)

type RewriteDraftInput struct {
	TenantID      string
	OwnerUID      string
	PersonaID     string
	AccountID     string
	ReferenceText string
	Topic         string
	Brief         string
	SaveLabel     string
	UseWebSearch  bool
	DraftCount    int
}

type RewriteDraftDeps struct {
	Persona        personadomain.UseCase
	ContentFormula contentformuladomain.UseCase
	CopyDraft      copydraftdomain.UseCase
	ThreadsAccount threadsaccountdomain.UseCase
	Placement      placementusecase.UseCase
	AI             domai.UseCase
}

func RunRewriteDraft(ctx context.Context, deps RewriteDraftDeps, in RewriteDraftInput, progress ProgressFn) (int, error) {
	if progress == nil {
		progress = func(string, int) {}
	}
	referenceText := strings.TrimSpace(in.ReferenceText)
	topic := strings.TrimSpace(in.Topic)
	if referenceText == "" {
		return 0, fmt.Errorf("reference_text is required")
	}
	if topic == "" {
		return 0, fmt.Errorf("topic is required")
	}

	progress("讀取人設…", 5)
	persona, err := deps.Persona.Get(ctx, in.TenantID, in.OwnerUID, in.PersonaID)
	if err != nil {
		return 0, err
	}
	if !style8d.HasReady8D(persona.Persona, persona.StyleProfile) {
		return 0, fmt.Errorf("請先完成人設 8D 對標分析")
	}
	credential, err := deps.ThreadsAccount.ResolveMemberAiCredential(ctx, in.TenantID, in.OwnerUID)
	if err != nil {
		return 0, err
	}
	providerID, err := aiusecase.MapWorkerProvider(credential.Provider)
	if err != nil {
		return 0, err
	}
	aiReq := domai.GenerateRequest{
		Provider:   providerID,
		Model:      credential.Model,
		Credential: domai.Credential{APIKey: credential.APIKey},
	}
	personaBlock := style8d.ResolvePersonaBlock(persona.Persona, persona.StyleProfile, persona.Brief)

	progress(fmt.Sprintf("分析參考貼文寫法（%s / %s）…", credential.Provider, credential.Model), 15)
	analysis, err := libformula.AnalyzePasted(ctx, deps.AI, aiReq, libformula.AnalyzePastedInput{
		PostText:     referenceText,
		PersonaBlock: personaBlock,
	})
	if err != nil {
		return 0, fmt.Errorf("分析參考貼文失敗：%w", err)
	}
	if analysis == nil {
		return 0, fmt.Errorf("分析未產出有效寫法公式")
	}

	label := strings.TrimSpace(in.SaveLabel)
	if label == "" {
		label = fmt.Sprintf("貼文改寫 %s", time.Now().UTC().Format("2006-01-02"))
	}
	progress("存入寫法公式…", 30)
	saved, err := deps.ContentFormula.Create(ctx, contentformuladomain.CreateRequest{
		TenantID:        in.TenantID,
		OwnerUID:        in.OwnerUID,
		AccountID:       in.AccountID,
		Label:           label,
		SourceType:      cfentity.SourcePaste,
		SourceRef:       "paste",
		SourcePostText:  referenceText,
		Summary:         analysis.Summary,
		Wins:            analysis.Wins,
		Improvements:    analysis.Improvements,
		Formula:         analysis.Formula,
		PostTemplate:    analysis.PostTemplate,
		HookPattern:     analysis.HookPattern,
		Structure:       analysis.Structure,
		ReplicationTips: analysis.ReplicationTips,
		Avoid:           analysis.Avoid,
	})
	if err != nil {
		return 0, err
	}

	return RunFormulaDraft(ctx, FormulaDraftDeps{
		Persona:        deps.Persona,
		ContentFormula: deps.ContentFormula,
		CopyDraft:      deps.CopyDraft,
		ThreadsAccount: deps.ThreadsAccount,
		Placement:      deps.Placement,
		AI:             deps.AI,
	}, FormulaDraftInput{
		TenantID:     in.TenantID,
		OwnerUID:     in.OwnerUID,
		PersonaID:    in.PersonaID,
		AccountID:    in.AccountID,
		FormulaID:    saved.ID,
		Topic:        topic,
		Brief:        in.Brief,
		UseWebSearch: in.UseWebSearch,
		DraftCount:   in.DraftCount,
	}, func(summary string, percentage int) {
		adjusted := 35 + (percentage * 65 / 100)
		progress(summary, adjusted)
	})
}
