"""Scrape CIRE por NIF.

Pesquisa `ConsultasCire.aspx` filtrando por NIF/NIPC e devolve uma linha por
publicação onde esse NIF aparece em qualquer papel. O parsing de blocos e datas
vive em `cire_common.py`, partilhado com o sweep nacional
(`cire_announcements.py`), que usa a mesma página com filtro por datas.
"""
import json
import logging
from datetime import date
from typing import Any

from app.scrapers.base import (
    build_client,
    extract_aspnet_state,
    http_get,
    http_post,
    random_delay,
)
from app.scrapers.cire_common import (
    F_ACTOS,
    F_ATE,
    F_BTN,
    F_DESDE,
    F_DIAS,
    F_GRUPO,
    F_NUMERO,
    F_PESQUISA,
    F_TIPO,
    F_TRIBUNAIS,
    URL,
    parse_cire_page,
    parse_pt_date,
    split_process,
)

logger = logging.getLogger(__name__)


def _role_for(target_nif: str, parties: list[dict[str, str]]) -> str | None:
    for p in parties:
        if p.get("nif") == target_nif:
            return p.get("role") or None
    return None


async def scrape_cire_for_nif(
    nif: str,
    company_id: str,
    days: str = "todos",
) -> list[dict[str, Any]]:
    """Pesquisa CIRE por NIF na janela escolhida. Devolve uma linha por
    publicação onde o NIF aparece em qualquer papel (Insolvente, Administrador,
    Credor, Reclamante, …)."""
    async with build_client() as client:
        initial = await http_get(client, URL)
        vs = extract_aspnet_state(initial.text)
        payload = {
            **vs,
            F_TIPO: "nif",
            F_PESQUISA: nif,
            F_DIAS: days,
            F_TRIBUNAIS: "",
            F_GRUPO: "",
            F_ACTOS: "",
            F_NUMERO: "",
            F_DESDE: "",
            F_ATE: "",
            F_BTN: "Pesquisar",
        }
        await random_delay()
        r = await http_post(client, URL, data=payload, headers={"Referer": URL})

        all_blocks: list[dict[str, Any]] = []
        page = 1
        while True:
            page_data = parse_cire_page(r.text)
            all_blocks.extend(page_data["blocks"])
            if not page_data["has_next"]:
                break
            if page >= 20:  # tecto de segurança
                logger.warning("cire %s: hit pagination safety cap at page %d", nif, page)
                break
            vs_next = extract_aspnet_state(r.text)
            pager_payload = {
                **vs_next,
                "__EVENTTARGET": "ctl00$ContentPlaceHolder1$Pager1$lnkNext",
                "__EVENTARGUMENT": "",
            }
            for k in (F_BTN,):
                pager_payload.pop(k, None)
            await random_delay()
            r = await http_post(client, URL, data=pager_payload, headers={"Referer": URL})
            page += 1

    total = page_data["total"] if all_blocks else 0
    logger.info("cire nif=%s days=%s -> total_reported=%d parsed=%d", nif, days, total, len(all_blocks))

    out: list[dict[str, Any]] = []
    for entry in all_blocks:
        process_number, juizo = split_process(entry.get("processo") or "")
        if not process_number:
            continue
        tribunal = entry.get("tribunal") or "CITIUS/CIRE"
        date_filed = (
            parse_pt_date(entry.get("data"))
            or parse_pt_date(entry.get("data da propositura da ação"))
            or date.today()
        )
        role = _role_for(nif, entry.get("_parties") or [])
        out.append(
            {
                "company_id": company_id,
                "source": "cire",
                "process_number": process_number,
                "tribunal": tribunal,
                "juizo": juizo,
                "species": entry.get("espécie") or entry.get("especie") or entry.get("ato"),
                "role_in_process": role,
                "date_filed": date_filed,
                "raw_json": json.dumps(entry, ensure_ascii=False),
                "raw_html": None,
            }
        )
    return out
