from fastapi import HTTPException
from sqlalchemy import INTEGER, VARCHAR, ForeignKey
from sqlalchemy.orm import Mapped, mapped_column, relationship,Session
from app.models.main import Base
from pydantic import Field
from app.utils.schemas_utils import CustomModel

class VesselBase(CustomModel):
    vessel_id: int | None = Field(default=None)
    vessel_name: str | None = Field(default=None)
    vessel_type: str | None = Field(default=None)
    imo: str | None = Field(default=None)
    vessel_standars: str | None = Field(default=None)
    sister_company: str | None = Field(default=None)
    company_code : str | None = Field(default=None)
    company_id: int | None = Field(default=None)


class TblVesselList(Base):
    __tablename__ = "tbl_vessel_list"

    vessel_id: Mapped[int] = mapped_column(INTEGER, primary_key=True, autoincrement=True)
    vessel_name: Mapped[str] = mapped_column(VARCHAR(255), nullable=False)
    vessel_type: Mapped[str] = mapped_column(VARCHAR(100), nullable=True)
    imo: Mapped[str] = mapped_column(VARCHAR(50), nullable=True)
    vessel_standars: Mapped[str] = mapped_column(VARCHAR(100), nullable=True)
    sister_company: Mapped[str] = mapped_column(VARCHAR(25), nullable=True)
    company_code: Mapped[str] = mapped_column(VARCHAR(25), nullable=True)
    company_id: Mapped[int] = mapped_column(INTEGER, ForeignKey("tbl_company_list.company_id"), nullable=False)

    company = relationship("TblCompanyList", back_populates="vessels")
    seafarers = relationship("TblSeafarers", back_populates="vessel")

    @classmethod
    def create(cls, data: VesselBase, db: Session) -> "TblVesselList":
        new_vessel = cls(**data.model_dump())
        db.add(new_vessel)
        db.flush()
        return new_vessel

    @classmethod
    def get_by_id(cls, vessel_id: int, db: Session) -> VesselBase:
        vessel = db.query(cls).filter(cls.vessel_id == vessel_id).first()
        if not vessel:
            raise HTTPException(status_code=404, detail="Vessel not found")
        return VesselBase.model_validate(vessel)

    @classmethod
    def update(cls, vessel_id: int, data: VesselBase, db: Session) -> "TblVesselList | None":
        get_data = db.query(cls).filter(cls.vessel_id == vessel_id).first()
        if not get_data:
            return None  
        data_dict = data.model_dump()
        for key, value in data_dict.items():
            if value is not None:
                setattr(get_data, key, value)
        db.commit()
        db.refresh(get_data)
        return get_data