"""Cloudflare integration client.

Cloudflare Pages deployment and domain management.
"""
from __future__ import annotations
from typing import Optional

import httpx
import structlog

from src.config import get_settings

logger = structlog.get_logger()
CF_API = "https://api.cloudflare.com/client/v4"


class CloudflareClient:
    def __init__(self, api_token: Optional[str] = None, account_id: Optional[str] = None):
        settings = get_settings()
        self._token = api_token or settings.cloudflare_api_token
        self._account_id = account_id or settings.cloudflare_account_id

    def _headers(self) -> dict:
        return {
            "Authorization": f"Bearer {self._token}",
            "Content-Type": "application/json",
        }

    async def create_pages_project(self, project_name: str) -> dict:
        async with httpx.AsyncClient() as client:
            resp = await client.post(
                f"{CF_API}/accounts/{self._account_id}/pages/projects",
                headers=self._headers(),
                json={
                    "name": project_name,
                    "production_branch": "main",
                },
            )
            resp.raise_for_status()
            data = resp.json()
            logger.info("cf_pages_project_created", name=project_name)
            return data["result"]

    async def create_deployment(self, project_name: str, branch: str = "main") -> dict:
        async with httpx.AsyncClient() as client:
            resp = await client.post(
                f"{CF_API}/accounts/{self._account_id}/pages/projects/{project_name}/deployments",
                headers=self._headers(),
                json={"branch": branch},
            )
            resp.raise_for_status()
            data = resp.json()
            logger.info("cf_deployment_created", project=project_name, id=data["result"]["id"])
            return data["result"]

    async def get_deployment(self, project_name: str, deployment_id: str) -> dict:
        async with httpx.AsyncClient() as client:
            resp = await client.get(
                f"{CF_API}/accounts/{self._account_id}/pages/projects/{project_name}/deployments/{deployment_id}",
                headers=self._headers(),
            )
            resp.raise_for_status()
            return resp.json()["result"]

    async def add_custom_domain(self, project_name: str, domain: str) -> dict:
        async with httpx.AsyncClient() as client:
            resp = await client.post(
                f"{CF_API}/accounts/{self._account_id}/pages/projects/{project_name}/domains",
                headers=self._headers(),
                json={"name": domain},
            )
            resp.raise_for_status()
            data = resp.json()
            logger.info("cf_domain_added", project=project_name, domain=domain)
            return data["result"]

    async def delete_custom_domain(self, project_name: str, domain: str) -> None:
        async with httpx.AsyncClient() as client:
            resp = await client.delete(
                f"{CF_API}/accounts/{self._account_id}/pages/projects/{project_name}/domains/{domain}",
                headers=self._headers(),
            )
            resp.raise_for_status()
            logger.info("cf_domain_deleted", project=project_name, domain=domain)

    async def create_zone(self, domain: str) -> dict:
        async with httpx.AsyncClient() as client:
            resp = await client.post(f"{CF_API}/zones", headers=self._headers(), json={"name": domain, "account": {"id": self._account_id}})
            resp.raise_for_status()
            return resp.json()["result"]

    async def create_dns_record(self, zone_id: str, record: dict) -> dict:
        async with httpx.AsyncClient() as client:
            resp = await client.post(f"{CF_API}/zones/{zone_id}/dns_records", headers=self._headers(), json=record)
            resp.raise_for_status()
            return resp.json()["result"]
