"""管理后台优惠券 API — 需管理员登录"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from typing import List, Optional
from datetime import datetime

from app.api.deps import get_db, get_admin_user
from app.core.models.discount import Discount
from app.core.models.user import User
from pydantic import BaseModel, Field

router = APIRouter(prefix="/coupons", tags=["优惠券管理"])


class CouponOut(BaseModel):
    id: int
    code: Optional[str]
    name: str
    type: str
    value: float
    min_order_amount: Optional[float]
    usage_limit: Optional[int]
    used_count: int
    start_at: Optional[datetime]
    end_at: Optional[datetime]
    is_active: bool
    created_at: Optional[datetime]

    model_config = {"from_attributes": True}


class CouponCreate(BaseModel):
    code: str = Field(..., max_length=50)
    name: str = Field(..., max_length=100, description="优惠券展示名称")
    type: str = Field(..., description="percentage / fixed / buy_x_get_y")
    value: float = Field(..., gt=0)
    min_order_amount: Optional[float] = None
    usage_limit: Optional[int] = None
    start_at: Optional[datetime] = None
    end_at: Optional[datetime] = None
    is_active: bool = True


class CouponUpdate(BaseModel):
    name: Optional[str] = Field(None, max_length=100)
    type: Optional[str] = None
    value: Optional[float] = None
    min_order_amount: Optional[float] = None
    usage_limit: Optional[int] = None
    start_at: Optional[datetime] = None
    end_at: Optional[datetime] = None
    is_active: Optional[bool] = None


@router.get("", response_model=List[CouponOut])
async def list_coupons(
    db: AsyncSession = Depends(get_db),
    admin_user: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(Discount)
        .where(Discount.tenant_id == admin_user.tenant_id)
        .order_by(Discount.id.desc())
    )
    return [_enrich(c) for c in result.scalars().all()]


@router.post("", response_model=CouponOut, status_code=status.HTTP_201_CREATED)
async def create_coupon(
    body: CouponCreate,
    db: AsyncSession = Depends(get_db),
    admin_user: User = Depends(get_admin_user),
):
    existing = await db.execute(
        select(Discount).where(
            Discount.tenant_id == admin_user.tenant_id,
            Discount.code == body.code.upper(),
        )
    )
    if existing.scalar_one_or_none():
        raise HTTPException(status_code=400, detail="该券码已存在")

    from decimal import Decimal
    coupon = Discount(
        tenant_id=admin_user.tenant_id,
        code=body.code.upper(),
        type=body.type,
        value=Decimal(str(body.value)),
        min_order_amount=Decimal(str(body.min_order_amount)) if body.min_order_amount else None,
        usage_limit=body.usage_limit,
        start_at=body.start_at,
        end_at=body.end_at,
        is_active=1 if body.is_active else 0,
    )
    db.add(coupon)
    await db.commit()
    await db.refresh(coupon)
    return _enrich(coupon)


@router.put("/{coupon_id}", response_model=CouponOut)
async def update_coupon(
    coupon_id: int,
    body: CouponUpdate,
    db: AsyncSession = Depends(get_db),
    admin_user: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(Discount).where(Discount.id == coupon_id, Discount.tenant_id == admin_user.tenant_id)
    )
    coupon = result.scalar_one_or_none()
    if not coupon:
        raise HTTPException(status_code=404, detail="优惠券不存在")

    for k, v in body.model_dump(exclude_unset=True).items():
        if k == "value" and v is not None:
            from decimal import Decimal
            setattr(coupon, k, Decimal(str(v)))
        elif k in ("min_order_amount",) and v is not None:
            from decimal import Decimal
            setattr(coupon, k, Decimal(str(v)))
        elif k == "is_active":
            setattr(coupon, k, 1 if v else 0)
        elif v is not None:
            setattr(coupon, k, v)

    await db.commit()
    await db.refresh(coupon)
    return _enrich(coupon)


@router.delete("/{coupon_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_coupon(
    coupon_id: int,
    db: AsyncSession = Depends(get_db),
    admin_user: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(Discount).where(Discount.id == coupon_id, Discount.tenant_id == admin_user.tenant_id)
    )
    coupon = result.scalar_one_or_none()
    if not coupon:
        raise HTTPException(status_code=404, detail="优惠券不存在")

    await db.delete(coupon)
    await db.commit()


def _type_label(t: str) -> str:
    return {"percentage": "折扣券", "percent": "折扣券", "fixed": "满减券", "buy_x_get_y": "买赠券"}.get(t, t)


def _enrich(c: Discount) -> CouponOut:
    return CouponOut(
        id=c.id,
        code=c.code,
        name=f"{_type_label(c.type)} {c.code or ''}".strip(),
        type=c.type,
        value=float(c.value),
        min_order_amount=float(c.min_order_amount) if c.min_order_amount else None,
        usage_limit=c.usage_limit,
        used_count=c.used_count,
        start_at=c.start_at,
        end_at=c.end_at,
        is_active=bool(c.is_active),
        created_at=c.created_at,
    )