from __future__ import annotations

from typing import Any

from .models import BUILTIN_CUSTOMER_FIELDS, FieldDefinition
from .normalizer import clean_text, guess_value_type, stable_field_key


BUILTIN_FIELD_ALIASES: dict[str, set[str]] = {
    "name": {"姓名", "名字", "客户名", "客户姓名", "name"},
    "primary_phone": {"电话", "手机号", "手机", "联系电话", "联系方式", "mobile", "phone"},
    "birthday": {"生日", "出生日期", "birth", "birthday"},
    "tags": {"标签", "分组", "tags"},
    "notes": {"备注", "说明", "note", "notes"},
}


GROUPED_RECORD_FIELD_ALIASES: dict[str, set[str]] = {
    "record_no": {"记录号", "编号", "单号", "保单号", "保单编号", "订单号", "合同号", "record_no"},
    "record_date": {"记录日期", "日期", "创建日期", "生效日", "生效日期", "保单生效日", "下单日"},
    "relationship": {"关系", "客户关系", "投被保人关系"},
    "item_name": {"项目名称", "产品名称", "商品名称", "服务名称", "险种", "产品"},
    "amount": {"金额", "费用", "消费金额", "保费", "保费（元）", "amount", "price"},
    "term": {"期限", "周期", "缴费期限", "缴费期"},
    "owner_name": {"负责人", "业务员", "顾问", "原业务员", "销售"},
}


def build_alias_lookup(alias_map: dict[str, set[str]]) -> dict[str, str]:
    lookup: dict[str, str] = {}
    for field_key, aliases in alias_map.items():
        for alias in aliases:
            lookup[clean_text(alias).lower()] = field_key
    return lookup


BUILTIN_ALIAS_LOOKUP = build_alias_lookup(BUILTIN_FIELD_ALIASES)
GROUPED_RECORD_ALIAS_LOOKUP = build_alias_lookup(GROUPED_RECORD_FIELD_ALIASES)


def resolve_builtin_field(label: str) -> str | None:
    return BUILTIN_ALIAS_LOOKUP.get(clean_text(label).lower())


def resolve_grouped_record_field(label: str) -> str | None:
    return GROUPED_RECORD_ALIAS_LOOKUP.get(clean_text(label).lower())


def resolve_existing_field(label: str, existing_defs: list[dict[str, Any]]) -> str | None:
    normalized = clean_text(label).lower()
    for item in existing_defs:
        if normalized == clean_text(item["label"]).lower():
            return item["field_key"]
        aliases = item.get("aliases") or []
        if normalized in {clean_text(alias).lower() for alias in aliases}:
            return item["field_key"]
    return None


def resolve_or_create_field(
    *,
    label: str,
    sample_values: list[Any],
    existing_defs: list[dict[str, Any]],
    source: str,
) -> FieldDefinition | None:
    text = clean_text(label)
    if not text:
        return None
    builtin_key = resolve_builtin_field(text)
    if builtin_key:
        return None
    existing_key = resolve_existing_field(text, existing_defs)
    field_key = existing_key or stable_field_key(text)
    aliases = [text]
    value_type = guess_value_type(text, sample_values)
    return FieldDefinition(
        field_key=field_key,
        label=text,
        value_type=value_type,
        entity_type="customer",
        is_required=False,
        source=source,
        status="active",
        aliases=aliases,
    )


def create_schema_from_labels(labels: list[str], existing_defs: list[dict[str, Any]]) -> list[FieldDefinition]:
    results: list[FieldDefinition] = []
    for label in labels:
        if resolve_builtin_field(label):
            continue
        field_def = resolve_or_create_field(
            label=label,
            sample_values=[],
            existing_defs=existing_defs,
            source="nl_generated",
        )
        if field_def and field_def.field_key not in {item.field_key for item in results}:
            results.append(field_def)
    return results


def is_builtin_field(field_key: str) -> bool:
    return field_key in BUILTIN_CUSTOMER_FIELDS
