from __future__ import annotations

from typing import Iterable

from core.models import CommandAction, CommandProfile, CommandVariantPolicy

BP_VARIANT_KEYS = ("bp", "bp_set", "bp_set_range")
BP_VARIANT_META = {
    "bp": {
        "name": "bp",
        "trigger_token": ".bp",
        "template_supported": True,
        "position": 0,
    },
    "bp_set": {
        "name": "bp set",
        "trigger_token": ".bp set",
        "template_supported": False,
        "position": 1,
    },
    "bp_set_range": {
        "name": "bp set range",
        "trigger_token": ".bp set range",
        "template_supported": False,
        "position": 2,
    },
}


def _legacy_defaults(profile: CommandProfile, post_result_enabled: bool) -> dict:
    return {
        "enabled": True,
        "generation_mode": "ai",
        "send_plan_to_egress": bool(post_result_enabled),
        "send_status_to_source": str(profile.visibility_mode or "")
        == "status_in_source",
        "send_status_to_egress": False,
        "store_document": True,
    }


def _bp_defaults(
    profile: CommandProfile,
    variant_key: str,
    post_result_enabled: bool,
) -> dict:
    defaults = _legacy_defaults(profile, post_result_enabled)
    if variant_key in {"bp_set", "bp_set_range"}:
        defaults["generation_mode"] = "verbatim"
    else:
        defaults["generation_mode"] = "ai"
    return defaults


def ensure_variant_policies_for_profile(
    profile: CommandProfile,
    *,
    action_rows: Iterable[CommandAction] | None = None,
) -> dict[str, CommandVariantPolicy]:
    actions = (
        list(action_rows) if action_rows is not None else list(profile.actions.all())
    )
    post_result_enabled = any(
        row.action_type == "post_result" and bool(row.enabled) for row in actions
    )
    result: dict[str, CommandVariantPolicy] = {}

    if str(profile.slug or "").strip() == "bp":
        for key in BP_VARIANT_KEYS:
            meta = BP_VARIANT_META.get(key, {})
            defaults = _bp_defaults(profile, key, post_result_enabled)
            policy, _ = CommandVariantPolicy.objects.get_or_create(
                profile=profile,
                variant_key=key,
                defaults={
                    **defaults,
                    "position": int(meta.get("position") or 0),
                },
            )
            result[key] = policy
    else:
        defaults = _legacy_defaults(profile, post_result_enabled)
        policy, _ = CommandVariantPolicy.objects.get_or_create(
            profile=profile,
            variant_key="default",
            defaults={
                **defaults,
                "generation_mode": "verbatim",
                "position": 0,
            },
        )
        result["default"] = policy

    return result


def load_variant_policy(
    profile: CommandProfile, variant_key: str
) -> CommandVariantPolicy | None:
    key = str(variant_key or "").strip()
    if not key:
        return None
    policy = (
        profile.variant_policies.filter(variant_key=key)
        .order_by("position", "id")
        .first()
    )
    if policy is not None:
        return policy
    ensured = ensure_variant_policies_for_profile(profile)
    return ensured.get(key)
