# /opt/docker/dev/service_finder/backend/app/models/vehicle/vehicle.py
"""
TCO (Total Cost of Ownership) alapmodelljei a 'vehicle' sémában.
- CostCategory: Standardizált költségkategóriák hierarchiája
- VehicleCost: Járműhöz kapcsolódó tényleges költségnapló
"""

from __future__ import annotations
from datetime import datetime
from typing import Optional
import uuid
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, Numeric, UniqueConstraint, Float, CheckConstraint
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.sql import func
from app.database import Base


class CostCategory(Base):
    """
    Standardizált költségkategóriák hierarchikus fája.
    Rendszerkategóriák (is_system=True) nem törölhetők, csak felhasználói kategóriák.
    """
    __tablename__ = "cost_categories"
    __table_args__ = {"schema": "vehicle"}

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    parent_id: Mapped[Optional[int]] = mapped_column(
        Integer, 
        ForeignKey("vehicle.cost_categories.id", ondelete="SET NULL"),
        nullable=True,
        index=True
    )
    code: Mapped[str] = mapped_column(String(50), unique=True, index=True, nullable=False)
    name: Mapped[str] = mapped_column(String(100), nullable=False)
    description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
    is_system: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false")
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now())

    # Hierarchikus kapcsolatok
    parent: Mapped[Optional["CostCategory"]] = relationship(
        "CostCategory", 
        remote_side=[id],
        back_populates="children",
        foreign_keys=[parent_id]
    )
    children: Mapped[list["CostCategory"]] = relationship(
        "CostCategory", 
        back_populates="parent",
        foreign_keys=[parent_id]
    )
    
    # Kapcsolódó költségek
    costs: Mapped[list["VehicleCost"]] = relationship("VehicleCost", back_populates="category")

    def __repr__(self) -> str:
        return f"CostCategory(id={self.id}, code='{self.code}', name='{self.name}')"


class VehicleCost(Base):
    """
    Járműhöz kapcsolódó tényleges költségnapló.
    Minden költséghez kötelező az odometer állás (km) és a dátum.
    Az organization_id az Univerzális Flotta hivatkozás (fleet.organizations).
    """
    __tablename__ = "costs"
    __table_args__ = (
        UniqueConstraint("vehicle_id", "category_id", "date", "odometer", name="uq_cost_unique_entry"),
        {"schema": "vehicle"}
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    vehicle_id: Mapped[int] = mapped_column(
        Integer, 
        ForeignKey("vehicle.vehicle_model_definitions.id", ondelete="CASCADE"),
        nullable=False,
        index=True
    )
    organization_id: Mapped[Optional[int]] = mapped_column(
        Integer,
        ForeignKey("fleet.organizations.id", ondelete="SET NULL"),
        nullable=True,
        index=True
    )
    category_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("vehicle.cost_categories.id", ondelete="RESTRICT"),
        nullable=False,
        index=True
    )
    amount: Mapped[float] = mapped_column(Numeric(12, 2), nullable=False)  # Összeg
    currency: Mapped[str] = mapped_column(String(3), default="HUF", server_default="'HUF'")  # ISO valutakód
    odometer: Mapped[int] = mapped_column(Integer, nullable=False)  # Kilométeróra állás (km)
    date: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, index=True)
    notes: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now())

    # Kapcsolatok
    vehicle: Mapped["VehicleModelDefinition"] = relationship("VehicleModelDefinition", back_populates="costs")
    organization: Mapped[Optional["Organization"]] = relationship("Organization", back_populates="vehicle_costs")
    category: Mapped["CostCategory"] = relationship("CostCategory", back_populates="costs")

    def __repr__(self) -> str:
        return f"VehicleCost(id={self.id}, vehicle_id={self.vehicle_id}, amount={self.amount} {self.currency})"


class VehicleOdometerState(Base):
    """
    Jármű kilométeróra állapotának és becslésének tárolása.
    Adminisztrátor által paraméterezhető algoritmusokkal működik.
    """
    __tablename__ = "vehicle_odometer_states"
    __table_args__ = {"schema": "vehicle"}

    vehicle_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("vehicle.vehicle_model_definitions.id", ondelete="CASCADE"),
        primary_key=True,
        nullable=False
    )
    last_recorded_odometer: Mapped[int] = mapped_column(Integer, nullable=False)
    last_recorded_date: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    daily_avg_distance: Mapped[float] = mapped_column(Numeric(10, 2), nullable=False)
    estimated_current_odometer: Mapped[float] = mapped_column(Numeric(12, 2), nullable=False)
    confidence_score: Mapped[float] = mapped_column(Float, nullable=False, default=0.0)
    manual_override_avg: Mapped[Optional[float]] = mapped_column(Numeric(10, 2), nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now())

    # Kapcsolat a jármű definícióval
    vehicle: Mapped["VehicleModelDefinition"] = relationship("VehicleModelDefinition", back_populates="odometer_state")

    def __repr__(self) -> str:
        return f"VehicleOdometerState(vehicle_id={self.vehicle_id}, estimated={self.estimated_current_odometer}, confidence={self.confidence_score})"


class VehicleUserRating(Base):
    """
    Jármű értékelési rendszer - User -> Vehicle kapcsolat.
    Egy felhasználó csak egyszer értékelhet egy adott járművet.
    Értékelés 4 dimenzióban 1-10 skálán.
    """
    __tablename__ = "vehicle_user_ratings"
    __table_args__ = (
        UniqueConstraint("vehicle_id", "user_id", name="uq_vehicle_user_rating_unique"),
        CheckConstraint("driving_experience BETWEEN 1 AND 10", name="ck_driving_experience_range"),
        CheckConstraint("reliability BETWEEN 1 AND 10", name="ck_reliability_range"),
        CheckConstraint("comfort BETWEEN 1 AND 10", name="ck_comfort_range"),
        CheckConstraint("consumption_satisfaction BETWEEN 1 AND 10", name="ck_consumption_satisfaction_range"),
        {"schema": "vehicle"}
    )

    id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True),
        primary_key=True,
        default=uuid.uuid4,
        server_default=func.gen_random_uuid()
    )
    vehicle_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("vehicle.vehicle_model_definitions.id", ondelete="CASCADE"),
        nullable=False,
        index=True
    )
    user_id: Mapped[int] = mapped_column(
        Integer,
        ForeignKey("identity.users.id", ondelete="CASCADE"),
        nullable=False,
        index=True
    )
    driving_experience: Mapped[int] = mapped_column(Integer, nullable=False)
    reliability: Mapped[int] = mapped_column(Integer, nullable=False)
    comfort: Mapped[int] = mapped_column(Integer, nullable=False)
    consumption_satisfaction: Mapped[int] = mapped_column(Integer, nullable=False)
    comment: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now())

    # Kapcsolatok
    vehicle: Mapped["VehicleModelDefinition"] = relationship("VehicleModelDefinition", back_populates="ratings")
    user: Mapped["User"] = relationship("User", back_populates="vehicle_ratings")

    def __repr__(self) -> str:
        return f"VehicleUserRating(id={self.id}, vehicle_id={self.vehicle_id}, user_id={self.user_id})"

    @property
    def average_score(self) -> float:
        """Számított átlagpontszám a 4 dimenzióból."""
        scores = [self.driving_experience, self.reliability, self.comfort, self.consumption_satisfaction]
        return sum(scores) / 4.0


class GbCatalogDiscovery(Base):
    __tablename__ = "gb_catalog_discovery"
    __table_args__ = {"schema": "vehicle"}
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    vrm: Mapped[str] = mapped_column(String(20), unique=True)
    make: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
    model: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
    status: Mapped[str] = mapped_column(String(20), default='pending')
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())