from __future__ import annotations

from typing import Any, Dict, List, Optional


def _as_dict(value: Any) -> Dict[str, Any]:
    return value if isinstance(value, dict) else {}


def _as_list(value: Any) -> List[Any]:
    return value if isinstance(value, list) else []


def _value(value: Any) -> str:
    return str(value or "").strip()


def _missing_label(field: Any) -> str:
    raw = str(field or "").strip()
    labels = {
        "shipment.recipient_name": "Contacto no local",
        "recipient_name": "Contacto no local",
        "shipment.recipient_phone": "Telefone",
        "recipient_phone": "Telefone",
        "produto/equipamento a recolher": "Equipamento a recolher",
        "equipment": "Equipamento a recolher",
        "motivo/instruções da recolha": "Motivo da recolha",
        "reason": "Motivo da recolha",
        "data preferida para recolha": "Data preferida",
        "preferred_date": "Data preferida",
        "billing.tax_id": "NIF",
        "billing.billing_address": "Morada fiscal",
        "billing.billing_email": "Email faturação",
        "shipment.delivery_address": "Morada de entrega",
        "shipment.pickup_address": "Morada de recolha",
    }
    return labels.get(raw, raw.replace("_", " ").replace(".", " · ").strip().capitalize() or "Dado em falta")


def build_preparation_view_model(task: Dict[str, Any], preparation: Optional[Dict[str, Any]]) -> Dict[str, Any]:
    prep = preparation or {}
    extracted = _as_dict(prep.get("extracted_data"))
    shipment = _as_dict(extracted.get("shipment"))
    customer = _as_dict(extracted.get("customer"))
    billing = _as_dict(extracted.get("billing"))
    sale = _as_dict(extracted.get("sale"))

    raw_missing = prep.get("missing_fields") or extracted.get("missing_fields") or []
    missing = [{"label": _missing_label(item), "raw": str(item or "")} for item in _as_list(raw_missing)]

    confirmed: List[Dict[str, str]] = []
    for label, value in [
        ("Local de recolha", shipment.get("pickup_address")),
        ("Morada de entrega", shipment.get("delivery_address")),
        ("Contacto", shipment.get("recipient_name")),
        ("Telefone", shipment.get("recipient_phone")),
        ("Empresa", customer.get("company") or task.get("customer_name")),
        ("Email", customer.get("email") or task.get("customer_email")),
        ("NIF", customer.get("tax_id") or billing.get("tax_id")),
    ]:
        v = _value(value)
        if v:
            confirmed.append({"label": label, "value": v})

    products = _as_list(sale.get("products"))
    product_names = [str(p.get("name") or p.get("description") or "").strip() for p in products if isinstance(p, dict)]
    product_names = [x for x in product_names if x]
    if product_names:
        confirmed.append({"label": "Produto", "value": ", ".join(product_names[:3])})

    suggested = _value(prep.get("suggested_reply") or extracted.get("suggested_reply"))

    action = _value(task.get("action")) or "Rever tarefa"
    primary_action = "Pedir dados em falta ao cliente" if missing else action

    return {
        "status": prep.get("status") or ("missing_data" if missing else "ready"),
        "prep_type": prep.get("prep_type") or "generic",
        "primary_action": primary_action,
        "missing_fields": missing,
        "confirmed_fields": confirmed,
        "suggested_reply": suggested,
        "confidence": prep.get("confidence"),
        "technical": {
            "customer": customer,
            "billing": billing,
            "sale": sale,
            "shipment": shipment,
        },
    }
