"""Built-in use case registry for prompt and code generation."""

from __future__ import annotations

from dataclasses import asdict
from typing import Any

from kiessclaw.usecases.schema import UseCaseSpec

_COMMON_SCAFFOLDS = [
    "agent.py.tmpl",
    "skill.py.tmpl",
    "workflow.py.tmpl",
    "test.py.tmpl",
    "docs.md.tmpl",
]

_DEFAULT_USECASES: dict[str, UseCaseSpec] = {
    "outreach_sdr": UseCaseSpec(
        id="outreach_sdr",
        title="Outbound SDR Workflow",
        description="Contacts to sequence, send, reply handling, and analytics checks.",
        required_inputs=["target_segment", "offer", "sender_name", "sender_email", "cta"],
        outputs=["prompt_pack", "workflow_scaffold", "qa_checklist"],
        recommended_agents=["KPRO", "KSEQ", "KPEN", "KINB", "KMET"],
        workflows=["prospect", "sequence", "enroll", "send", "reply", "analyze"],
        prompt_templates={
            "system": (
                "You are an SDR operations copilot.\n"
                "Use only factual inputs.\n"
                "Target segment: {{target_segment}}\n"
                "Offer: {{offer}}\n"
                "Sender: {{sender_name}} <{{sender_email}}>"
            ),
            "task": (
                "Build a deterministic outbound SDR plan for {{target_segment}}.\n"
                "Include sequence structure, qualification criteria, and CTA: {{cta}}.\n"
                "Output must include steps, stop-conditions, and metrics to track."
            ),
            "guardrails": (
                "Do not fabricate data.\n"
                "Do not promise outcomes.\n"
                "Always include unsubscribe handling and DNC compliance.\n"
                "Use plain language and explicit success criteria."
            ),
            "checklist": (
                "- ICP criteria defined\n"
                "- Sequence has stop-on-reply logic\n"
                "- Message templates include CTA '{{cta}}'\n"
                "- Analytics fields listed (open/reply/meeting rates)\n"
                "- Risks and fallback path documented"
            ),
        },
        scaffold_templates=_COMMON_SCAFFOLDS,
    ),
    "seo_audit_to_leads": UseCaseSpec(
        id="seo_audit_to_leads",
        title="SEO Audit To Leads",
        description="Convert SEO audit findings into lead lists and outreach plans without auto-send.",
        required_inputs=["domain", "icp_profile", "priority_issue_types", "offer"],
        outputs=["prompt_pack", "lead_list_schema", "outreach_plan"],
        recommended_agents=["KRAWL", "KANA", "KPRO", "KPEN"],
        workflows=["crawl", "analyze", "qualify", "plan"],
        prompt_templates={
            "system": (
                "You are an SEO-to-SDR planning assistant.\n"
                "Domain: {{domain}}\n"
                "ICP profile: {{icp_profile}}\n"
                "Issue priorities: {{priority_issue_types}}"
            ),
            "task": (
                "Generate a non-automated lead generation plan from SEO findings for {{domain}}.\n"
                "Produce lead prioritization criteria and outreach angle tied to {{offer}}."
            ),
            "guardrails": (
                "No automatic sending.\n"
                "No speculative owner identities.\n"
                "Every recommendation must map to a measurable issue category."
            ),
            "checklist": (
                "- Audit issue buckets listed\n"
                "- Lead score criteria defined\n"
                "- Outreach angles mapped to issue types\n"
                "- Manual approval gate before outreach"
            ),
        },
        scaffold_templates=_COMMON_SCAFFOLDS,
    ),
    "enrichment_only": UseCaseSpec(
        id="enrichment_only",
        title="Lead Enrichment Only",
        description="Normalize and enrich contact/account records without sequence execution.",
        required_inputs=["input_source", "required_fields", "quality_threshold"],
        outputs=["prompt_pack", "enrichment_workflow", "validation_rules"],
        recommended_agents=["KPRO"],
        workflows=["import", "enrich", "validate"],
        prompt_templates={
            "system": (
                "You are a deterministic data enrichment planner.\n"
                "Input source: {{input_source}}\n"
                "Required fields: {{required_fields}}"
            ),
            "task": (
                "Design an enrichment-only workflow with quality threshold {{quality_threshold}}.\n"
                "Define normalization rules, fallbacks, and rejection conditions."
            ),
            "guardrails": (
                "No outbound actions.\n"
                "Do not invent missing firmographic details.\n"
                "Return explicit pass/fail validation criteria."
            ),
            "checklist": (
                "- Required fields mapped\n"
                "- Validation rules explicit\n"
                "- Rejection reasons captured\n"
                "- Output schema deterministic"
            ),
        },
        scaffold_templates=_COMMON_SCAFFOLDS,
    ),
    "customer_success_recovery": UseCaseSpec(
        id="customer_success_recovery",
        title="Customer Success Recovery",
        description="Build churn/no-show recovery sequences and escalation playbooks.",
        required_inputs=["segment", "risk_signals", "desired_outcome", "primary_offer"],
        outputs=["prompt_pack", "recovery_sequence", "escalation_checklist"],
        recommended_agents=["KPEN", "KSEQ", "KINB", "KMET"],
        workflows=["segment", "sequence", "reply_classification", "reporting"],
        prompt_templates={
            "system": (
                "You are a customer recovery operations specialist.\n"
                "Segment: {{segment}}\n"
                "Risk signals: {{risk_signals}}"
            ),
            "task": (
                "Generate a churn/no-show recovery messaging plan.\n"
                "Desired outcome: {{desired_outcome}}\n"
                "Primary offer: {{primary_offer}}"
            ),
            "guardrails": (
                "Avoid blame language.\n"
                "Respect opt-out requests immediately.\n"
                "All messages must include clear next-step choice."
            ),
            "checklist": (
                "- Recovery stages defined\n"
                "- Escalation path documented\n"
                "- Reply intents mapped to actions\n"
                "- Success criteria tied to {{desired_outcome}}"
            ),
        },
        scaffold_templates=_COMMON_SCAFFOLDS,
    ),
    "github_oss_launch": UseCaseSpec(
        id="github_oss_launch",
        title="GitHub OSS Launch",
        description="Prepare repository docs, releases, and contribution setup for OSS launch.",
        required_inputs=["repo_url", "version", "audience", "launch_goal"],
        outputs=["prompt_pack", "release_checklist", "community_issue_plan"],
        recommended_agents=["KMET"],
        workflows=["hygiene", "docs", "release", "distribution"],
        prompt_templates={
            "system": (
                "You are an OSS release engineer.\n"
                "Repository: {{repo_url}}\n"
                "Version: {{version}}\n"
                "Audience: {{audience}}"
            ),
            "task": (
                "Create a launch-ready execution checklist for {{repo_url}}.\n"
                "Primary launch goal: {{launch_goal}}.\n"
                "Include release notes, issue labels, and announcement plan."
            ),
            "guardrails": (
                "No vanity tasks.\n"
                "Prioritize reproducibility, docs accuracy, and contributor onboarding."
            ),
            "checklist": (
                "- Release notes drafted\n"
                "- Docs links verified\n"
                "- Issue templates and labels prepared\n"
                "- 72-hour distribution plan listed"
            ),
        },
        scaffold_templates=_COMMON_SCAFFOLDS,
    ),
    "client_onboarding": UseCaseSpec(
        id="client_onboarding",
        title="Client Onboarding Pipeline",
        description="Turn intake inputs into scoped plan, timeline, and proposal email.",
        required_inputs=["client_name", "project_scope", "timeline", "budget_range", "success_metrics"],
        outputs=["prompt_pack", "project_plan", "proposal_email"],
        recommended_agents=["KPRO", "KPEN", "KMET"],
        workflows=["intake", "requirements", "plan", "proposal"],
        prompt_templates={
            "system": (
                "You are a delivery planning assistant.\n"
                "Client: {{client_name}}\n"
                "Project scope: {{project_scope}}\n"
                "Timeline: {{timeline}}"
            ),
            "task": (
                "Generate onboarding outputs for {{client_name}} using budget {{budget_range}}.\n"
                "Include requirements summary, phased plan, and a proposal draft email."
            ),
            "guardrails": (
                "No guarantees.\n"
                "Document assumptions explicitly.\n"
                "Include measurable success criteria: {{success_metrics}}."
            ),
            "checklist": (
                "- Intake assumptions listed\n"
                "- Deliverables scoped by phase\n"
                "- Risks and dependencies captured\n"
                "- Proposal includes timeline + next steps"
            ),
        },
        scaffold_templates=_COMMON_SCAFFOLDS,
    ),
}


def list_usecases() -> list[UseCaseSpec]:
    """Return all built-in use cases sorted by stable ID."""
    return [_DEFAULT_USECASES[key] for key in sorted(_DEFAULT_USECASES.keys())]


def get_usecase(usecase_id: str) -> UseCaseSpec:
    """Return one use case by ID or raise KeyError."""
    key = usecase_id.strip()
    if key not in _DEFAULT_USECASES:
        raise KeyError(f"Unknown use case: {usecase_id}")
    return _DEFAULT_USECASES[key]


def validate_usecase(spec: UseCaseSpec) -> None:
    """Fail fast on invalid spec fields."""
    as_dict = asdict(spec)
    required_strings = ["id", "title", "description"]
    for field_name in required_strings:
        value = as_dict.get(field_name)
        if not isinstance(value, str) or not value.strip():
            raise ValueError(f"UseCaseSpec.{field_name} must be a non-empty string")

    list_fields = [
        "required_inputs",
        "outputs",
        "recommended_agents",
        "workflows",
        "scaffold_templates",
    ]
    for field_name in list_fields:
        values = as_dict.get(field_name)
        if not isinstance(values, list) or not values:
            raise ValueError(f"UseCaseSpec.{field_name} must be a non-empty list")
        if not all(isinstance(item, str) and item.strip() for item in values):
            raise ValueError(f"UseCaseSpec.{field_name} must contain non-empty strings")

    prompts = as_dict.get("prompt_templates")
    if not isinstance(prompts, dict):
        raise ValueError("UseCaseSpec.prompt_templates must be a dict")
    for name in ("system", "task", "guardrails", "checklist"):
        content = prompts.get(name)
        if not isinstance(content, str) or not content.strip():
            raise ValueError(f"UseCaseSpec.prompt_templates['{name}'] is required")


def usecase_to_dict(spec: UseCaseSpec) -> dict[str, Any]:
    """Return serializable use case payload."""
    validate_usecase(spec)
    return asdict(spec)
