from datetime import datetime
from typing import TYPE_CHECKING

import httpx
import logfire

from app.config import get_settings

if TYPE_CHECKING:
    from app.models.customer import Customer
    from app.models.reservation import Reservation
    from app.models.restaurant import Restaurant

_TEM_API_URL = "https://api.scaleway.com/transactional-email/v1alpha1/regions/fr-par/emails"

_MONTHS_NL = [
    "januari",
    "februari",
    "maart",
    "april",
    "mei",
    "juni",
    "juli",
    "augustus",
    "september",
    "oktober",
    "november",
    "december",
]


def _format_dt_nl(dt: datetime) -> str:
    return f"{dt.day} {_MONTHS_NL[dt.month - 1]} {dt.year} om {dt.strftime('%H:%M')}"


class ScalewayEmailClient:
    def __init__(self, *, client: httpx.AsyncClient | None = None) -> None:
        settings = get_settings()
        self._enabled = bool(settings.SCALEWAY_TEM_SECRET_KEY and settings.SCALEWAY_PROJECT_ID)
        self._headers = {
            "X-Auth-Token": settings.SCALEWAY_TEM_SECRET_KEY,
            "X-Project-Id": settings.SCALEWAY_PROJECT_ID,
            "Content-Type": "application/json",
        }
        self._from_email = settings.SCALEWAY_FROM_EMAIL
        self._from_name = settings.SCALEWAY_FROM_NAME
        self._shared_client = client

    async def _send(self, to: str, subject: str, html: str) -> None:
        if not self._enabled:
            logfire.info("email_disabled", reason="missing_scaleway_credentials")
            return

        settings = get_settings()
        payload = {
            "from": {"email": self._from_email, "name": self._from_name},
            "to": [{"email": to}],
            "subject": subject,
            "html": html,
            "project_id": settings.SCALEWAY_PROJECT_ID,
        }
        send_headers = {
            "X-Auth-Token": settings.SCALEWAY_TEM_SECRET_KEY,
            "Content-Type": "application/json",
        }
        if self._shared_client is not None:
            try:
                response = await self._shared_client.post(
                    _TEM_API_URL,
                    json=payload,
                    headers=send_headers,
                )
                if not response.is_success:
                    logfire.error(
                        "scaleway_tem_error",
                        status=response.status_code,
                        body=response.text[:500],
                    )
            except Exception as exc:
                logfire.error("scaleway_tem_exception", error=str(exc))
            return

        try:
            async with httpx.AsyncClient() as client:
                response = await client.post(_TEM_API_URL, json=payload, headers=send_headers)
                if not response.is_success:
                    logfire.error(
                        "scaleway_tem_error",
                        status=response.status_code,
                        body=response.text[:500],
                    )
        except Exception as exc:
            logfire.error("scaleway_tem_exception", error=str(exc))

    async def send_reservation_confirmation(
        self,
        reservation: "Reservation",
        customer: "Customer",
        restaurant: "Restaurant",
    ) -> None:
        dt_str = _format_dt_nl(reservation.reserved_at)
        subject = f"Reservering bevestigd — {restaurant.name}"
        html = f"""<!DOCTYPE html>
<html><body style="font-family:sans-serif;max-width:600px;margin:auto;padding:24px">
<h2 style="color:#1a1a1a">Reservering bevestigd</h2>
<p>Beste {customer.name},</p>
<p>Uw reservering bij <strong>{restaurant.name}</strong> is bevestigd.</p>
<table style="border-collapse:collapse;width:100%;margin:16px 0">
  <tr><td style="padding:8px;border-bottom:1px solid #eee;color:#666">Datum &amp; tijd</td>
      <td style="padding:8px;border-bottom:1px solid #eee"><strong>{dt_str}</strong></td></tr>
  <tr><td style="padding:8px;border-bottom:1px solid #eee;color:#666">Aantal personen</td>
      <td style="padding:8px;border-bottom:1px solid #eee">
          <strong>{reservation.party_size} personen</strong></td></tr>
</table>
<p>Wilt u annuleren of wijzigen? Neem contact op via {restaurant.phone or "het restaurant"}.</p>
<p>Tot ziens bij {restaurant.name}!</p>
</body></html>"""
        await self._send(customer.email or "", subject, html)

    async def send_reservation_cancellation(
        self,
        reservation: "Reservation",
        customer: "Customer",
        restaurant: "Restaurant",
    ) -> None:
        dt_str = _format_dt_nl(reservation.reserved_at)
        subject = f"Reservering geannuleerd — {restaurant.name}"
        html = f"""<!DOCTYPE html>
<html><body style="font-family:sans-serif;max-width:600px;margin:auto;padding:24px">
<h2 style="color:#1a1a1a">Reservering geannuleerd</h2>
<p>Beste {customer.name},</p>
<p>Uw reservering bij <strong>{restaurant.name}</strong> op {dt_str}
   voor {reservation.party_size} personen is geannuleerd.</p>
<p>Wilt u een nieuwe reservering maken?
Neem contact op via {restaurant.phone or "het restaurant"}.</p>
<p>Met vriendelijke groet,<br>{restaurant.name}</p>
</body></html>"""
        await self._send(customer.email or "", subject, html)

    async def send_reservation_reminder(
        self,
        reservation: "Reservation",
        customer: "Customer",
        restaurant: "Restaurant",
    ) -> None:
        dt_str = _format_dt_nl(reservation.reserved_at)
        settings_data = restaurant.settings or {}
        address = settings_data.get("address", "")
        subject = f"Herinnering: uw reservering morgen — {restaurant.name}"
        address_block = f"<p>Adres: {address}</p>" if address else ""
        html = f"""<!DOCTYPE html>
<html><body style="font-family:sans-serif;max-width:600px;margin:auto;padding:24px">
<h2 style="color:#1a1a1a">Herinnering: reservering morgen</h2>
<p>Beste {customer.name},</p>
<p>Dit is een herinnering voor uw reservering bij <strong>{restaurant.name}</strong>.</p>
<table style="border-collapse:collapse;width:100%;margin:16px 0">
  <tr><td style="padding:8px;border-bottom:1px solid #eee;color:#666">Datum &amp; tijd</td>
      <td style="padding:8px;border-bottom:1px solid #eee"><strong>{dt_str}</strong></td></tr>
  <tr><td style="padding:8px;border-bottom:1px solid #eee;color:#666">Aantal personen</td>
      <td style="padding:8px;border-bottom:1px solid #eee">
          <strong>{reservation.party_size} personen</strong></td></tr>
</table>
{address_block}
<p>Tot morgen bij {restaurant.name}!</p>
</body></html>"""
        await self._send(customer.email or "", subject, html)

    async def send_reservation_approved(
        self,
        reservation: "Reservation",
        customer: "Customer",
        restaurant: "Restaurant",
        comment: str | None = None,
    ) -> None:
        dt_str = _format_dt_nl(reservation.reserved_at)
        subject = f"Reservering bevestigd — {restaurant.name}"
        comment_block = (
            f'<p style="background:#f4f4f4;padding:12px;border-radius:6px">'
            f"<strong>Bericht van het restaurant:</strong><br>{comment}</p>"
            if comment
            else ""
        )
        html = f"""<!DOCTYPE html>
<html><body style="font-family:sans-serif;max-width:600px;margin:auto;padding:24px">
<h2 style="color:#1a1a1a">Reservering bevestigd</h2>
<p>Beste {customer.name},</p>
<p>Uw reservering bij <strong>{restaurant.name}</strong> is bevestigd.</p>
<table style="border-collapse:collapse;width:100%;margin:16px 0">
  <tr><td style="padding:8px;border-bottom:1px solid #eee;color:#666">Datum &amp; tijd</td>
      <td style="padding:8px;border-bottom:1px solid #eee"><strong>{dt_str}</strong></td></tr>
  <tr><td style="padding:8px;border-bottom:1px solid #eee;color:#666">Aantal personen</td>
      <td style="padding:8px;border-bottom:1px solid #eee">
          <strong>{reservation.party_size} personen</strong></td></tr>
</table>
{comment_block}
<p>Wilt u annuleren of wijzigen? Neem contact op via {restaurant.phone or "het restaurant"}.</p>
<p>Tot ziens bij {restaurant.name}!</p>
</body></html>"""
        await self._send(customer.email or "", subject, html)

    async def send_reservation_rejected(
        self,
        reservation: "Reservation",
        customer: "Customer",
        restaurant: "Restaurant",
        comment: str | None = None,
    ) -> None:
        dt_str = _format_dt_nl(reservation.reserved_at)
        subject = f"Reservering geweigerd — {restaurant.name}"
        comment_block = (
            f'<p style="background:#f4f4f4;padding:12px;border-radius:6px">'
            f"<strong>Bericht van het restaurant:</strong><br>{comment}</p>"
            if comment
            else ""
        )
        html = f"""<!DOCTYPE html>
<html><body style="font-family:sans-serif;max-width:600px;margin:auto;padding:24px">
<h2 style="color:#1a1a1a">Reservering geweigerd</h2>
<p>Beste {customer.name},</p>
<p>Helaas kunnen wij uw reservering bij <strong>{restaurant.name}</strong> op {dt_str}
   voor {reservation.party_size} personen niet bevestigen.</p>
{comment_block}
<p>Wilt u een andere datum proberen? Neem contact op via {restaurant.phone or "het restaurant"}.</p>
<p>Met vriendelijke groet,<br>{restaurant.name}</p>
</body></html>"""
        await self._send(customer.email or "", subject, html)

    async def send_reservation_pending_review(
        self,
        reservation: "Reservation",
        customer: "Customer",
        restaurant: "Restaurant",
    ) -> None:
        dt_str = _format_dt_nl(reservation.reserved_at)
        subject = f"Reservering ontvangen — {restaurant.name}"
        html = f"""<!DOCTYPE html>
<html><body style="font-family:sans-serif;max-width:600px;margin:auto;padding:24px">
<h2 style="color:#1a1a1a">Reservering ontvangen</h2>
<p>Beste {customer.name},</p>
<p>Wij hebben uw reserveringsaanvraag bij <strong>{restaurant.name}</strong> ontvangen.</p>
<table style="border-collapse:collapse;width:100%;margin:16px 0">
  <tr><td style="padding:8px;border-bottom:1px solid #eee;color:#666">Datum &amp; tijd</td>
      <td style="padding:8px;border-bottom:1px solid #eee"><strong>{dt_str}</strong></td></tr>
  <tr><td style="padding:8px;border-bottom:1px solid #eee;color:#666">Aantal personen</td>
      <td style="padding:8px;border-bottom:1px solid #eee">
          <strong>{reservation.party_size} personen</strong></td></tr>
</table>
<p>Uw reservering is nog niet definitief. Het restaurant zal uw aanvraag beoordelen
   en u ontvangt een bevestiging of afwijzing per e-mail.</p>
<p>Vragen? Neem contact op via {restaurant.phone or "het restaurant"}.</p>
</body></html>"""
        await self._send(customer.email or "", subject, html)

    async def send_verification_code(
        self,
        *,
        to_email: str,
        code: str,
        restaurant_name: str,
    ) -> None:
        """Send a 6-digit verification code for chat identity verification."""
        subject = f"Your verification code for {restaurant_name}"
        html = f"""<!DOCTYPE html>
<html><body style="font-family:sans-serif;max-width:600px;margin:auto;padding:24px">
<h2 style="color:#1a1a1a">Verification Code</h2>
<p>Your verification code for <strong>{restaurant_name}</strong> is:</p>
<p style="font-size:32px;font-weight:bold;letter-spacing:8px;text-align:center;
   padding:16px;background:#f4f4f4;border-radius:8px;margin:24px 0">{code}</p>
<p>This code expires in <strong>10 minutes</strong>.</p>
<p style="color:#666;font-size:14px">If you did not request this code,
you can safely ignore this email.</p>
</body></html>"""
        await self._send(to_email, subject, html)
