from __future__ import annotations

import json
import ctypes
from dataclasses import dataclass
from typing import Any

from license_client import _load_dll


@dataclass
class CustomerRegistrationInput:
    tax_code: str
    legal_name: str
    address: str = ""
    email: str = ""
    phone: str = ""
    fax: str = ""
    website: str = ""
    representative: str = ""
    representative_title: str = ""
    bank_account: str = ""
    notes: str = ""


@dataclass
class CustomerRegistrationResult:
    ok: bool
    created: bool
    tax_code: str
    message: str
    record: dict[str, Any] | None = None


def _normalize_tax_code(tax_code: str) -> str:
    return "".join(ch for ch in (tax_code or "").strip() if ch.isdigit())


def register_customer_once(data: CustomerRegistrationInput) -> CustomerRegistrationResult:
    tax_code = _normalize_tax_code(data.tax_code)
    legal_name = (data.legal_name or "").strip()

    if not tax_code:
        return CustomerRegistrationResult(False, False, "", "Mã số thuế không hợp lệ")
    if not legal_name:
        return CustomerRegistrationResult(False, False, tax_code, "Tên pháp lý là bắt buộc")

    payload = {
        "tax_code": tax_code,
        "name": legal_name,
        "address": (data.address or "").strip(),
        "notes": (data.notes or "").strip(),
        "email": (data.email or "").strip(),
        "phone": (data.phone or "").strip(),
        "fax": (data.fax or "").strip(),
        "website": (data.website or "").strip(),
        "representative": (data.representative or "").strip(),
        "representative_title": (data.representative_title or "").strip(),
        "bank_account": (data.bank_account or "").strip(),
        "legal_name": legal_name,
    }
    try:
        dll = _load_dll()
        if not hasattr(dll, "register_customer_once_json"):
            return CustomerRegistrationResult(
                ok=False,
                created=False,
                tax_code=tax_code,
                message="DLL chưa hỗ trợ register_customer_once_json",
            )

        out_buf = ctypes.create_string_buffer(2048)
        rc = dll.register_customer_once_json(
            json.dumps(payload, ensure_ascii=False).encode("utf-8"),
            out_buf,
            ctypes.sizeof(out_buf),
        )
        if rc < 0:
            return CustomerRegistrationResult(
                ok=False,
                created=False,
                tax_code=tax_code,
                message=f"DLL lỗi nội bộ, mã={rc}",
            )

        raw = out_buf.value.decode("utf-8", errors="replace")
        try:
            result_json: dict[str, Any] = json.loads(raw) if raw else {}
        except json.JSONDecodeError:
            result_json = {
                "ok": False,
                "created": False,
                "tax_code": tax_code,
                "message": f"DLL trả dữ liệu không hợp lệ: {raw}",
            }

        return CustomerRegistrationResult(
            ok=bool(result_json.get("ok", False)),
            created=bool(result_json.get("created", False)),
            tax_code=str(result_json.get("tax_code", tax_code)),
            message=str(result_json.get("message", "Không có phản hồi từ DLL")),
            record=result_json.get("record") if isinstance(result_json.get("record"), dict) else None,
        )
    except Exception as exc:
        return CustomerRegistrationResult(
            ok=False,
            created=False,
            tax_code=tax_code,
            message=f"Đăng ký qua DLL thất bại: {exc}",
        )
