package prompt

import (
	"encoding/json"
	"strings"
)

const overlaySeparator = "\n\n---\n\n"

// ComposeSystem prepends global overlay to the base system prompt before provider send.
func ComposeSystem(base string) (string, error) {
	base = strings.TrimSpace(base)
	overlayText, err := Overlay()
	if err != nil {
		return "", err
	}
	overlayText = strings.TrimSpace(overlayText)
	if overlayText == "" {
		return base, nil
	}
	if base == "" {
		return overlayText, nil
	}
	return overlayText + overlaySeparator + base, nil
}

// Style8DSystem loads 8D slots from config files and composes the outgoing system prompt.
func Style8DSystem() (string, error) {
	system, err := Slot(KeyStyle8DSystem)
	if err != nil {
		return "", err
	}
	schema, err := Slot(KeyStyle8DSchema)
	if err != nil {
		return "", err
	}
	return ComposeSystem(system + schema)
}

// IslanderSystem composes the islander guide system prompt with optional live page context.
func IslanderSystem(pageContext string) (string, error) {
	base, err := Slot(KeyIslanderSystem)
	if err != nil {
		return "", err
	}
	pageContext = strings.TrimSpace(pageContext)
	if pageContext != "" {
		base = base + "\n\n---\n\n" + pageContext
	}
	return ComposeSystem(base)
}

// KnowledgeGraphSystem composes the TKG synthesis system prompt.
func KnowledgeGraphSystem() (string, error) {
	base, err := Slot(KeyKnowledgeGraphSystem)
	if err != nil {
		return "", err
	}
	return ComposeSystem(base)
}

// KnowledgeGraphLLMSystem composes the LLM-only TKG synthesis system prompt.
func KnowledgeGraphLLMSystem() (string, error) {
	base, err := Slot(KeyKnowledgeGraphLLMSystem)
	if err != nil {
		return "", err
	}
	return ComposeSystem(base)
}

// KnowledgeGraphUser renders the TKG user prompt from the template slot.
func KnowledgeGraphUser(vars map[string]string) (string, error) {
	base, err := Slot(KeyKnowledgeGraphUser)
	if err != nil {
		return "", err
	}
	return renderTemplate(base, vars), nil
}

// KnowledgeGraphLLMUser renders the LLM-only TKG user prompt.
func KnowledgeGraphLLMUser(vars map[string]string) (string, error) {
	base, err := Slot(KeyKnowledgeGraphLLMUser)
	if err != nil {
		return "", err
	}
	return renderTemplate(base, vars), nil
}

// KnowledgeGraphSupplemental returns the supplemental-round instruction prompt.
func KnowledgeGraphSupplemental() (string, error) {
	return Slot(KeyKnowledgeGraphSupplemental)
}

// KnowledgeGraphQueryConfig loads query template config from prompt files.
func KnowledgeGraphQueryConfig() (map[string]json.RawMessage, error) {
	raw, err := readFile(fileKnowledgeGraphQueries)
	if err != nil {
		return nil, err
	}
	out := map[string]json.RawMessage{}
	if err := json.Unmarshal([]byte(raw), &out); err != nil {
		return nil, err
	}
	return out, nil
}

func renderTemplate(base string, vars map[string]string) string {
	out := base
	for key, value := range vars {
		out = strings.ReplaceAll(out, "{{"+key+"}}", value)
	}
	return strings.TrimSpace(out)
}

// OutreachPlacementSystem composes placement outreach comment system prompt.
func OutreachPlacementSystem() (string, error) {
	base, err := Slot(KeyOutreachPlacementSystem)
	if err != nil {
		return "", err
	}
	return ComposeSystem(base)
}

// OutreachPlacementUser renders outreach user prompt from template slot.
func OutreachPlacementUser(vars map[string]string) (string, error) {
	base, err := Slot(KeyOutreachPlacementUser)
	if err != nil {
		return "", err
	}
	return renderTemplate(base, vars), nil
}

// MatrixPlacementSystem composes content matrix system prompt.
func MatrixPlacementSystem() (string, error) {
	base, err := Slot(KeyMatrixPlacementSystem)
	if err != nil {
		return "", err
	}
	return ComposeSystem(base)
}

// MatrixPlacementUser renders matrix user prompt from template slot.
func MatrixPlacementUser(vars map[string]string) (string, error) {
	base, err := Slot(KeyMatrixPlacementUser)
	if err != nil {
		return "", err
	}
	return renderTemplate(base, vars), nil
}

// MatrixCopySystem composes copy-mission matrix system prompt.
func MatrixCopySystem() (string, error) {
	base, err := Slot(KeyMatrixCopySystem)
	if err != nil {
		return "", err
	}
	return ComposeSystem(base)
}

// MatrixCopyUser renders copy matrix user prompt from template slot.
func MatrixCopyUser(vars map[string]string) (string, error) {
	base, err := Slot(KeyMatrixCopyUser)
	if err != nil {
		return "", err
	}
	return renderTemplate(base, vars), nil
}

// AIChatSystem composes the outgoing system prompt for console AI chat.
func AIChatSystem(clientSystem string) (string, error) {
	base := strings.TrimSpace(clientSystem)
	if base == "" {
		var err error
		base, err = Slot(KeyAIChatSystem)
		if err != nil {
			return "", err
		}
	}
	return ComposeSystem(base)
}
