"""
HubSpot marketing read helpers.
"""

from __future__ import annotations

import json
from typing import Any, Dict, Iterable, List

from g_gremlin.hubspot import HubSpotClient


def list_forms(client: HubSpotClient, *, limit: int = 100) -> List[Dict[str, Any]]:
    return client.list_forms(limit=limit)


def list_form_submissions(client: HubSpotClient, form_id: str, *, limit: int = 100) -> List[Dict[str, Any]]:
    return client.list_form_submissions(form_id, limit=limit)


def list_emails(client: HubSpotClient, *, limit: int = 100) -> List[Dict[str, Any]]:
    return client.list_marketing_emails(limit=limit, include_stats=True)


def get_email_stats(
    client: HubSpotClient,
    email_id: str,
    *,
    start_timestamp: str | None = None,
    end_timestamp: str | None = None,
) -> Dict[str, Any]:
    return client.get_marketing_email_stats(
        email_id,
        start_timestamp=start_timestamp,
        end_timestamp=end_timestamp,
    )


def list_campaigns(client: HubSpotClient, *, limit: int = 100) -> List[Dict[str, Any]]:
    return client.list_campaigns(limit=limit)


def format_forms_rows(forms: Iterable[Dict[str, Any]]) -> List[Dict[str, Any]]:
    rows: List[Dict[str, Any]] = []
    for form in forms:
        rows.append(
            {
                "id": form.get("id"),
                "name": form.get("name"),
                "formType": form.get("formType"),
                "createdAt": form.get("createdAt"),
                "updatedAt": form.get("updatedAt"),
                "archived": form.get("archived"),
            }
        )
    return rows


def format_form_submission_rows(submissions: Iterable[Dict[str, Any]], *, form_id: str) -> List[Dict[str, Any]]:
    rows: List[Dict[str, Any]] = []
    for submission in submissions:
        values = submission.get("values") or []
        value_map = {}
        for item in values:
            name = item.get("name")
            value = item.get("value")
            if name:
                value_map[str(name)] = value
        rows.append(
            {
                "form_id": form_id,
                "conversionId": submission.get("conversionId"),
                "submittedAt": submission.get("submittedAt"),
                "pageUrl": submission.get("pageUrl"),
                "values_json": json.dumps(value_map, sort_keys=True),
            }
        )
    return rows


def format_email_rows(emails: Iterable[Dict[str, Any]]) -> List[Dict[str, Any]]:
    rows: List[Dict[str, Any]] = []
    for email in emails:
        counters = ((email.get("stats") or {}).get("counters") or {})
        rows.append(
            {
                "id": email.get("id"),
                "name": email.get("name"),
                "subject": email.get("subject"),
                "state": email.get("state"),
                "type": email.get("type"),
                "createdAt": email.get("createdAt"),
                "updatedAt": email.get("updatedAt"),
                "archived": email.get("archived"),
                "sent": counters.get("sent"),
                "delivered": counters.get("delivered"),
                "open": counters.get("open"),
                "click": counters.get("click"),
                "bounce": counters.get("bounce"),
            }
        )
    return rows


def format_email_stats_rows(payload: Dict[str, Any], *, email_id: str) -> List[Dict[str, Any]]:
    aggregate = payload.get("aggregate") or {}
    counters = aggregate.get("counters") or {}
    ratios = aggregate.get("ratios") or {}
    qualifier_stats = aggregate.get("qualifierStats") or {}
    device_breakdown = aggregate.get("deviceBreakdown") or {}
    row: Dict[str, Any] = {"email_id": email_id}
    row.update(_flatten_dict("counters", counters))
    row.update(_flatten_dict("ratios", ratios))
    row.update(_flatten_dict("qualifierStats", qualifier_stats))
    row.update(_flatten_dict("deviceBreakdown", device_breakdown))
    return [row]


def format_campaign_rows(campaigns: Iterable[Dict[str, Any]]) -> List[Dict[str, Any]]:
    rows: List[Dict[str, Any]] = []
    for campaign in campaigns:
        rows.append(
            {
                "id": campaign.get("id"),
                "name": campaign.get("name") or campaign.get("campaignName"),
                "state": campaign.get("state"),
                "createdAt": campaign.get("createdAt"),
                "updatedAt": campaign.get("updatedAt"),
                "archived": campaign.get("archived"),
            }
        )
    return rows


def _flatten_dict(prefix: str, payload: Dict[str, Any]) -> Dict[str, Any]:
    flattened: Dict[str, Any] = {}
    for key, value in (payload or {}).items():
        column = f"{prefix}_{key}"
        if isinstance(value, dict):
            flattened.update(_flatten_dict(column, value))
        elif isinstance(value, list):
            flattened[column] = json.dumps(value, sort_keys=True)
        else:
            flattened[column] = value
    return flattened


__all__ = [
    "format_campaign_rows",
    "format_email_rows",
    "format_email_stats_rows",
    "format_form_submission_rows",
    "format_forms_rows",
    "get_email_stats",
    "list_campaigns",
    "list_emails",
    "list_form_submissions",
    "list_forms",
]
