from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse
from pydantic import BaseModel, validator
from typing import Optional, List
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from sqlalchemy import text
import os
from datetime import date
import uuid
from dotenv import load_dotenv

load_dotenv()

raw_url = os.getenv("DATABASE_URL")
if not raw_url:
    raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
fixed_url = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")

engine = create_async_engine(fixed_url)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

app = FastAPI(title="Service Finder API")

# --- MODELLEK ---
class IssueReport(BaseModel):
    vehicle_id: int
    description: str
    is_critical: bool

class IssueResolve(BaseModel):
    vehicle_id: int

# ÚJ: KÖLTSÉG MODELL
class CostCreate(BaseModel):
    vehicle_id: int
    cost_type: str  # FUEL, SERVICE, INSURANCE, TAX, OTHER
    amount: float
    currency: str   # HUF, EUR
    date: date
    mileage: int
    description: Optional[str] = ""

# --- LOGOLÁS ---
async def create_audit_log(session, user_id, event, target_id, details, old_val=None, new_val=None):
    await session.execute(text("""
        INSERT INTO data.audit_logs (user_id, event_type, target_id, details, old_value, new_value)
        VALUES (:uid, :evt, :tid, :det, :old, :new)
    """), {"uid": user_id, "evt": event, "tid": target_id, "det": details, "old": old_val, "new": new_val})

# --- VÉGPONTOK ---

# 1. KÖLTSÉG HOZZÁADÁSA (Okos Km frissítéssel!)
@app.post("/api/add_cost")
async def add_cost(data: CostCreate):
    user_id = 1
    async with AsyncSessionLocal() as session:
        async with session.begin():
            # Költség mentése
            await session.execute(text("""
                INSERT INTO data.costs (vehicle_id, user_id, cost_type, amount, currency, date, mileage_at_cost, description)
                VALUES (:vid, :uid, :type, :amt, :curr, :date, :mil, :desc)
            """), {
                "vid": data.vehicle_id, "uid": user_id, "type": data.cost_type,
                "amt": data.amount, "curr": data.currency, "date": data.date,
                "mil": data.mileage, "desc": data.description
            })
            
            # KM ÓRA AUTOMATIKUS FRISSÍTÉSE (Ha a megadott km nagyobb, mint a jelenlegi)
            # Először lekérjük a jelenlegit
            res = await session.execute(text("SELECT start_mileage FROM data.vehicle_history WHERE vehicle_id = :vid AND end_date IS NULL"), {"vid": data.vehicle_id})
            current = res.scalar() or 0
            
            if data.mileage > current:
                 await session.execute(text("""
                    UPDATE data.vehicle_history SET start_mileage = :mil 
                    WHERE vehicle_id = :vid AND end_date IS NULL
                 """), {"mil": data.mileage, "vid": data.vehicle_id})
                 
                 # Opcionális: Logoljuk a km frissítést is
                 await create_audit_log(session, user_id, "MILEAGE_UPDATE", data.vehicle_id, f"Km frissítve költség rögzítésekor: {data.mileage}")

            await create_audit_log(session, user_id, "ADD_COST", data.vehicle_id, f"{data.cost_type}: {data.amount} {data.currency}")
            return {"status": "success"}

# 2. SZERVIZKÖNYV LEKÉRÉSE (Történet)
@app.get("/api/vehicle/{vehicle_id}/history")
async def get_vehicle_history(vehicle_id: int):
    user_id = 1
    async with AsyncSessionLocal() as session:
        # Lekérjük a költségeket
        res_costs = await session.execute(text("""
            SELECT id, cost_type as type, amount, currency, date, mileage_at_cost as mileage, description, 'COST' as source
            FROM data.costs WHERE vehicle_id = :vid ORDER BY date DESC
        """), {"vid": vehicle_id})
        costs = res_costs.fetchall()
        
        # Lekérjük az Audit Log eseményeket (Hiba, Javítás)
        res_logs = await session.execute(text("""
            SELECT id, event_type as type, 0 as amount, '' as currency, created_at::date as date, 0 as mileage, details as description, 'LOG' as source
            FROM data.audit_logs WHERE target_id = :vid AND event_type IN ('ISSUE_REPORT', 'ISSUE_RESOLVED') ORDER BY created_at DESC
        """), {"vid": vehicle_id})
        logs = res_logs.fetchall()
        
        # Összefésüljük a két listát Pythonban és dátum szerint rendezzük
        combined = []
        for r in costs: combined.append(dict(r._mapping))
        for r in logs: combined.append(dict(r._mapping))
        
        # Rendezés dátum szerint csökkenőbe (legújabb elöl)
        combined.sort(key=lambda x: x['date'], reverse=True)
        
        return combined

# --- KORÁBBI VÉGPONTOK (Rövidítve a hely miatt, de ezek kellenek!) ---
@app.get("/api/my_vehicles")
async def get_my_garage():
    user_id = 1
    async with AsyncSessionLocal() as session:
        query = text("""
            SELECT v.id as vehicle_id, v.vin, v.current_plate, m.name as brand, 
                   mo.model_name, mo.category, vh.start_mileage, vh.role,
                   v.status, v.current_issue
            FROM data.vehicle_history vh
            JOIN data.vehicles v ON vh.vehicle_id = v.id
            JOIN ref.vehicle_models mo ON v.model_id = mo.id
            JOIN ref.vehicle_makes m ON mo.make_id = m.id
            WHERE vh.user_id = :uid AND vh.end_date IS NULL
            ORDER BY vh.start_date DESC
        """)
        result = await session.execute(query, {"uid": user_id})
        return [{"vehicle_id": r.vehicle_id, "brand": r.brand, "model": r.model_name, "plate": r.current_plate, "category": r.category, "role": r.role, "status": r.status, "current_issue": r.current_issue} for r in result.fetchall()]

@app.get("/api/vehicle/{vehicle_id}")
async def get_vehicle_details(vehicle_id: int):
    user_id = 1
    async with AsyncSessionLocal() as session:
        q = text("""
            SELECT v.id, v.vin, v.current_plate, v.production_year, 
                   m.name as brand, mo.model_name, mo.category,
                   vh.role, vh.start_date, vh.start_mileage, u.default_currency,
                   v.status, v.current_issue
            FROM data.vehicle_history vh
            JOIN data.vehicles v ON vh.vehicle_id = v.id
            JOIN ref.vehicle_models mo ON v.model_id = mo.id
            JOIN ref.vehicle_makes m ON mo.make_id = m.id
            JOIN data.users u ON vh.user_id = u.id
            WHERE v.id = :vid AND vh.user_id = :uid AND vh.end_date IS NULL
        """)
        res = await session.execute(q, {"vid": vehicle_id, "uid": user_id})
        car = res.fetchone()
        if not car: raise HTTPException(status_code=404, detail="Nincs adat")
        return {"id": car.id, "brand": car.brand, "model": car.model_name, "plate": car.current_plate, "vin": car.vin, "role": car.role, "start_date": car.start_date, "mileage": car.start_mileage, "currency": car.default_currency, "status": car.status, "current_issue": car.current_issue}

@app.post("/api/report_issue")
async def report_issue(data: IssueReport):
    user_id = 1 
    async with AsyncSessionLocal() as session:
        async with session.begin():
            new_status = 'CRITICAL' if data.is_critical else 'WARNING'
            await session.execute(text("UPDATE data.vehicles SET status = :st, current_issue = :desc WHERE id = :vid"), {"st": new_status, "desc": data.description, "vid": data.vehicle_id})
            await create_audit_log(session, user_id, "ISSUE_REPORT", data.vehicle_id, details=data.description, old_val="OK", new_val=new_status)
            return {"status": "success"}

@app.post("/api/resolve_issue")
async def resolve_issue(data: IssueResolve):
    user_id = 1
    async with AsyncSessionLocal() as session:
        async with session.begin():
            await session.execute(text("UPDATE data.vehicles SET status = 'OK', current_issue = NULL WHERE id = :vid"), {"vid": data.vehicle_id})
            await create_audit_log(session, user_id, "ISSUE_RESOLVED", data.vehicle_id, details="Probléma megoldva", old_val="WARNING", new_val="OK")
            return {"status": "success", "message": "Jármű státusza helyreállítva!"}

@app.get("/")
async def serve_frontend():
    if os.path.exists("/app/frontend/index.html"): return FileResponse("/app/frontend/index.html")
    return {"error": "Frontend hiányzik"}