"""cPanel adapter for the Fetch Data Toggle system."""
from __future__ import annotations

import logging
from typing import Any, Dict, List

from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession

from services.module_sync.adapters import registry
from services.module_sync.engine import STATUS_FAILED, STATUS_OK, SyncAttempt

logger = logging.getLogger(__name__)


def _preview(obj: Any, limit: int = 4000) -> str:
    text = str(obj)
    return text[:limit]


class _CpanelAdapter:
    module_name = "cpanel"
    module_label = "cPanel Reseller"

    async def fetch_clients(self, db: AsyncSession) -> SyncAttempt:
        """Mirror WHMCS clients count (shared across reseller modules)."""
        try:
            from services import whmcs

            result = await whmcs.call_whmcs_safe("GetClients", {"limitnum": 1000})
            block = (result or {}).get("clients") or {}
            clients: List[Dict[str, Any]] = list(block.get("client", []) or [])
            return SyncAttempt(
                status=STATUS_OK,
                items_fetched=len(clients),
                raw_response=_preview(result),
            )
        except Exception as exc:  # noqa: BLE001
            logger.exception("cpanel.fetch_clients failed")
            return SyncAttempt(status=STATUS_FAILED, error_message=str(exc)[:500])

    async def fetch_accounts(self, db: AsyncSession) -> SyncAttempt:
        """Count cPanel accounts mirrored locally, and on the first active WHM server."""
        try:
            from models.cpanel import CpanelClientAccount, CpanelServer

            local = (await db.execute(select(func.count(CpanelClientAccount.id)))).scalar() or 0
            remote = 0
            servers = (
                await db.execute(select(CpanelServer).where(CpanelServer.is_active.is_(True)).limit(3))
            ).scalars().all()
            for server in servers:
                try:
                    from services.cpanel.client import CpanelApi

                    data = await CpanelApi(server, db=db).list_accounts()
                    accts = ((data.get("data") or {}).get("acct") or []) if isinstance(data.get("data"), dict) else []
                    remote += len(accts)
                except Exception as exc:  # noqa: BLE001
                    logger.warning("cpanel.fetch_accounts server %s failed: %s", server.id, exc)
            return SyncAttempt(
                status=STATUS_OK,
                items_fetched=int(max(local, remote)),
                raw_response=f"local={local} remote={remote}",
            )
        except Exception as exc:  # noqa: BLE001
            logger.exception("cpanel.fetch_accounts failed")
            return SyncAttempt(status=STATUS_FAILED, error_message=str(exc)[:500])

    async def fetch_domains(self, db: AsyncSession) -> SyncAttempt:
        """Cross-check WHMCS domains against mirrored main_domain values."""
        try:
            from services import whmcs
            from models.cpanel import CpanelClientAccount

            result = await whmcs.call_whmcs_safe("GetClientsDomains", {"limitnum": 1000})
            block = (result or {}).get("domains") or {}
            whmcs_domains = list(block.get("domain", []) or [])
            whmcs_names = {str(d.get("domainname") or "").lower() for d in whmcs_domains if isinstance(d, dict)}

            accounts = (
                await db.execute(select(CpanelClientAccount.main_domain))
            ).scalars().all()
            local_domains = {str(d).lower() for d in accounts if d}

            linked = len(whmcs_names & local_domains)
            return SyncAttempt(
                status=STATUS_OK,
                items_fetched=len(whmcs_names),
                raw_response=f"whmcs={len(whmcs_names)} local={len(local_domains)} linked={linked}",
            )
        except Exception as exc:  # noqa: BLE001
            logger.exception("cpanel.fetch_domains failed")
            return SyncAttempt(status=STATUS_FAILED, error_message=str(exc)[:500])


registry.register(_CpanelAdapter())