"""Context Engine — structured context assembly for AI prompts.

Provides:
- ContextAssembler: priority-ordered, deduplicated context block manager
- build_domain_context: assembles context for domain analysis
- build_generation_context: assembles context for content generation

Zero imports from app/. Uses ContextBlock from aura_core.types.
"""

import json
import logging
from typing import Optional

from aura_core.types import ContextBlock

logger = logging.getLogger(__name__)


class ContextAssembler:
    def __init__(self):
        self._blocks: list[ContextBlock] = []
        self._seen: set[str] = set()

    def add(self, block: ContextBlock) -> "ContextAssembler":
        key = f"{block.source}:{block.content}"
        if key in self._seen:
            return self
        self._seen.add(key)
        self._blocks.append(block)
        return self

    def add_raw(self, source: str, content: str, priority: int = 0) -> "ContextAssembler":
        return self.add(ContextBlock(source=source, content=content, priority=priority))

    def render(self, max_chars: int = 0) -> str:
        if not self._blocks:
            return ""

        sorted_blocks = sorted(self._blocks, key=lambda b: -b.priority)

        sections = []
        for block in sorted_blocks:
            header = f"--- {block.source.upper()} ---"
            sections.append(f"{header}\n{block.content}")

        full = "\n\n".join(sections)

        if max_chars > 0 and len(full) > max_chars:
            full = full[:max_chars] + "\n[...truncated]"

        return full

    def clear(self):
        self._blocks.clear()
        self._seen.clear()

    @property
    def block_count(self) -> int:
        return len(self._blocks)


def build_domain_context(
    domain: str,
    analysis: Optional[dict] = None,
    niche: Optional[dict] = None,
    brand: Optional[dict] = None,
    valuation: Optional[dict] = None,
) -> str:
    ca = ContextAssembler()

    ca.add_raw("domain", f"Domain: {domain}", priority=10)

    if analysis:
        parts = []
        if analysis.get("keywords"):
            parts.append(f"Keywords: {', '.join(analysis['keywords'])}")
        if analysis.get("domain_summary"):
            parts.append(f"Summary: {analysis['domain_summary']}")
        niches = analysis.get("niches", [])
        if niches:
            niche_names = [n.get("name", "Unknown") for n in niches]
            parts.append(f"Identified niches: {', '.join(niche_names)}")
        if parts:
            ca.add_raw("analysis", "\n".join(parts), priority=8)

    if niche:
        parts = []
        if niche.get("name"):
            parts.append(f"Niche: {niche['name']}")
        if niche.get("description"):
            parts.append(f"Description: {niche['description']}")
        if niche.get("target_audience"):
            parts.append(f"Target Audience: {niche['target_audience']}")
        if niche.get("monetization_model"):
            parts.append(f"Monetization: {niche['monetization_model']}")
        if niche.get("affiliate_programs"):
            programs = niche["affiliate_programs"]
            if isinstance(programs, list):
                parts.append(f"Affiliate Programs: {', '.join(programs)}")
        if parts:
            ca.add_raw("niche", "\n".join(parts), priority=7)

    if brand:
        parts = []
        if brand.get("name"):
            parts.append(f"Brand: {brand['name']}")
        if brand.get("tagline"):
            parts.append(f"Tagline: {brand['tagline']}")
        if parts:
            ca.add_raw("brand", "\n".join(parts), priority=6)

    if valuation:
        parts = []
        if valuation.get("domain_only_value"):
            parts.append(f"Domain Value: ${valuation['domain_only_value']:,}")
        if valuation.get("best_developed_value"):
            parts.append(f"Developed Value: ${valuation['best_developed_value']:,}")
        if valuation.get("best_monthly_net"):
            parts.append(f"Monthly Net Potential: ${valuation['best_monthly_net']:,}")
        if parts:
            ca.add_raw("valuation", "\n".join(parts), priority=5)

    return ca.render()


def build_generation_context(
    domain: str,
    niche: str = "",
    brand: Optional[dict] = None,
    tone: str = "",
    depth: str = "standard",
    section_type: str = "",
    extra_context: str = "",
) -> str:
    ca = ContextAssembler()

    ca.add_raw("domain", f"Domain: {domain}", priority=10)

    if niche:
        ca.add_raw("niche", f"Niche: {niche}", priority=9)

    if brand:
        parts = []
        if brand.get("name"):
            parts.append(f"Brand: {brand['name']}")
        if brand.get("tagline"):
            parts.append(f"Tagline: {brand['tagline']}")
        if parts:
            ca.add_raw("brand", "\n".join(parts), priority=8)

    if tone:
        ca.add_raw("tone", f"Tone: {tone}", priority=7)

    if depth != "standard":
        ca.add_raw("depth", f"Content Depth: {depth}", priority=6)

    if section_type:
        ca.add_raw("section", f"Section Type: {section_type}", priority=5)

    if extra_context:
        ca.add_raw("extra", extra_context, priority=3)

    return ca.render()
