"""
CVR service for looking up Danish company information.

Primary provider: FirmaAPI (authenticated).
Legacy fallback: cvrapi.dk when no FirmaAPI key is configured.
"""
import asyncio
import aiohttp
import logging
from typing import Optional, Dict

from app.core.config import settings

logger = logging.getLogger(__name__)


class CVRService:
    """Service for CVR lookups using FirmaAPI (or legacy fallback)."""

    LEGACY_BASE_URL = "https://cvrapi.dk/api"

    @property
    def firmaapi_base_url(self) -> str:
        return settings.FIRMAAPI_BASE_URL.rstrip("/")

    @property
    def firmaapi_timeout(self) -> aiohttp.ClientTimeout:
        return aiohttp.ClientTimeout(total=settings.FIRMAAPI_TIMEOUT_SECONDS)

    @property
    def has_firmaapi_key(self) -> bool:
        return bool((settings.FIRMAAPI_API_KEY or "").strip())

    def _firmaapi_headers(self) -> Dict[str, str]:
        api_key = (settings.FIRMAAPI_API_KEY or "").strip()
        return {
            "Authorization": f"Bearer {api_key}",
            "Accept": "application/json",
        }

    @staticmethod
    def _normalize_payload(payload: Dict) -> Dict:
        return {
            "cvr": payload.get("cvr") or payload.get("vat"),
            "name": payload.get("name"),
            "address": payload.get("address"),
            "city": payload.get("city"),
            "zipcode": payload.get("zipcode"),
            "postal_code": payload.get("zipcode") or payload.get("postal_code"),
            "country": payload.get("country") or "DK",
            "phone": payload.get("phone"),
            "email": payload.get("email"),
            "website": payload.get("website"),
            "status": payload.get("status"),
            "source": "firmaapi" if payload.get("meta", {}).get("source") == "FirmaAPI" else payload.get("source", "firmaapi"),
        }
    
    async def lookup_by_name(self, company_name: str) -> Optional[Dict]:
        """
        Lookup company by name using CVR.dk API
        
        Args:
            company_name: Company name to search for
            
        Returns:
            Company data dict or None if not found
        """
        if not company_name or len(company_name) < 3:
            return None
        
        # Clean company name
        clean_name = company_name.strip()
        
        try:
            if self.has_firmaapi_key:
                async with aiohttp.ClientSession() as session:
                    async with session.get(
                        f"{self.firmaapi_base_url}/company/search",
                        params={"q": clean_name, "limit": 1},
                        headers=self._firmaapi_headers(),
                        timeout=self.firmaapi_timeout,
                    ) as response:
                        if response.status == 200:
                            data = await response.json()
                            results = data.get("results") or []
                            if results:
                                match = results[0]
                                logger.info("✅ Found CVR %s for '%s' via FirmaAPI", match.get("cvr"), company_name)
                                return self._normalize_payload(match)
                            return None

                        if response.status == 404:
                            return None

                        detail = await response.text()
                        logger.error("❌ FirmaAPI name lookup error %s for '%s': %s", response.status, company_name, detail[:240])
                        return None

            # Legacy fallback without API key
            params = {"search": clean_name, "country": "dk"}
            async with aiohttp.ClientSession() as session:
                async with session.get(
                    f"{self.LEGACY_BASE_URL}",
                    params=params,
                    timeout=aiohttp.ClientTimeout(total=10),
                ) as response:
                    if response.status == 200:
                        data = await response.json()
                        if data and "vat" in data:
                            return self._normalize_payload(data)
                    return None

        except asyncio.TimeoutError:
            logger.error(f"⏱️ CVR API timeout for '{company_name}'")
            return None
            
        except Exception as e:
            logger.error(f"❌ CVR lookup error for '{company_name}': {e}")
            return None
    
    async def lookup_by_cvr(self, cvr_number: str) -> Optional[Dict]:
        """
        Lookup company by CVR number
        
        Args:
            cvr_number: CVR number (8 digits)
            
        Returns:
            Company data dict or None if not found
        """
        if not cvr_number:
            return None
        
        # Extract only digits
        cvr_clean = ''.join(filter(str.isdigit, str(cvr_number)))
        
        if len(cvr_clean) != 8:
            logger.warning(f"⚠️ Invalid CVR number format: {cvr_number}")
            return None
        
        try:
            if self.has_firmaapi_key:
                async with aiohttp.ClientSession() as session:
                    async with session.get(
                        f"{self.firmaapi_base_url}/company/{cvr_clean}",
                        headers=self._firmaapi_headers(),
                        timeout=self.firmaapi_timeout,
                    ) as response:
                        if response.status == 200:
                            data = await response.json()
                            logger.info("✅ Validated CVR %s via FirmaAPI", cvr_clean)
                            return self._normalize_payload(data)

                        if response.status in (400, 404):
                            return None

                        detail = await response.text()
                        logger.error("❌ FirmaAPI CVR lookup error %s for %s: %s", response.status, cvr_clean, detail[:240])
                        return None

            # Legacy fallback without API key
            async with aiohttp.ClientSession() as session:
                async with session.get(
                    f"{self.LEGACY_BASE_URL}",
                    params={"vat": cvr_clean, "country": "dk"},
                    timeout=aiohttp.ClientTimeout(total=10),
                ) as response:
                    if response.status == 200:
                        data = await response.json()
                        if data and "vat" in data:
                            logger.info("✅ Validated CVR %s via legacy CVR API", cvr_clean)
                            return self._normalize_payload(data)
                    return None

        except Exception as e:
            logger.error(f"❌ CVR validation error for {cvr_number}: {e}")
            return None


def get_cvr_service() -> CVRService:
    """Get CVR service instance"""
    return CVRService()
