from sqlalchemy.orm import Session
from fastapi import HTTPException, status

from src.apps.wine_settings.models.appellations import WineAppellation
from src.apps.wine_settings.schemas.appellations import (
    WineAppellationCreateSchema,
    WineAppellationUpdateSchema,
    WineAppellationOutSchema
)
from src.utils.pagination import QueryPaginator
from src.apps.base.models.regions import Region, SubRegion
from src.apps.base.models.country import Country



def get_all_wine_appellations(db: Session, page: int = 1, per_page: int = 10):
    offset = (page - 1) * per_page
    query = db.query(WineAppellation)

    paginator = QueryPaginator(
        query=query,
        schema=WineAppellationOutSchema,
        url="/wine-appellations",
        offset=offset,
        limit=per_page,
        use_orm=True
    )
    return paginator.paginate()


def get_wine_appellation_by_id(db: Session, appellation_id: int):
    obj = db.query(WineAppellation).filter(WineAppellation.id == appellation_id).first()
    if not obj:
        raise HTTPException(status_code=404, detail="Wine Appellation not found")
    return obj


def create_wine_appellation(db: Session, payload: WineAppellationCreateSchema) -> WineAppellation:
    # Validate Country
    country = db.query(Country).filter(Country.id == payload.country_id).first()
    if not country:
        raise HTTPException(status_code=404, detail="Country not found")

    # Validate Region
    region = db.query(Region).filter(Region.id == payload.region_id).first()
    if not region:
        raise HTTPException(status_code=404, detail="Region not found")

    # Validate Sub-region
    if payload.sub_region_id:
        sub_region = db.query(SubRegion).filter(SubRegion.id == payload.sub_region_id).first()
        if not sub_region:
            raise HTTPException(status_code=404, detail="Sub-region not found")

        if sub_region.region_id != payload.region_id:
            raise HTTPException(
                status_code=400,
                detail=f"Sub-region (ID: {payload.sub_region_id}) does not belong to Region (ID: {payload.region_id})"
            )

    # Check for existing Appellation
    existing = db.query(WineAppellation).filter(
        WineAppellation.title == payload.title,
        WineAppellation.region_id == payload.region_id,
        WineAppellation.sub_region_id == payload.sub_region_id
    ).first()
    if existing:
        raise HTTPException(status_code=400, detail="Wine Appellation already exists")

    # Create new Wine Appellation
    appellation = WineAppellation(**payload.dict())
    db.add(appellation)
    db.commit()
    db.refresh(appellation)
    return appellation


def update_wine_appellation(db: Session, appellation_id: int, payload: WineAppellationUpdateSchema):
    obj = get_wine_appellation_by_id(db, appellation_id)
    for field, value in payload.dict(exclude_unset=True).items():
        setattr(obj, field, value)

    db.commit()
    db.refresh(obj)
    return obj


def delete_wine_appellation(db: Session, appellation_id: int):
    obj = get_wine_appellation_by_id(db, appellation_id)
    db.delete(obj)
    db.commit()
