from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from app.models.vehicle import UserVehicle
from app.models.expense import VehicleEvent
from app.models.social import ServiceProvider, SourceType, ModerationStatus
from app.schemas.fleet import EventCreate, TCOStats
from app.services.gamification_service import GamificationService

async def add_vehicle_event(db: AsyncSession, vehicle_id: int, event_data: EventCreate, user_id: int):
    v_res = await db.execute(select(UserVehicle).where(UserVehicle.id == vehicle_id))
    vehicle = v_res.scalars().first()
    if not vehicle: return {"error": "Vehicle not found"}

    final_provider_id = event_data.provider_id
    if event_data.is_diy: final_provider_id = None
    elif event_data.provider_name and not final_provider_id:
        p_res = await db.execute(select(ServiceProvider).where(func.lower(ServiceProvider.name) == event_data.provider_name.lower()))
        existing = p_res.scalars().first()
        if existing: final_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(); final_provider_id = new_p.id
            await GamificationService.award_points(db, user_id, 50, f"Új helyszín: {event_data.provider_name}")

    anomaly = event_data.odometer_value < vehicle.current_odometer
    new_event = VehicleEvent(vehicle_id=vehicle_id, service_provider_id=final_provider_id, odometer_anomaly=anomaly, **event_data.model_dump(exclude={"provider_id", "provider_name"}))
    db.add(new_event)
    if event_data.odometer_value > vehicle.current_odometer: vehicle.current_odometer = event_data.odometer_value
    await GamificationService.award_points(db, user_id, 20, f"Esemény: {event_data.event_type}")
    await db.commit(); await db.refresh(new_event)
    return new_event

async def calculate_tco(db: AsyncSession, vehicle_id: int) -> TCOStats:
    result = await db.execute(select(VehicleEvent.event_type, func.sum(VehicleEvent.cost_amount)).where(VehicleEvent.vehicle_id == vehicle_id).group_by(VehicleEvent.event_type))
    breakdown = {row[0]: row[1] for row in result.all()}
    v_res = await db.execute(select(UserVehicle).where(UserVehicle.id == vehicle_id))
    v = v_res.scalars().first()
    km = (v.current_odometer - v.initial_odometer) if v else 0
    cpk = sum(breakdown.values()) / km if km > 0 else 0
    return TCOStats(vehicle_id=vehicle_id, total_cost=sum(breakdown.values()), breakdown=breakdown, cost_per_km=round(cpk, 2))