"""GoDaddy REST API v1 integration.

Credentials dict keys:
    api_key    – GoDaddy API key (from developer portal)
    api_secret – GoDaddy API secret
"""

from __future__ import annotations

import logging
from datetime import date, datetime
from typing import Any

import httpx

from integrations.base import RegistrarBase

logger = logging.getLogger(__name__)

_BASE_URL = "https://api.godaddy.com/v1"


def _parse_date(value: str | None) -> date | None:
    """Parse ISO-8601 datetime string from GoDaddy; return date part only."""
    if not value:
        return None
    # GoDaddy returns "2025-03-15T00:00:00.000Z" style strings
    for fmt in ("%Y-%m-%dT%H:%M:%S.%fZ", "%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%d"):
        try:
            return datetime.strptime(value[:19], fmt[:len(fmt.split("T")[0]) + 9]).date()
        except ValueError:
            continue
    # Fallback: take first 10 chars
    try:
        return datetime.strptime(value[:10], "%Y-%m-%d").date()
    except ValueError:
        return None


class GoDaddyIntegration(RegistrarBase):
    def __init__(self, credentials: dict[str, Any]) -> None:
        super().__init__(credentials)
        self._api_key: str = credentials["api_key"]
        self._api_secret: str = credentials["api_secret"]

    def _headers(self) -> dict[str, str]:
        return {
            "Authorization": f"sso-key {self._api_key}:{self._api_secret}",
            "Content-Type": "application/json",
            "Accept": "application/json",
        }

    # ------------------------------------------------------------------
    # list_domains
    # ------------------------------------------------------------------

    async def list_domains(self) -> list[dict[str, Any]]:
        """Fetch all domains from GoDaddy, paginating with the marker param."""
        domains: list[dict[str, Any]] = []
        marker: str | None = None

        async with httpx.AsyncClient(timeout=30, headers=self._headers()) as client:
            while True:
                params: dict[str, Any] = {
                    "limit": 1000,
                    "statuses": "ACTIVE,CANCELLED,TRANSFERRED_OUT,EXPIRED,PENDING_RENEWAL",
                }
                if marker:
                    params["marker"] = marker

                resp = await client.get(f"{_BASE_URL}/domains", params=params)

                if resp.status_code == 401:
                    raise ValueError("GoDaddy API error: Invalid credentials (401 Unauthorized)")
                if resp.status_code == 403:
                    raise ValueError("GoDaddy API error: Forbidden (403). Check API key permissions.")
                resp.raise_for_status()

                data: list[dict[str, Any]] = resp.json()

                if not data:
                    break

                for item in data:
                    raw_status = item.get("status", "UNKNOWN")
                    if raw_status == "ACTIVE":
                        status = "active"
                    elif raw_status in ("CANCELLED", "EXPIRED"):
                        status = "expired"
                    elif raw_status == "LOCKED":
                        status = "locked"
                    else:
                        status = "unknown"

                    domains.append(
                        {
                            "domain_name": item.get("domain", ""),
                            "expiry_date": _parse_date(item.get("expires")),
                            "auto_renew": item.get("renewAuto", False),
                            "status": status,
                            "registrar_domain_id": str(item.get("domainId", "")),
                        }
                    )

                # GoDaddy paginates: if we got exactly 1000 results, there may be more.
                if len(data) < 1000:
                    break

                # The marker for the next page is the last domain name returned.
                marker = data[-1].get("domain", None)
                if not marker:
                    break

        return domains

    # ------------------------------------------------------------------
    # get_dns_records
    # ------------------------------------------------------------------

    async def get_dns_records(self, domain_name: str) -> list[dict[str, Any]]:
        """Fetch all DNS records for *domain_name* via GET /domains/{domain}/records."""
        async with httpx.AsyncClient(timeout=30, headers=self._headers()) as client:
            resp = await client.get(f"{_BASE_URL}/domains/{domain_name}/records")

            if resp.status_code == 404:
                logger.warning("Domain %r not found in GoDaddy DNS records", domain_name)
                return []

            resp.raise_for_status()

        data: list[dict[str, Any]] = resp.json()
        records: list[dict[str, Any]] = []

        for item in data:
            records.append(
                {
                    "record_type": item.get("type", ""),
                    "name": item.get("name", "@"),
                    "value": item.get("data", ""),
                    "ttl": item.get("ttl"),
                    "priority": item.get("priority"),
                }
            )

        return records

    # ------------------------------------------------------------------
    # test_connection
    # ------------------------------------------------------------------

    async def test_connection(self) -> bool:
        """Validate credentials by fetching the first domain."""
        try:
            async with httpx.AsyncClient(timeout=15, headers=self._headers()) as client:
                resp = await client.get(f"{_BASE_URL}/domains", params={"limit": 1})
            return resp.status_code in (200, 204)
        except Exception as exc:
            logger.warning("GoDaddy test_connection failed: %s", exc)
            return False
