# /opt/docker/dev/service_finder/backend/app/services/notification_service.py
import logging
import uuid
from datetime import datetime, timedelta, timezone
from typing import Optional, List, Dict, Any

from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from sqlalchemy.orm import joinedload

from app.models.identity import User
from app.models import Asset
from app.models.marketplace.organization import Organization
from app.models.system import InternalNotification
from app.services.email_manager import email_manager
from app.services.config_service import config 

logger = logging.getLogger("Notification-Service-2.2")

class NotificationService:
    """
    Sentinel Master Notification Service 2.2 - Fully Admin-Configurable.
    Nincs fix kód: minden típus (biztosítás, műszaki, okmány) a DB-ből vezérelt.
    """

    @staticmethod
    async def send_notification(
        db: AsyncSession, 
        user_id: int, 
        title: str, 
        message: str, 
        category: str = "info",
        priority: str = "medium",
        data: dict = None,
        send_email: bool = True,
        email_template: str = None,
        email_vars: dict = None
    ):
        """ Univerzális küldő: Belső Dashboard + Email. """
        new_notif = InternalNotification(
            user_id=user_id,
            title=title,
            message=message,
            category=category,
            priority=priority,
            data=data or {}
        )
        db.add(new_notif)

        if send_email and email_template and email_vars:
            await email_manager.send_email(
                db=db,
                recipient=email_vars.get("recipient"),
                template_key=email_template,
                variables=email_vars,
                lang=email_vars.get("lang", "hu")
            )
        await db.commit()

    @staticmethod
    async def check_expiring_documents(db: AsyncSession):
        """ 
        Dinamikus lejárat-figyelő: Típusonkénti naptárak az adminból.
        """
        try:
            today = datetime.now(timezone.utc).date()

            # 1. Lekérjük az összes aktív járművet és a tulajdonosaikat
            stmt = (
                select(Asset, User)
                .join(Organization, Asset.current_organization_id == Organization.id)
                .join(User, Organization.owner_id == User.id)
                .where(Asset.status == "active")
                .options(joinedload(Asset.catalog))
            )
            result = await db.execute(stmt)
            notifications_sent = 0

            for asset, user in result.all():
                # 2. DINAMIKUS MÁTRIX LEKÉRÉSE (Hierarchikus: User > Region > Global)
                # Az adminban így van tárolva: {"insurance": [45, 30, 7, 0], "mot": [30, 7, 0], ...}
                alert_matrix = await config.get_setting(
                    db, 
                    "NOTIFICATION_TYPE_MATRIX", 
                    scope_level="user", 
                    scope_id=str(user.id),
                    default={
                        "insurance": [45, 30, 15, 7, 1, 0],
                        "mot": [30, 7, 1, 0],
                        "personal_id": [30, 15, 0],
                        "default": [30, 7, 1]
                    }
                )

                # 3. Ellenőrizendő dátumok (factory_data a Robotoktól)
                # Kulcsok: insurance_expiry_date, mot_expiry_date, id_card_expiry stb.
                check_map = {
                    "insurance": asset.factory_data.get("insurance_expiry_date"),
                    "mot": asset.factory_data.get("mot_expiry_date"),
                    "personal_id": user.person.identity_docs.get("expiry_date") if user.person else None
                }

                for doc_type, expiry_str in check_map.items():
                    if not expiry_str: continue

                    try:
                        expiry_dt = datetime.strptime(expiry_str, "%Y-%m-%d").date()
                        days_until = (expiry_dt - today).days
                        
                        # Megnézzük a típushoz tartozó admin-beállítást (pl. a 45 napot)
                        alert_steps = alert_matrix.get(doc_type, alert_matrix["default"])

                        if days_until in alert_steps:
                            # Prioritás meghatározása (Adminból is jöhetne, de itt kategória alapú)
                            priority = "critical" if days_until <= 1 or (doc_type == "insurance" and days_until == 45) else "high"
                            
                            title = f"Riasztás: {asset.license_plate} - {doc_type.upper()}"
                            msg = f"A(z) {doc_type} dokumentum {days_until} nap múlva lejár ({expiry_str})."
                            
                            if days_until == 45 and doc_type == "insurance":
                                msg = f"🚨 BIZTOSÍTÁSI FORDULÓ! (45 nap). Most van időd felmondani a régit!"

                            await NotificationService.send_notification(
                                db=db,
                                user_id=user.id,
                                title=title,
                                message=msg,
                                category=doc_type,
                                priority=priority,
                                data={"asset_id": str(asset.id), "vin": asset.vin, "days": days_until},
                                email_template="expiry_alert",
                                email_vars={
                                    "recipient": user.email,
                                    "first_name": user.person.first_name if user.person else "Partnerünk",
                                    "license_plate": asset.license_plate,
                                    "expiry_date": expiry_str,
                                    "days_left": days_until,
                                    "lang": user.preferred_language
                                }
                            )
                            notifications_sent += 1

                    except (ValueError, TypeError):
                        continue

            return {"status": "success", "count": notifications_sent}

        except Exception as e:
            logger.error(f"Notification System Error: {e}")
            raise e