from dataclasses import dataclass

from sqlalchemy.orm import Session

from app.models.repair import Repair
from app.repositories.repair_repository import RepairRepository
from app.schemas.repair import RepairNotificationOverviewResponse, RepairNotificationTemplateResponse, RepairStatus


STATUS_LABELS: dict[str, str] = {
    "new": "Neu",
    "accepted": "Angenommen",
    "diagnosis": "Diagnose",
    "estimate": "Kostenvoranschlag",
    "waiting_for_customer": "Wartet auf Kunde",
    "approved": "Freigegeben",
    "repair": "Reparatur",
    "final_test": "Endprüfung",
    "ready_for_pickup": "Abholbereit",
    "shipped": "Versand",
    "completed": "Abgeschlossen",
    "cancelled": "Storniert",
}


@dataclass(frozen=True)
class RepairNotificationTemplate:
    event_type: str
    status: RepairStatus | None
    subject: str
    text: str
    html: str | None = None


TEMPLATES: tuple[RepairNotificationTemplate, ...] = (
    RepairNotificationTemplate(
        event_type="repair_created",
        status="new",
        subject="Reparatur {repair_number} wurde erfasst",
        text="Guten Tag {customer_name},\n\nIhre Reparatur {repair_number} für {device} wurde erfasst. Den aktuellen Status finden Sie später unter {public_status_url}.\n\n{company_name}",
    ),
    RepairNotificationTemplate(
        event_type="device_accepted",
        status="accepted",
        subject="Gerät zu Reparatur {repair_number} angenommen",
        text="Guten Tag {customer_name},\n\nIhr Gerät {device} wurde angenommen. Aktueller Status: {status_label}.\n\n{company_name}",
    ),
    RepairNotificationTemplate(
        event_type="diagnosis_started",
        status="diagnosis",
        subject="Diagnose für Reparatur {repair_number} läuft",
        text="Guten Tag {customer_name},\n\nwir prüfen Ihr Gerät {device}. Aktueller Status: {status_label}.\n\n{company_name}",
    ),
    RepairNotificationTemplate(
        event_type="estimate_created",
        status="estimate",
        subject="Kostenvoranschlag zu Reparatur {repair_number}",
        text="Guten Tag {customer_name},\n\nfür Ihr Gerät {device} wurde ein Kostenvoranschlag vorbereitet. Aktueller Status: {status_label}.\n\n{company_name}",
    ),
    RepairNotificationTemplate(
        event_type="waiting_for_customer",
        status="waiting_for_customer",
        subject="Freigabe für Reparatur {repair_number} erforderlich",
        text="Guten Tag {customer_name},\n\nfür Ihre Reparatur {repair_number} warten wir auf Ihre Rückmeldung. Aktueller Status: {status_label}.\n\n{company_name}",
    ),
    RepairNotificationTemplate(
        event_type="repair_started",
        status="repair",
        subject="Reparatur {repair_number} läuft",
        text="Guten Tag {customer_name},\n\nwir bearbeiten Ihr Gerät {device}. Aktueller Status: {status_label}.\n\n{company_name}",
    ),
    RepairNotificationTemplate(
        event_type="final_test",
        status="final_test",
        subject="Endprüfung für Reparatur {repair_number}",
        text="Guten Tag {customer_name},\n\nIhr Gerät {device} befindet sich in der Endprüfung. Aktueller Status: {status_label}.\n\n{company_name}",
    ),
    RepairNotificationTemplate(
        event_type="ready_for_pickup",
        status="ready_for_pickup",
        subject="Reparatur {repair_number} ist abholbereit",
        text="Guten Tag {customer_name},\n\nIhr Gerät {device} ist abholbereit. Aktueller Status: {status_label}.\n\n{company_name}",
    ),
    RepairNotificationTemplate(
        event_type="shipped",
        status="shipped",
        subject="Reparatur {repair_number} wurde versendet",
        text="Guten Tag {customer_name},\n\nIhr Gerät {device} wurde versendet. Aktueller Status: {status_label}.\n\n{company_name}",
    ),
    RepairNotificationTemplate(
        event_type="completed",
        status="completed",
        subject="Reparatur {repair_number} abgeschlossen",
        text="Guten Tag {customer_name},\n\nIhre Reparatur {repair_number} wurde abgeschlossen. Vielen Dank.\n\n{company_name}",
    ),
)


class RepairNotificationService:
    @staticmethod
    def render_templates(repair: Repair, *, public_status_url: str = "") -> list[RepairNotificationTemplateResponse]:
        placeholders = {
            "repair_number": repair.repair_number,
            "customer_name": repair.customer_name,
            "device": f"{repair.device_manufacturer} {repair.device_model}".strip(),
            "status_label": STATUS_LABELS.get(repair.status, repair.status),
            "public_status_url": public_status_url or "wird später bereitgestellt",
            "company_name": "Olympus CRM",
        }
        return [
            RepairNotificationTemplateResponse(
                event_type=template.event_type,
                status=template.status,
                subject=template.subject.format(**placeholders),
                text=template.text.format(**placeholders),
                html=template.html.format(**placeholders) if template.html else None,
            )
            for template in TEMPLATES
        ]

    @staticmethod
    def overview(db: Session, repair: Repair, *, public_status_url: str = "") -> RepairNotificationOverviewResponse:
        return RepairNotificationOverviewResponse(
            templates=RepairNotificationService.render_templates(repair, public_status_url=public_status_url),
            events=RepairRepository.list_notification_events(db, repair.id),
        )
