import enum
from datetime import datetime, date, timezone
from decimal import Decimal
from sqlalchemy import (
    String, Boolean, Date, DateTime, DECIMAL, Integer, Text,
    ForeignKey, Enum as SAEnum
)
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.core.database import Base


class ValuationStatus(str, enum.Enum):
    bozza = "bozza"
    inviata = "inviata"
    in_lavorazione = "in_lavorazione"
    completata = "completata"
    vinta = "vinta"
    persa = "persa"


class ValuationPriority(str, enum.Enum):
    contratto = "contratto"
    preventivo = "preventivo"
    valutazione = "valutazione"


class RetakeRegime(str, enum.Enum):
    nuovo = "nuovo"
    usato = "usato"


class Valuation(Base):
    __tablename__ = "valuations"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    plate: Mapped[str] = mapped_column(String(10), ForeignKey("vehicle_registry.plate"), nullable=False, index=True)
    user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False)
    group_id: Mapped[int | None] = mapped_column(Integer, ForeignKey("groups.id"))
    motornet_code: Mapped[str | None] = mapped_column(String(20), ForeignKey("vehicle_versions.motornet_code"))
    mileage: Mapped[int | None] = mapped_column(Integer)
    retake_regime: Mapped[RetakeRegime | None] = mapped_column(SAEnum(RetakeRegime))
    expected_return_date: Mapped[date | None] = mapped_column(Date)
    interest_fuel: Mapped[str | None] = mapped_column(String(50))
    priority: Mapped[ValuationPriority] = mapped_column(
        SAEnum(ValuationPriority), default=ValuationPriority.valutazione
    )
    notes: Mapped[str | None] = mapped_column(Text)
    status: Mapped[ValuationStatus] = mapped_column(
        SAEnum(ValuationStatus), default=ValuationStatus.bozza, index=True
    )
    final_value: Mapped[Decimal | None] = mapped_column(DECIMAL(10, 2))
    evaluator_id: Mapped[int | None] = mapped_column(Integer, ForeignKey("users.id"))
    evaluator_notes: Mapped[str | None] = mapped_column(Text)
    is_frozen: Mapped[bool] = mapped_column(Boolean, default=False)
    priority_rank: Mapped[int] = mapped_column(Integer, default=3)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        default=lambda: datetime.now(timezone.utc),
        onupdate=lambda: datetime.now(timezone.utc),
    )

    photos: Mapped[list["ValuationPhoto"]] = relationship("ValuationPhoto", back_populates="valuation")
    comments: Mapped[list["ValuationComment"]] = relationship("ValuationComment", back_populates="valuation")
    history: Mapped[list["ValuationHistory"]] = relationship("ValuationHistory", back_populates="valuation")
    contracts: Mapped[list["ValuationContract"]] = relationship("ValuationContract", back_populates="valuation")
    motornet_valuations: Mapped[list["MotornetValuation"]] = relationship("MotornetValuation", back_populates="valuation")


class ValuationPhoto(Base):
    __tablename__ = "valuation_photos"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    valuation_id: Mapped[int] = mapped_column(Integer, ForeignKey("valuations.id"), nullable=False)
    filename: Mapped[str] = mapped_column(String(255), nullable=False)
    storage_path: Mapped[str] = mapped_column(String(500), nullable=False)
    uploaded_by: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False)
    uploaded_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
    )

    valuation: Mapped["Valuation"] = relationship("Valuation", back_populates="photos")


class ValuationComment(Base):
    __tablename__ = "valuation_comments"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    valuation_id: Mapped[int] = mapped_column(Integer, ForeignKey("valuations.id"), nullable=False)
    user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False)
    content: Mapped[str] = mapped_column(Text, nullable=False)
    visible_to_all: Mapped[bool] = mapped_column(Boolean, default=True)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
    )

    valuation: Mapped["Valuation"] = relationship("Valuation", back_populates="comments")


class ValuationHistory(Base):
    __tablename__ = "valuation_history"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    valuation_id: Mapped[int] = mapped_column(Integer, ForeignKey("valuations.id"), nullable=False)
    changed_by: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False)
    field_name: Mapped[str] = mapped_column(String(100), nullable=False)
    old_value: Mapped[str | None] = mapped_column(Text)
    new_value: Mapped[str | None] = mapped_column(Text)
    changed_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
    )

    valuation: Mapped["Valuation"] = relationship("Valuation", back_populates="history")
