import base64
import json
import logging
import re
from typing import Dict, Any
from urllib.error import HTTPError, URLError
from urllib.request import Request as UrlRequest, urlopen

from app.core.config import settings

logger = logging.getLogger(__name__)


class SmsService:
    API_URL = "https://api.cpsms.dk/v2/send"

    @staticmethod
    def normalize_recipient(number: str) -> str:
        cleaned = re.sub(r"[^0-9+]", "", (number or "").strip())
        if not cleaned:
            raise ValueError("Mobilnummer mangler")

        if cleaned.startswith("+"):
            cleaned = cleaned[1:]
        if cleaned.startswith("00"):
            cleaned = cleaned[2:]

        if not cleaned.isdigit():
            raise ValueError("Ugyldigt mobilnummer")

        if len(cleaned) == 8:
            cleaned = "45" + cleaned

        if len(cleaned) < 8:
            raise ValueError("Ugyldigt mobilnummer")

        return cleaned

    @staticmethod
    def _authorization_header() -> str:
        username = (settings.SMS_USERNAME or "").strip()
        api_key = (settings.SMS_API_KEY or "").strip()

        if not username or not api_key:
            raise ValueError("SMS er ikke konfigureret (SMS_USERNAME/SMS_API_KEY mangler)")

        raw = f"{username}:{api_key}".encode("utf-8")
        token = base64.b64encode(raw).decode("ascii")
        return f"Basic {token}"

    @classmethod
    def send_sms(cls, to: str, message: str, sender: str | None = None) -> Dict[str, Any]:
        sms_message = (message or "").strip()
        if not sms_message:
            raise ValueError("SMS-besked må ikke være tom")
        if len(sms_message) > 1530:
            raise ValueError("SMS-besked er for lang (max 1530 tegn)")

        recipient = cls.normalize_recipient(to)
        sms_sender = (sender or settings.SMS_SENDER or "").strip()
        if not sms_sender:
            raise ValueError("SMS afsender mangler (SMS_SENDER)")

        payload = {
            "to": recipient,
            "message": sms_message,
            "from": sms_sender,
        }

        body = json.dumps(payload).encode("utf-8")
        request = UrlRequest(cls.API_URL, data=body, method="POST")
        request.add_header("Content-Type", "application/json")
        request.add_header("Authorization", cls._authorization_header())

        try:
            with urlopen(request, timeout=15) as response:
                response_body = response.read().decode("utf-8")
                response_data = json.loads(response_body) if response_body else {}
                return {
                    "http_status": getattr(response, "status", 200),
                    "provider": "cpsms",
                    "recipient": recipient,
                    "result": response_data,
                }
        except HTTPError as e:
            error_body = ""
            try:
                error_body = e.read().decode("utf-8")
            except Exception:
                error_body = ""

            logger.error("❌ CPSMS HTTP error: status=%s body=%s", e.code, error_body)
            raise RuntimeError(f"CPSMS fejl ({e.code})")
        except URLError as e:
            logger.error("❌ CPSMS connection error: %s", e)
            raise RuntimeError("Kunne ikke kontakte CPSMS")
