"""WHM (WebHost Manager / cPanel) REST API v1 integration.

Credentials dict keys:
    host - Hostname or IP of WHM server (e.g. '37.27.71.8', 'staging1.oneterminal.org', '37.27.71.8:2087')
    username - WHM username (e.g. 'root' or reseller username)
    api_token - WHM API Token or password
"""

from __future__ import annotations

import base64
import logging
from typing import Any
import httpx

logger = logging.getLogger(__name__)


def _normalize_whm_url(host: str) -> str:
    """Ensure host starts with https:// and targets WHM port 2087."""
    host_clean = host.strip()
    if not host_clean.startswith("http://") and not host_clean.startswith("https://"):
        host_clean = f"https://{host_clean}"

    # If cPanel port 2083 is given, replace with WHM port 2087
    if ":2083" in host_clean:
        host_clean = host_clean.replace(":2083", ":2087")
    elif ":2086" not in host_clean and ":2087" not in host_clean:
        # Append port 2087 if no port specified
        parts = host_clean.split("/")
        # parts[0] is https:, parts[1] is '', parts[2] is hostname
        if len(parts) >= 3 and ":" not in parts[2]:
            parts[2] = f"{parts[2]}:2087"
            host_clean = "/".join(parts)

    return host_clean.rstrip("/")


class WHMIntegration:
    def __init__(self, credentials: dict[str, Any]) -> None:
        self.raw_host: str = str(credentials.get("host", ""))
        self.base_url: str = _normalize_whm_url(self.raw_host)
        self.username: str = str(credentials.get("username", "")).strip()
        self.api_token: str = str(credentials.get("api_token", "") or credentials.get("password", "")).strip()

    def _headers(self) -> dict[str, str]:
        headers = {"Accept": "application/json"}
        if self.username and self.api_token:
            # WHM API token header format: whm username:token
            headers["Authorization"] = f"whm {self.username}:{self.api_token}"
        return headers

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

    async def test_connection(self) -> bool:
        """Verify credentials by querying WHM API version endpoint."""
        url = f"{self.base_url}/json-api/version"
        params = {"api.version": 1}

        try:
            async with httpx.AsyncClient(timeout=15, verify=False, headers=self._headers()) as client:
                resp = await client.get(url, params=params)
                if resp.status_code == 200:
                    data = resp.json()
                    metadata = data.get("metadata", {})
                    return metadata.get("result") == 1 or "version" in data
                return False
        except Exception as exc:
            logger.warning("WHM test_connection failed for %s: %s", self.base_url, exc)
            return False

    # ------------------------------------------------------------------
    # list_accounts (listaccts)
    # ------------------------------------------------------------------

    async def list_accounts(self, search_query: str = "") -> list[dict[str, Any]]:
        """Fetch cPanel accounts / hosted domains from WHM server via listaccts."""
        url = f"{self.base_url}/json-api/listaccts"
        params: dict[str, Any] = {"api.version": 1}

        if search_query:
            params["search"] = search_query
            params["searchtype"] = "domain"

        accounts: list[dict[str, Any]] = []

        async with httpx.AsyncClient(timeout=25, verify=False, headers=self._headers()) as client:
            resp = await client.get(url, params=params)
            resp.raise_for_status()
            data = resp.json()

            # WHM API v1 data structure
            raw_data = data.get("data", {})
            acct_list = raw_data.get("acct", []) if isinstance(raw_data, dict) else []

            for acct in acct_list:
                domain_name = acct.get("domain", "")
                cpanel_user = acct.get("user", "")
                ip_addr = acct.get("ip", "")
                owner_email = acct.get("email", "")
                plan_name = acct.get("plan", "")
                start_date = acct.get("startdate", "")
                is_suspended = bool(acct.get("suspended", 0))

                accounts.append(
                    {
                        "domain_name": domain_name,
                        "cpanel_user": cpanel_user,
                        "ip_address": ip_addr,
                        "email": owner_email,
                        "plan": plan_name,
                        "start_date": start_date,
                        "is_suspended": is_suspended,
                        "disk_used": acct.get("diskused", ""),
                        "disk_limit": acct.get("disklimit", ""),
                        "whm_host": self.base_url,
                    }
                )

        return accounts
