import asyncio
import logging
from datetime import date, datetime
from typing import Any, Dict, List, Optional
import whois

from integrations.base import RegistrarBase
from dns_checker import check_all_record_types

logger = logging.getLogger(__name__)


class CustomWhoisIntegration(RegistrarBase):
    """
    Generic / Custom Registrar Integration.
    Allows managing domains from any registrar (Hostinger, Dynadot, AWS, OVH, etc.)
    using automated WHOIS queries for expiration dates and DNS lookups.
    """

    def __init__(self, credentials: Dict[str, Any]) -> None:
        raw_domains = credentials.get("domains", "")
        if isinstance(raw_domains, list):
            self.domains_list = [d.strip().lower() for d in raw_domains if d.strip()]
        else:
            # Comma or newline separated
            self.domains_list = [
                d.strip().lower()
                for line in raw_domains.replace(",", "\n").splitlines()
                if (d := line.strip())
            ]

    async def test_connection(self) -> bool:
        """Verify at least one domain is configured."""
        if not self.domains_list:
            raise ValueError("Please provide at least one domain name to track.")
        return True

    def _query_whois(self, domain_name: str) -> Optional[date]:
        try:
            w = whois.whois(domain_name)
            exp = w.expiration_date
            if isinstance(exp, list) and exp:
                exp = exp[0]
            if isinstance(exp, datetime):
                return exp.date()
            elif isinstance(exp, date):
                return exp
        except Exception as e:
            logger.warning(f"WHOIS lookup failed for {domain_name}: {e}")
        return None

    async def list_domains(self) -> List[Dict[str, Any]]:
        """Query WHOIS for each tracked domain concurrently in a thread pool."""
        domains: List[Dict[str, Any]] = []
        loop = asyncio.get_running_loop()

        for domain_name in self.domains_list:
            expiry_date = await loop.run_in_executor(None, self._query_whois, domain_name)
            domains.append({
                "domain_name": domain_name,
                "expiry_date": expiry_date,
                "auto_renew": False,
                "status": "active",
                "registrar_domain_id": domain_name,
            })

        return domains

    async def get_dns_records(self, domain_name: str) -> List[Dict[str, Any]]:
        """Resolve current active DNS records via public DNS resolvers."""
        records: List[Dict[str, Any]] = []
        results = await check_all_record_types(domain_name)
        for r in results:
            if r.get("is_reachable") and r.get("resolved_values"):
                for val in r["resolved_values"]:
                    records.append({
                        "record_type": r["record_type"],
                        "name": "@",
                        "value": val,
                        "ttl": 300,
                        "priority": None,
                    })
        return records
