from __future__ import annotations

import hashlib
import json
from typing import Any, Dict, List, Optional

from src.fmatch.ingest.connector_sdk.base import ConnectorBase, FetchResult


class CompaniesHouseStreamConnector(ConnectorBase):
    """Realtime Companies House stream consumer."""

    def __init__(self, http_client: Any, stream_url: str) -> None:
        self.http = http_client
        self.stream_url = stream_url

    def checkpoint_key(self) -> str:
        return "CH"

    def fetch(
        self,
        *,
        batch_id: Optional[str] = None,
        next_token: Optional[str] = None,
        resume: bool = False,
    ) -> FetchResult:
        params = {"since": next_token} if next_token else {}
        response = self.http.get(self.stream_url, params=params, timeout=30)
        response.raise_for_status()
        payload = response.json()
        items = payload.get("items", [])
        nxt = payload.get("next_since")
        return FetchResult(
            items=items, next_token=nxt, batch_id=payload.get("etag") or nxt
        )

    def process(self, *, item: Dict[str, Any]) -> Dict[str, Any]:
        raw = item
        record = raw.get("data", {}) or {}
        sha256 = hashlib.sha256(
            json.dumps(raw, sort_keys=True).encode("utf-8")
        ).hexdigest()
        company_number = raw.get("company_number") or raw.get("resource_id") or ""
        legal_name = record.get("company_name") or ""
        status_raw = (record.get("company_status") or "unknown").lower()
        status = (
            "active"
            if status_raw == "active"
            else ("dissolved" if status_raw == "dissolved" else "unknown")
        )
        seen_at = raw.get("event", {}).get("timepoint") or raw.get("timestamp")

        urls: List[str] = []
        website = record.get("company_website") or record.get(
            "registered_office_address", {}
        ).get("website")
        if isinstance(website, str):
            candidate = website.strip()
            if candidate:
                if not candidate.startswith(("http://", "https://")):
                    candidate = f"https://{candidate}"
                urls.append(candidate)

        source_event = {
            "source": "CH",
            "jurisdiction": "GB",
            "raw_id": str(company_number),
            "raw_payload": raw,
            "seen_at": seen_at,
            "sha256": sha256,
            "license_tag": "redistributable",
        }

        normalized_entity = {
            "legal_name": legal_name,
            "country_code": "GB",
            "status": status,
            "ids": [{"type": "CH", "value": str(company_number)}]
            if company_number
            else [],
            "urls": urls,
            "updated_at": seen_at,
        }

        status_type = "status:dissolved" if status == "dissolved" else "status"
        evidence = [
            {
                "entity_key": sha256,
                "source": "CH",
                "evidence_type": "authority_id",
                "payload": {"company_number": company_number},
                "seen_at": seen_at,
                "license_tag": "redistributable",
            },
            {
                "entity_key": sha256,
                "source": "CH",
                "evidence_type": status_type,
                "payload": {"status": status_raw},
                "seen_at": seen_at,
                "license_tag": "redistributable",
            },
        ]

        return {
            "source_event": source_event,
            "normalized_entity": normalized_entity,
            "promotion_evidence": evidence,
        }
