"""Mapeamento activação cliente — Spec 043 activation-field-mapping.md."""

from __future__ import annotations

import re
from typing import Any

DEFAULT_PLAN_CODE = "ligbox-mail-business"

PLAN_DEFAULTS: dict[str, dict[str, int]] = {
    "ligbox-mail-starter": {"seats": 10, "mail_gb": 20, "files_gb": 100},
    "ligbox-mail-business": {"seats": 25, "mail_gb": 30, "files_gb": 200},
    "ligbox-mail-enterprise": {"seats": 50, "mail_gb": 50, "files_gb": 500},
    "ligbox-mail-custom": {"seats": 25, "mail_gb": 30, "files_gb": 200},
    "ligbox-site-cms": {"seats": 1, "mail_gb": 0, "files_gb": 10},
}

ACTIVATABLE_STATES = frozenset(
    {"awaiting_billing_validation", "provisioning", "policy_pending"}
)


def _digits_only(value: str | None) -> str:
    if not value:
        return ""
    return re.sub(r"\D", "", str(value))


def normalize_company_profile(
    profile: dict[str, Any] | None,
    *,
    domain: str,
) -> dict[str, Any]:
    """Unifica manager_* e address vindos do webhook wizard."""
    p = dict(profile or {})
    addr = p.get("address")
    if not isinstance(addr, dict):
        addr = {}
    p["address"] = {
        "country": addr.get("country") or "BR",
        "city": addr.get("city") or "",
        "postal_code": addr.get("postal_code") or "",
        "street": addr.get("street") or "",
        "state": addr.get("state") or "",
    }
    p.setdefault("domain", domain.strip().lower())
    if not p.get("manager_email"):
        p["manager_email"] = f"admin@{domain.strip().lower()}"
    if not p.get("manager_name"):
        p["manager_name"] = p.get("trade_name") or p.get("legal_name") or ""
    return p


def split_manager_name(name: str | None) -> tuple[str, str]:
    parts = (name or "").strip().split(None, 1)
    if not parts:
        return ("", "")
    if len(parts) == 1:
        return (parts[0], "")
    return (parts[0], parts[1])


def derive_openpanel_username(domain: str, profile: dict[str, Any] | None = None) -> str:
    """Sugestão username hub — Spec 024 (7 chars alfanum + sufixo)."""
    existing = (profile or {}).get("openpanel_username")
    if existing:
        return str(existing).strip().lower()
    label = re.sub(r"[^a-z0-9]", "", domain.split(".")[0].lower()) or "ligbox"
    if len(label) <= 7:
        return f"{label}x"[:16]
    return f"{label[:7]}x"[:16]


def resolve_plan_config(plan_code: str | None, config: dict[str, Any] | None = None) -> tuple[str, dict[str, int]]:
    code = (plan_code or DEFAULT_PLAN_CODE).strip() or DEFAULT_PLAN_CODE
    defaults = dict(PLAN_DEFAULTS.get(code, PLAN_DEFAULTS[DEFAULT_PLAN_CODE]))
    if config:
        for key in ("seats", "mail_gb", "files_gb"):
            if config.get(key) is not None:
                defaults[key] = int(config[key])
    return code, defaults


def map_foss_client(profile: dict[str, Any], domain: str) -> dict[str, Any]:
    first, last = split_manager_name(profile.get("manager_name"))
    email = (profile.get("manager_email") or profile.get("email_billing") or "").strip().lower()
    addr = profile.get("address") or {}
    return {
        "email": email,
        "first_name": first,
        "last_name": last,
        "company": profile.get("legal_name") or profile.get("trade_name") or domain,
        "company_vat": _digits_only(profile.get("tax_id")),
        "phone": profile.get("phone_mobile") or profile.get("contact_phone") or profile.get("phone_landline") or "",
        "address_1": addr.get("street") or "",
        "city": addr.get("city") or "",
        "state": addr.get("state") or "",
        "postcode": addr.get("postal_code") or "",
        "country": addr.get("country") or "BR",
        "currency": "BRL",
        "status": "active",
        "custom_ligbox_domain": domain,
    }


def map_foss_order(
    *,
    domain: str,
    profile: dict[str, Any],
    plan_code: str,
    config: dict[str, int],
    foss_client_id: str | int | None = None,
) -> dict[str, Any]:
    return {
        "client_id": foss_client_id,
        "product_slug": plan_code,
        "period": "1M",
        "domain": domain,
        "manager_email": profile.get("manager_email"),
        "manager_name": profile.get("manager_name"),
        "config": {
            "seats": config.get("seats"),
            "mail_gb": config.get("mail_gb"),
            "files_gb": config.get("files_gb"),
        },
    }


def map_openpanel(
    *,
    domain: str,
    profile: dict[str, Any],
    plan_code: str,
    config: dict[str, int],
) -> dict[str, Any]:
    username = derive_openpanel_username(domain, profile)
    return {
        "username": username,
        "email": profile.get("manager_email"),
        "plan_name": plan_code,
        "domain": domain,
        "metadata": {
            "bundle_type": "ligbox_mail" if plan_code.startswith("ligbox-mail") else "ligbox_hosting",
            "max_seats": config.get("seats"),
            "mail_gb_per_seat": config.get("mail_gb"),
            "files_gb_per_seat": config.get("files_gb"),
            "easydmarc": True,
            "wizard_domain": domain,
            "manager_name": profile.get("manager_name"),
            "manager_email": profile.get("manager_email"),
        },
    }


def map_odoo_partner(profile: dict[str, Any], domain: str, foss_client_id: str | int | None = None) -> dict[str, Any]:
    addr = profile.get("address") or {}
    return {
        "name": profile.get("legal_name") or profile.get("trade_name") or domain,
        "display_name": profile.get("trade_name") or profile.get("legal_name") or domain,
        "vat": profile.get("tax_id") or "",
        "email": profile.get("email_billing") or profile.get("manager_email") or "",
        "phone": profile.get("phone_mobile") or profile.get("contact_phone") or "",
        "street": addr.get("street") or "",
        "city": addr.get("city") or "",
        "zip": addr.get("postal_code") or "",
        "country_code": addr.get("country") or "BR",
        "company_type": "company",
        "customer_rank": 1,
        "ref": domain,
        "comment": {
            "manager_email": profile.get("manager_email"),
            "foss_client_id": foss_client_id,
            "domain": domain,
        },
    }


def map_wizard_mail_bundle(
    *,
    domain: str,
    profile: dict[str, Any],
    config: dict[str, int],
    foss_order_id: str | int | None = None,
) -> dict[str, Any]:
    return {
        "domain": domain,
        "admin_email": profile.get("manager_email"),
        "admin_name": profile.get("manager_name"),
        "seats": config.get("seats"),
        "mail_gb_per_seat": config.get("mail_gb"),
        "files_gb_per_seat": config.get("files_gb"),
        "foss_order_id": foss_order_id,
    }


def build_activation_preview(
    account: dict[str, Any],
    *,
    plan_code: str | None = None,
    config: dict[str, Any] | None = None,
) -> dict[str, Any]:
    domain = str(account.get("domain") or "").strip().lower()
    profile = normalize_company_profile(account.get("company_profile"), domain=domain)
    code, cfg = resolve_plan_config(plan_code or account.get("plan_code"), config)
    foss_id = account.get("external_customer_id")
    billing_state = account.get("billing_state") or "awaiting_billing_validation"
    can_activate = billing_state in ACTIVATABLE_STATES and not account.get("recurrence_active")

    return {
        "billing_account_id": account.get("id"),
        "domain": domain,
        "billing_state": billing_state,
        "can_activate": can_activate,
        "plan_code": code,
        "config": cfg,
        "company_profile": profile,
        "mapped": {
            "foss_client": map_foss_client(profile, domain),
            "foss_order": map_foss_order(
                domain=domain,
                profile=profile,
                plan_code=code,
                config=cfg,
                foss_client_id=foss_id,
            ),
            "openpanel": map_openpanel(domain=domain, profile=profile, plan_code=code, config=cfg),
            "odoo_partner": map_odoo_partner(profile, domain, foss_client_id=foss_id),
            "wizard_mail_bundle": map_wizard_mail_bundle(
                domain=domain,
                profile=profile,
                config=cfg,
            ),
        },
        "existing_ids": {
            "foss_client_id": foss_id,
            "external_subscription_id": account.get("external_subscription_id"),
            "openpanel_username": profile.get("openpanel_username"),
        },
        "notes": (
            "Preview read-only — confirmar dados antes de Activar conta."
        ),
    }
