from __future__ import annotations

import csv
import json
import logging
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Dict, Iterable, List


logger = logging.getLogger(__name__)

PROMOTIONS_PATH = (
    Path(__file__).resolve().parents[4] / "data" / "company_domain_promotions.csv"
)
CSV_HEADERS = [
    "ts_iso",
    "account_id",
    "name",
    "domain",
    "existing_domain",
    "match_confidence",
    "reason_chips",
    "source",
    "metadata_json",
]


def _ensure_file() -> None:
    if PROMOTIONS_PATH.exists():
        return
    try:
        PROMOTIONS_PATH.parent.mkdir(parents=True, exist_ok=True)
        with PROMOTIONS_PATH.open("w", encoding="utf-8", newline="") as fh:
            writer = csv.writer(fh)
            writer.writerow(CSV_HEADERS)
    except Exception as exc:  # noqa: BLE001
        logger.error(
            "Failed to initialise promotions file %s: %s", PROMOTIONS_PATH, exc
        )
        raise


def record_promotions(
    items: Iterable[Dict[str, Any]],
    *,
    account_id: str,
    source: str = "sheets",
) -> int:
    """
    Append promotion rows to disk for later review.

    Args:
        items: Iterable of promotion payloads (name/domain/etc.)
        account_id: API account performing the promotion
        source: Logical source of the promotion (sheets, api, etc.)

    Returns:
        Number of promotions written.
    """
    rows: List[List[Any]] = []
    now_iso = datetime.now(timezone.utc).isoformat()

    for item in items:
        name = (item.get("name") or "").strip()
        domain = (item.get("domain") or "").strip().lower()
        if not name or not domain:
            continue
        existing_domain = (item.get("existing_domain") or "").strip().lower()
        match_conf = item.get("match_confidence")
        try:
            match_conf = float(match_conf) if match_conf not in (None, "") else ""
        except (TypeError, ValueError):
            match_conf = ""
        reason_chips = item.get("reason_chips")
        if isinstance(reason_chips, str):
            reason_str = reason_chips
        elif isinstance(reason_chips, (list, tuple)):
            reason_str = ", ".join(str(chip).strip() for chip in reason_chips if chip)
        else:
            reason_str = ""

        metadata = item.get("metadata") or {}
        safe_meta: Dict[str, Any] = {}
        for key, value in metadata.items():
            try:
                safe_meta[key] = value
            except Exception:  # noqa: BLE001
                safe_meta[key] = str(value)

        rows.append(
            [
                now_iso,
                account_id,
                name,
                domain,
                existing_domain,
                match_conf,
                reason_str,
                source,
                json.dumps(safe_meta, ensure_ascii=True),
            ]
        )

    if not rows:
        return 0

    _ensure_file()
    try:
        with PROMOTIONS_PATH.open("a", encoding="utf-8", newline="") as fh:
            writer = csv.writer(fh)
            writer.writerows(rows)
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to append promotions to %s: %s", PROMOTIONS_PATH, exc)
        raise

    return len(rows)
