package style8d

import (
	"encoding/json"
	"strings"
)

var dimensionLabels = map[string]string{
	"d1Tone":        "D1 語氣人格",
	"d2Structure":   "D2 結構模板",
	"d3Interaction": "D3 互動方式",
	"d4Topics":      "D4 主題分布",
	"d5Rhythm":      "D5 發文節奏",
	"d6Visual":      "D6 視覺語法",
	"d7Conversion":  "D7 轉換方式",
	"d8Risk":        "D8 風險紅線",
}

var dimensionOrder = []string{
	"d1Tone", "d2Structure", "d3Interaction", "d4Topics",
	"d5Rhythm", "d6Visual", "d7Conversion", "d8Risk",
}

// ParseStoredProfile decodes the persona.style_profile JSON blob.
func ParseStoredProfile(raw string) (*StoredProfile, bool) {
	raw = strings.TrimSpace(raw)
	if raw == "" {
		return nil, false
	}
	var profile StoredProfile
	if err := json.Unmarshal([]byte(raw), &profile); err != nil {
		return nil, false
	}
	if len(profile.Analysis) == 0 && strings.TrimSpace(profile.PersonaDraft) == "" {
		return nil, false
	}
	return &profile, true
}

// HasReady8D returns true when 8D analysis exists and can drive copy generation.
func HasReady8D(personaText, styleProfileJSON string) bool {
	if profile, ok := ParseStoredProfile(styleProfileJSON); ok {
		if strings.TrimSpace(profile.PersonaDraft) != "" {
			return true
		}
		for _, key := range dimensionOrder {
			if summary := strings.TrimSpace(profile.Analysis[key].Summary); summary != "" {
				return true
			}
		}
	}
	return strings.TrimSpace(personaText) != "" && strings.TrimSpace(styleProfileJSON) != ""
}

// BuildStyle8DPromptBlock formats D1–D8 summaries for LLM prompts.
func BuildStyle8DPromptBlock(styleProfileJSON string) string {
	profile, ok := ParseStoredProfile(styleProfileJSON)
	if !ok {
		return ""
	}
	lines := make([]string, 0, len(dimensionOrder))
	for _, key := range dimensionOrder {
		summary := strings.TrimSpace(profile.Analysis[key].Summary)
		if summary == "" {
			continue
		}
		label := dimensionLabels[key]
		if label == "" {
			label = key
		}
		lines = append(lines, label+"："+summary)
	}
	if len(lines) == 0 {
		return ""
	}
	var b strings.Builder
	b.WriteString("【8D 風格策略】\n產文必須遵守：\n")
	b.WriteString(strings.Join(lines, "\n"))
	return b.String()
}

// ResolvePersonaBlock picks the best persona voice block for copy generation.
// Priority: explicit persona field → 8D personaDraft → brief fallback; always append 8D strategy when present.
func ResolvePersonaBlock(personaText, styleProfileJSON, brief string) string {
	var parts []string

	voice := strings.TrimSpace(personaText)
	if voice == "" {
		if profile, ok := ParseStoredProfile(styleProfileJSON); ok {
			voice = strings.TrimSpace(profile.PersonaDraft)
		}
	}
	if voice == "" {
		voice = strings.TrimSpace(brief)
	}
	if voice != "" {
		parts = append(parts, "【人設語氣】\n"+voice)
	}

	if block := BuildStyle8DPromptBlock(styleProfileJSON); block != "" {
		parts = append(parts, block)
	}
	return strings.TrimSpace(strings.Join(parts, "\n\n"))
}
