# /opt/docker/dev/service_finder/backend/app/services/fleet_service.py
import logging
from uuid import UUID
from typing import Optional, Dict, Any
from decimal import Decimal

from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from sqlalchemy.orm import selectinload

from app.models import Asset, AssetEvent, AssetCost, AssetTelemetry
from app.models import ServiceProvider, ModerationStatus
from app.schemas.fleet import EventCreate, TCOStats
from app.services.gamification_service import gamification_service
from app.services.config_service import config # 2.0 Dinamikus konfig

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

class FleetService:
    """
    Sentinel Master Fleet Service 2.2.
    Kezeli a járműflotta eseményeit és a TCO elemzéseket admin-vezérelt szabályokkal.
    """

    @staticmethod
    async def add_vehicle_event(db: AsyncSession, asset_id: UUID, event_data: EventCreate, user_id: int):
        """ 
        Esemény rögzítése dinamikus jutalmazással és anomália figyeléssel.
        """
        try:
            # 1. Asset és Telemetria betöltése
            stmt = select(Asset).where(Asset.id == asset_id).options(selectinload(Asset.telemetry))
            res = await db.execute(stmt)
            asset = res.scalar_one_or_none()
            if not asset: return None

            # 2. ADMIN KONFIGURÁCIÓ LEKÉRÉSE (Hierarchikus: User > Region > Global)
            # Lekérjük az eseménytípushoz tartozó jutalmakat
            event_rewards = await config.get_setting(
                db, 
                "FLEET_EVENT_REWARDS", 
                scope_level="user", 
                scope_id=str(user_id),
                default={
                    "refuel": {"xp": 30, "social": 5},
                    "service": {"xp": 100, "social": 20},
                    "inspection": {"xp": 50, "social": 10},
                    "default": {"xp": 20, "social": 2}
                }
            )

            # 3. SZOLGÁLTATÓ KEZELÉSE
            provider_id = event_data.provider_id
            if not event_data.is_diy and event_data.provider_name and not provider_id:
                p_stmt = select(ServiceProvider).where(func.lower(ServiceProvider.name) == event_data.provider_name.lower())
                existing = (await db.execute(p_stmt)).scalar_one_or_none()
                if existing:
                    provider_id = existing.id
                else:
                    new_p = ServiceProvider(
                        name=event_data.provider_name, 
                        added_by_user_id=user_id, 
                        status=ModerationStatus.pending
                    )
                    db.add(new_p)
                    await db.flush()
                    provider_id = new_p.id

            # 4. ANOMÁLIA DETEKCIÓ (Admin-vezérelt küszöbökkel)
            current_mileage = asset.telemetry.current_mileage if asset.telemetry else 0
            is_odometer_anomaly = event_data.odometer_value < current_mileage
            
            # 5. ESEMÉNY RÖGZÍTÉSE
            new_event = AssetEvent(
                asset_id=asset_id, 
                event_type=event_data.event_type,
                recorded_mileage=event_data.odometer_value,
                provider_id=provider_id,
                is_anomaly=is_odometer_anomaly,
                data=event_data.model_dump(exclude={"provider_id", "provider_name"})
            )
            db.add(new_event)

            # 6. DINAMIKUS GAMIFIKÁCIÓ
            # Kikeresjük a konkrét eseménytípushoz tartozó pontokat
            rewards = event_rewards.get(event_data.event_type, event_rewards["default"])
            
            await gamification_service.process_activity(
                db, 
                user_id, 
                xp_amount=rewards["xp"], 
                social_amount=rewards["social"], 
                reason=f"FLEET_EVENT_{event_data.event_type.upper()}"
            )

            await db.commit()
            return new_event

        except Exception as e:
            await db.rollback()
            logger.error(f"Fleet Event Error: {e}")
            raise e

    @staticmethod
    async def calculate_tco(db: AsyncSession, asset_id: UUID) -> TCOStats:
        """ 
        TCO számítás dinamikus pénznemkezeléssel és KM-alapú költséganalízissel.
        """
        # 1. Admin beállítások (Pl. alapértelmezett pénznem a riportokhoz)
        report_currency = await config.get_setting(db, "finance_base_currency", default="EUR")

        # 2. Költségek összesítése kategóriánként
        result = await db.execute(
            select(AssetCost.cost_type, func.sum(AssetCost.amount_eur))
            .where(AssetCost.asset_id == asset_id)
            .group_by(AssetCost.cost_type)
        )
        
        breakdown = {row[0]: float(row[1]) for row in result.all()}
        total_eur = sum(breakdown.values())

        # 3. KM alapú költség (Telemetria bevonása)
        telemetry_stmt = select(AssetTelemetry).where(AssetTelemetry.asset_id == asset_id)
        telemetry = (await db.execute(telemetry_stmt)).scalar_one_or_none()
        
        mileage = telemetry.current_mileage if telemetry and telemetry.current_mileage > 0 else 1
        cost_per_km = total_eur / mileage

        return TCOStats(
            asset_id=asset_id, 
            total_cost_eur=total_eur, 
            breakdown=breakdown,
            cost_per_km=round(cost_per_km, 4),
            currency=report_currency
        )