# /opt/docker/dev/service_finder/backend/app/services/asset_service.py
from __future__ import annotations
import logging
import uuid
from typing import List, Optional, Dict, Any, TYPE_CHECKING
from datetime import datetime
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, and_
from sqlalchemy.orm import selectinload

from app.models.asset import Asset, AssetAssignment, AssetTelemetry, AssetFinancials
from app.models.identity import User
from app.services.config_service import config
from app.services.gamification_service import GamificationService
from app.services.security_service import security_service

if TYPE_CHECKING:
    from .identity import User, Person
    from .organization import Organization
    from .vehicle_definitions import VehicleModelDefinition

logger = logging.getLogger(__name__)

class AssetService:
    """
    Asset Service 2.0 - A Járművek Életciklus-menedzsere.
    Kezeli a regisztrációt, a tulajdonosváltást és a flotta-korlátokat.
    """

    @staticmethod
    async def create_or_claim_vehicle(
        db: AsyncSession, 
        user_id: int, 
        org_id: int, 
        vin: str, 
        license_plate: str, 
        catalog_id: int = None
    ):
        """
        Intelligens Jármű Rögzítés: 
        Ha új: létrehozza. 
        Ha már létezik: Transzfer folyamatot indít.
        """
        try:
            vin_clean = vin.strip().upper()
            
            # 1. ADMIN LIMIT ELLENŐRZÉS
            user_stmt = select(User).where(User.id == user_id)
            user = (await db.execute(user_stmt)).scalar_one()
            
            limits = await config.get_setting(db, "VEHICLE_LIMIT", default={"free": 1, "premium": 5, "vip": 50})
            user_role = user.role.value if hasattr(user.role, 'value') else str(user.role)
            allowed_limit = limits.get(user_role, 1)

            count_stmt = select(func.count(Asset.id)).where(Asset.current_organization_id == org_id)
            current_count = (await db.execute(count_stmt)).scalar()

            if current_count >= allowed_limit:
                raise ValueError(f"Limit túllépés! A csomagod {allowed_limit} autót engedélyez.")

            # 2. LÉTEZIK-E MÁR A JÁRMŰ?
            stmt = select(Asset).where(Asset.vin == vin_clean)
            existing_asset = (await db.execute(stmt)).scalar_one_or_none()

            if existing_asset:
                # HA MÁR A JELENLEGI SZERVEZETNÉL VAN
                if existing_asset.current_organization_id == org_id:
                    raise ValueError("Ez a jármű már a te garázsodban van.")
                
                # TRANSZFER FOLYAMAT INDÍTÁSA
                return await AssetService.initiate_ownership_transfer(
                    db, existing_asset, user_id, org_id, license_plate
                )

            # 3. ÚJ JÁRMŰ LÉTREHOZÁSA (Standard Flow)
            new_asset = Asset(
                vin=vin_clean,
                license_plate=license_plate.strip().upper(),
                catalog_id=catalog_id,
                current_organization_id=org_id,
                status="active",
                is_verified=False
            )
            db.add(new_asset)
            await db.flush()

            # Digitális Iker Alapmodulok
            db.add(AssetAssignment(asset_id=new_asset.id, organization_id=org_id, status="active"))
            db.add(AssetTelemetry(asset_id=new_asset.id))
            db.add(AssetFinancials(asset_id=new_asset.id))

            # Gamification
            reward = await config.get_setting(db, "xp_reward_asset_register", default=250)
            await GamificationService.award_points(db, user_id, int(reward), "NEW_ASSET_REG")

            await db.commit()
            return new_asset

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

    @staticmethod
    async def initiate_ownership_transfer(db: AsyncSession, asset: Asset, user_id: int, org_id: int, new_plate: str):
        """
        Adásvétel kezelése: Az autót 'Transfer Pending' állapotba teszi.
        """
        # Admin paraméter: Automatikus transzfer engedélyezése?
        auto_transfer = await config.get_setting(db, "asset_auto_transfer_enabled", default=False)
        
        # Logoljuk a kísérletet a biztonsági szolgálatnál (Sentinel)
        await security_service.log_event(
            db, user_id=user_id, action="VEHICLE_CLAIM_INITIATED",
            severity="warning", target_type="Asset", target_id=str(asset.id),
            new_data={"vin": asset.vin, "new_org": org_id}
        )

        if auto_transfer:
            # Csak akkor, ha a régi tulajdonos 'sold' állapotba tette
            if asset.status == "sold":
                return await AssetService.execute_final_transfer(db, asset, org_id, new_plate)
        
        # Függőben lévő állapot: Dokumentum feltöltésre vár
        asset.status = "transfer_pending"
        asset.temp_claim_org_id = org_id # Átmeneti tároló a validálásig
        
        await db.commit()
        # Itt egy speciális hibaüzenetet dobunk, amit a Frontend tud kezelni (Dokumentum feltöltő ablak)
        raise HTTPException(
            status_code=202, 
            detail="A jármű már szerepel a rendszerben. Kérjük, töltsd fel az adásvételi szerződést a tulajdonjog igazolásához."
        )

    @staticmethod
    async def execute_final_transfer(db: AsyncSession, asset: Asset, new_org_id: int, new_plate: str):
        """ A tulajdonjog tényleges átírása az adatbázisban. """
        # 1. Régi hozzárendelés lezárása
        await db.execute(
            update(AssetAssignment)
            .where(and_(AssetAssignment.asset_id == asset.id, AssetAssignment.status == "active"))
            .values(status="archived", end_date=datetime.now())
        )

        # 2. Új hozzárendelés és adatok frissítése
        asset.current_organization_id = new_org_id
        asset.license_plate = new_plate.upper()
        asset.status = "active"
        asset.is_verified = False # Az új tulajdonos papírjait is ellenőrizni kell!
        
        db.add(AssetAssignment(asset_id=asset.id, organization_id=new_org_id, status="active"))
        
        await db.commit()
        return asset