import logging

from fastapi import APIRouter, Depends
from sqlalchemy import func, select
from sqlalchemy.orm import Session

from app.core.rbac import get_user_permission_names, require_permission
from app.db.database import get_db
from app.models.rbac import Role
from app.models.audit import AuditLog
from app.models.user import User
from app.repositories.customer_repository import CustomerRepository
from app.repositories.repair_repository import RepairRepository
from app.repositories.user_repository import UserRepository
from app.schemas.dashboard import DashboardSummary, EmptyWidget, MetricCard, SystemStatusItem
from app.services.system_settings_service import SystemSettingsService

logger = logging.getLogger(__name__)

router = APIRouter(
    prefix="/dashboard",
    tags=["Dashboard"],
)


@router.get("/summary", response_model=DashboardSummary)
def get_dashboard_summary(
    db: Session = Depends(get_db),
    current_user: User = Depends(require_permission("dashboard.read")),
):
    permissions = get_user_permission_names(current_user)
    customers: list[MetricCard] = []
    latest_customers = []
    users: list[MetricCard] = []
    roles: list[MetricCard] = []
    repairs: list[MetricCard] = []
    system_status: list[SystemStatusItem] = []

    if "customers.read" in permissions:
        customers = [
            MetricCard(label="Kunden", value=CustomerRepository.count_all(db)),
            MetricCard(label="Aktive Kunden", value=CustomerRepository.count_active(db)),
            MetricCard(label="Neue Kunden", value=CustomerRepository.count_recent(db)),
        ]
        latest_customers = CustomerRepository.get_latest(db)

    if "users.read" in permissions:
        all_users = UserRepository.get_all(db)
        users = [
            MetricCard(label="Benutzer", value=len(all_users)),
            MetricCard(label="Aktive Benutzer", value=len([user for user in all_users if user.is_active])),
        ]

    if "roles.read" in permissions:
        roles = [
            MetricCard(
                label="Rollen",
                value=db.scalar(select(func.count(Role.id))) or 0,
            )
        ]

    if "repairs.read" in permissions:
        repairs = [
            MetricCard(label="Neue Reparaturen", value=RepairRepository.count_by_status(db, "new")),
            MetricCard(label="In Diagnose", value=RepairRepository.count_by_status(db, "diagnosis")),
            MetricCard(label="Wartet auf Kunde", value=RepairRepository.count_by_status(db, "waiting_for_customer")),
            MetricCard(label="In Reparatur", value=RepairRepository.count_by_status(db, "repair")),
            MetricCard(label="Endprüfung", value=RepairRepository.count_by_status(db, "final_test")),
            MetricCard(label="Abgeschlossen", value=RepairRepository.count_by_status(db, "completed")),
            MetricCard(label="Statusmails heute", value=RepairRepository.count_status_mails_sent_today(db)),
            MetricCard(label="Fehlgeschlagene Mails", value=RepairRepository.count_failed_status_mails(db)),
            MetricCard(label="Offen ohne Kundenmail", value=RepairRepository.count_open_repairs_without_customer_email(db)),
        ]

    if "system_settings.manage" in permissions:
        smtp_config = SystemSettingsService.get_smtp_runtime_config(db)
        public_links = SystemSettingsService.get_public_links_settings(db)
        latest_testmail = db.scalar(
            select(AuditLog)
            .where(AuditLog.action.in_(["system_settings.smtp.test_sent", "system_settings.smtp.test_failed"]))
            .order_by(AuditLog.created_at.desc(), AuditLog.id.desc())
            .limit(1)
        )
        latest_failed_status_mail = RepairRepository.latest_failed_status_mail(db)
        system_status = [
            SystemStatusItem(
                label="SMTP-Konfiguration",
                value={
                    "database": "Admin-Konfiguration",
                    "environment": "Umgebung",
                    "missing": "Nicht konfiguriert",
                }[smtp_config.source],
                status="ok" if smtp_config.is_configured else "warning",
            ),
            SystemStatusItem(
                label="Public Status Base URL",
                value=public_links.repair_status_base_url or "Nicht konfiguriert",
                status="ok" if public_links.repair_status_base_url else "warning",
            ),
            SystemStatusItem(
                label="Letzte SMTP-Testmail",
                value=latest_testmail.created_at.isoformat() if latest_testmail else "Noch keine Testmail",
                status="info" if latest_testmail else "warning",
            ),
            SystemStatusItem(
                label="Letzte fehlgeschlagene Statusmail",
                value=latest_failed_status_mail.created_at.isoformat() if latest_failed_status_mail else "Keine Fehler",
                status="warning" if latest_failed_status_mail else "ok",
            ),
        ]

    logger.info("dashboard.summary", extra={"actor_user_id": current_user.id})

    return DashboardSummary(
        customers=customers,
        latest_customers=latest_customers,
        users=users,
        roles=roles,
        repairs=repairs,
        system_status=system_status,
        activities=EmptyWidget(
            title="Letzte Aktivitäten",
            message="Noch keine Aktivitäten vorhanden.",
        ),
        tasks=EmptyWidget(
            title="Offene Aufgaben",
            message="Noch keine Aufgaben vorhanden.",
        ),
        tickets=EmptyWidget(
            title="Offene Tickets",
            message="Noch keine Tickets vorhanden.",
        ),
        projects=EmptyWidget(
            title="Projekte",
            message="Noch keine Projektdaten vorhanden.",
        ),
    )
