"""
Multi-provider enrichment orchestrator (Apollo/ZoomInfo/Apify).

Current provider implementations for Apollo/ZoomInfo are stubs; this module
handles cache lookups and CSV I/O so providers can be implemented later.
"""

from __future__ import annotations

import csv
from pathlib import Path
from typing import Dict, List, Tuple

from g_gremlin import apollo, zoominfo
from g_gremlin import apify as apify_helpers
from g_gremlin import pdl
from g_gremlin import clearbit
from g_gremlin.enrichment_cache import get_cache, set_cache

ProviderResult = Dict[str, str]


def _normalize_company(name: str) -> str:
    return name.strip().lower()


def _provider_lookup(provider: str, company: str, fields: List[str]) -> ProviderResult:
    if provider == "apollo":
        return apollo.enrich_company(company, fields)
    if provider == "zoominfo":
        return zoominfo.enrich_company(company, fields)
    if provider == "apify":
        # Re-use apify helper for domain enrichment if needed; fallback to empty.
        res = apify_helpers.enrich_company_sync(company, country="US")
        data = res.get("data", {}) if isinstance(res, dict) else {}
        if fields:
            return {k: data.get(k) for k in fields if k in data}
        return data
    if provider == "pdl":
        return pdl.enrich_company(company, fields)
    if provider == "clearbit":
        return clearbit.enrich_company(company, fields)
    raise ValueError(f"Unsupported provider '{provider}'")


def enrich_csv(
    csv_path: Path,
    missing_fields: List[str],
    providers: List[str],
    company_column: str,
    cache_ttl: int = 86400,
    waterfall: bool = False,
    output_path: Path | None = None,
) -> Tuple[int, int, List[Dict[str, str]]]:
    """
    Enrich CSV rows missing specific fields.

    Returns tuple: (rows_processed, rows_enriched, rows)
    """
    with csv_path.open(newline="", encoding="utf-8-sig") as f:
        reader = list(csv.DictReader(f))

    if not reader:
        return 0, 0, []
    if company_column not in reader[0]:
        raise ValueError(f"Company column '{company_column}' not found in CSV.")

    rows_enriched = 0
    for row in reader:
        company_raw = row.get(company_column, "").strip()
        company_norm = _normalize_company(company_raw)
        needed = [field for field in missing_fields if not row.get(field)]
        if not needed:
            continue

        # Try cache first
        for field in needed.copy():
            cache_hit = get_cache(providers[0], company_norm, field)
            if cache_hit:
                row[field] = cache_hit.value
                needed.remove(field)

        if not needed:
            rows_enriched += 1
            continue

        for provider in providers:
            result = _provider_lookup(provider, company_raw, needed)
            if result:
                for field in needed.copy():
                    val = result.get(field)
                    if val:
                        row[field] = val
                        set_cache(provider, company_raw, company_norm, field, val, confidence=1.0, ttl_seconds=cache_ttl)
                        needed.remove(field)
            if not needed or not waterfall:
                break

        if not needed:
            rows_enriched += 1

    if output_path:
        output_path.parent.mkdir(parents=True, exist_ok=True)
        with output_path.open("w", newline="", encoding="utf-8") as f:
            writer = csv.DictWriter(f, fieldnames=reader[0].keys())
            writer.writeheader()
            writer.writerows(reader)

    return len(reader), rows_enriched, reader
