#!/usr/bin/env python3
"""
Modulo do FUNIL LINKIA por tag.

Reaproveita a coleta pesada de contatos GHL que ja e feita em
tracking.coletar_atribuicao_cached() e adiciona a etapa de pageviews
(a partir do JSONL local).

Etapas:
  Visitantes  -> pageviews da landing no periodo
  Leads       -> contatos criados no periodo (dateAdded no range)
  Iniciaram   -> contatos com tag iniciou_fluxo_compra_*
  Compraram   -> contatos com tag comprou-*

Taxas de conversao sao calculadas etapa-a-etapa.
"""
from __future__ import annotations

import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Iterable

from zoneinfo import ZoneInfo

TZ_BR = ZoneInfo("America/Sao_Paulo")
TZ_UTC = ZoneInfo("UTC")

PAGEVIEWS_FILE = Path("/opt/mia/workspace/clientes/px3lab/tracking/pageviews.jsonl")


def _parse_dt(v: str):
    if not v:
        return None
    try:
        return datetime.fromisoformat(v.replace("Z", "+00:00"))
    except Exception:
        return None


def _iter_pageviews() -> Iterable[dict]:
    if not PAGEVIEWS_FILE.exists():
        return
    try:
        with PAGEVIEWS_FILE.open("r", encoding="utf-8") as f:
            for line in f:
                line = line.strip()
                if not line:
                    continue
                try:
                    yield json.loads(line)
                except Exception:
                    continue
    except Exception:
        return


def contar_pageviews(inicio_utc: datetime, fim_utc: datetime) -> int:
    total = 0
    for pv in _iter_pageviews():
        dt = _parse_dt(pv.get("ts", ""))
        if dt and inicio_utc <= dt <= fim_utc:
            total += 1
    return total


def montar_funil(
    contatos: list[dict],
    inicio_utc: datetime,
    fim_utc: datetime,
    tags_compra: set[str],
    tags_iniciou: set[str],
) -> dict:
    """Recebe contatos GHL crus e retorna funil no periodo."""
    leads = 0
    iniciaram = 0
    compraram = 0

    for c in contatos:
        dt = _parse_dt(c.get("dateAdded") or "")
        if not dt or not (inicio_utc <= dt <= fim_utc):
            continue
        leads += 1
        tags = [str(t).lower() for t in (c.get("tags") or [])]
        if any(t in tags_iniciou for t in tags):
            iniciaram += 1
        if any(t in tags_compra for t in tags):
            compraram += 1

    visitantes = contar_pageviews(inicio_utc, fim_utc)

    def _pct(num, denom):
        return round(num / denom * 100, 2) if denom else 0.0

    etapas = [
        {
            "nome": "Visitantes (LP)",
            "descricao": "Pageviews rastreados na landing",
            "count": visitantes,
            "conv_anterior_pct": None,      # topo do funil
            "cor": "#94a3b8",
        },
        {
            "nome": "Leads (Linkia)",
            "descricao": "Contatos criados no periodo",
            "count": leads,
            "conv_anterior_pct": _pct(leads, visitantes),
            "cor": "#60a5fa",
        },
        {
            "nome": "Iniciaram fluxo",
            "descricao": "Tag iniciou_fluxo_compra_*",
            "count": iniciaram,
            "conv_anterior_pct": _pct(iniciaram, leads),
            "cor": "#fbbf24",
        },
        {
            "nome": "Compraram",
            "descricao": "Tag comprou-*",
            "count": compraram,
            "conv_anterior_pct": _pct(compraram, iniciaram),
            "cor": "#4ade80",
        },
    ]

    return {
        "etapas": etapas,
        "kpis": {
            "visitantes": visitantes,
            "leads": leads,
            "iniciaram": iniciaram,
            "compraram": compraram,
            "conv_visitante_lead":  _pct(leads, visitantes),
            "conv_lead_iniciou":    _pct(iniciaram, leads),
            "conv_iniciou_comprou": _pct(compraram, iniciaram),
            "conv_visitante_compra": _pct(compraram, visitantes),
        },
        "gerado_em": datetime.now(TZ_UTC).isoformat(timespec="seconds"),
    }
