package placement

import (
	"strings"

	branddomain "haixun-backend/internal/model/brand/domain/usecase"
	topicdomain "haixun-backend/internal/model/placement_topic/domain/usecase"
)

// PlacementTopicContext bundles brand, product, and user-entered topic fields for prompts.
type PlacementTopicContext struct {
	BrandDisplayName string
	TopicName        string
	SeedQuery        string
	Brief            string
	Goals            string
	TargetAudience   string
	ProductContext   string
	ProductBrief     string
	ProductLabel     string
}

func PlacementTopicContextFromTopic(topic *topicdomain.TopicSummary, brand *branddomain.BrandSummary, productBrief string) PlacementTopicContext {
	if topic == nil {
		return PlacementTopicContextFromBrand(brand, productBrief)
	}
	merged := brandSummaryForTopic(topic, brand)
	return PlacementTopicContextFromBrand(merged, productBrief)
}

func brandSummaryForTopic(topic *topicdomain.TopicSummary, brand *branddomain.BrandSummary) *branddomain.BrandSummary {
	if brand == nil {
		return nil
	}
	out := *brand
	out.TopicName = strings.TrimSpace(topic.TopicName)
	out.SeedQuery = strings.TrimSpace(topic.SeedQuery)
	out.Brief = strings.TrimSpace(topic.Brief)
	out.ProductID = strings.TrimSpace(topic.ProductID)
	out.ResearchMap = topic.ResearchMap
	return &out
}

func PlacementTopicContextFromBrand(brand *branddomain.BrandSummary, productBrief string) PlacementTopicContext {
	if brand == nil {
		return PlacementTopicContext{}
	}
	ctx := PlacementTopicContext{
		BrandDisplayName: strings.TrimSpace(brand.DisplayName),
		TopicName:        strings.TrimSpace(brand.TopicName),
		SeedQuery:        strings.TrimSpace(brand.SeedQuery),
		Brief:            strings.TrimSpace(brand.Brief),
		Goals:            strings.TrimSpace(brand.Goals),
		TargetAudience:   strings.TrimSpace(brand.TargetAudience),
		ProductContext:   strings.TrimSpace(brand.ProductContext),
		ProductBrief:     strings.TrimSpace(productBrief),
		ProductLabel:     productLabelFromBrand(brand),
	}
	if ctx.ProductBrief == "" {
		ctx.ProductBrief = strings.TrimSpace(brand.ProductBrief)
	}
	return ctx
}

func productLabelFromBrand(brand *branddomain.BrandSummary) string {
	if brand == nil {
		return ""
	}
	productID := strings.TrimSpace(brand.ProductID)
	if productID == "" {
		return ""
	}
	for _, item := range brand.Products {
		if item.ID == productID {
			return strings.TrimSpace(item.Label)
		}
	}
	return ""
}

func (c PlacementTopicContext) ToResearchMapInput() ResearchMapInput {
	return ResearchMapInput{
		BrandDisplayName: c.BrandDisplayName,
		TopicName:        c.TopicName,
		SeedQuery:        c.SeedQuery,
		Brief:            c.Brief,
		Goals:            c.Goals,
		TargetAudience:   c.TargetAudience,
		ProductContext:   c.ProductContext,
		ProductBrief:     c.ProductBrief,
		ProductLabel:     c.ProductLabel,
	}
}

func (c PlacementTopicContext) WritePromptBlock(b *strings.Builder) {
	writePromptSection(b, "品牌", c.BrandDisplayName)
	writePromptSection(b, "置入產品", c.ProductDisplayName())
	writePromptSection(b, "主題名稱", c.TopicName)
	writePromptSection(b, "種子關鍵字", c.SeedQuery)
	writePromptSection(b, "主題目標", c.Brief)
	writePromptSection(b, "置入目標／備註", c.Goals)
	writePromptSection(b, "已知受眾描述", c.TargetAudience)
	productDetail := FormatProductContextForPrompt(c.ProductContext)
	if productDetail == "" && c.ProductBrief != "" {
		productDetail = c.ProductBrief
	}
	if productDetail != "" {
		b.WriteString("【產品詳情】\n")
		b.WriteString(productDetail)
		b.WriteString("\n")
	}
}

func (c PlacementTopicContext) ProductDisplayName() string {
	fields := ParseProductContext(c.ProductContext)
	if fields.Product != "" {
		return fields.Product
	}
	return c.ProductLabel
}

func writePromptSection(b *strings.Builder, label, value string) {
	value = strings.TrimSpace(value)
	if value == "" {
		return
	}
	b.WriteString("【")
	b.WriteString(label)
	b.WriteString("】")
	b.WriteString(value)
	b.WriteString("\n")
}

// PromptLines returns optional labeled lines for knowledge graph template vars.
func (c PlacementTopicContext) PromptLines() map[string]string {
	productName := c.ProductDisplayName()
	return map[string]string{
		"brand_line":   optionalPromptLine("品牌", c.BrandDisplayName),
		"topic_line":   optionalPromptLine("主題名稱", c.TopicName),
		"product_line": optionalPromptLine("置入產品", productName),
		"goals_line":   optionalPromptLine("置入目標", c.Goals),
	}
}

func optionalPromptLine(label, value string) string {
	value = strings.TrimSpace(value)
	if value == "" {
		return ""
	}
	return label + "：" + value + "\n"
}
