from datetime import datetime
from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select

from app.api.deps import get_db, get_admin_user
from app.core.models.banner import StoreBanner
from app.core.models.user import User
from pydantic import BaseModel, field_serializer
from typing import Optional

router = APIRouter(prefix="/banners", tags=["Banner 管理"])


class BannerOut(BaseModel):
    id: int
    title: str
    image_url: str
    link_url: Optional[str] = None
    sort_order: int = 0
    is_active: bool = True
    start_at: Optional[str] = None
    end_at: Optional[str] = None
    created_at: Optional[datetime] = None
    start_at: Optional[datetime] = None
    end_at: Optional[datetime] = None

    @field_serializer('created_at', 'start_at', 'end_at')
    def serialize_dt(self, v):
        return v.isoformat() if v else None

    model_config = {"from_attributes": True}


class BannerCreate(BaseModel):
    title: str
    image_url: str
    link_url: Optional[str] = None
    sort_order: int = 0
    is_active: bool = True
    start_at: Optional[str] = None
    end_at: Optional[str] = None


class BannerUpdate(BaseModel):
    title: Optional[str] = None
    image_url: Optional[str] = None
    link_url: Optional[str] = None
    sort_order: Optional[int] = None
    is_active: Optional[bool] = None
    start_at: Optional[str] = None
    end_at: Optional[str] = None


@router.get("", response_model=list[BannerOut])
async def list_banners(
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    rows = (await db.execute(
        select(StoreBanner)
        .where(StoreBanner.tenant_id == admin.tenant_id)
        .order_by(StoreBanner.sort_order.asc())
    )).scalars().all()
    return rows


@router.post("", response_model=BannerOut, status_code=201)
async def create_banner(
    body: BannerCreate,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    row = StoreBanner(tenant_id=admin.tenant_id, **body.model_dump())
    db.add(row)
    await db.commit()
    await db.refresh(row)
    return row


@router.put("/{banner_id}", response_model=BannerOut)
async def update_banner(
    banner_id: int,
    body: BannerUpdate,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(StoreBanner).where(
            StoreBanner.id == banner_id,
            StoreBanner.tenant_id == admin.tenant_id,
        )
    )
    row = result.scalar_one_or_none()
    if not row:
        from fastapi import HTTPException
        raise HTTPException(status_code=404, detail="Banner 不存在")

    for k, v in body.model_dump(exclude_unset=True).items():
        setattr(row, k, v)
    await db.commit()
    await db.refresh(row)
    return row


@router.delete("/{banner_id}", status_code=204)
async def delete_banner(
    banner_id: int,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(StoreBanner).where(
            StoreBanner.id == banner_id,
            StoreBanner.tenant_id == admin.tenant_id,
        )
    )
    row = result.scalar_one_or_none()
    if not row:
        from fastapi import HTTPException
        raise HTTPException(status_code=404, detail="Banner 不存在")

    await db.delete(row)
    await db.commit()
    return None