from datetime import date

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

from app.database import get_db
from app.models.goal import Goal
from app.models.user import User
from app.routers.auth import get_current_user
from app.schemas.goal import GoalCreate, GoalListOut, GoalOut, GoalUpdate

router = APIRouter(prefix="/api/goals", tags=["目标"])


@router.get("", response_model=GoalListOut)
async def list_goals(
    date_str: str = Query(...),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    target_date = date.fromisoformat(date_str).isoformat()
    query = (
        select(Goal)
        .where(Goal.user_id == current_user.id)
        .where(Goal.goal_date == target_date)
        .order_by(Goal.created_at.desc())
    )
    items = (await db.execute(query)).scalars().all()
    return GoalListOut(items=items)


@router.post("", response_model=GoalOut, status_code=201)
async def create_goal(
    data: GoalCreate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    goal = Goal(
        user_id=current_user.id,
        title=data.title,
        note=data.note,
        goal_date=data.goal_date.isoformat(),
        status=data.status,
    )
    db.add(goal)
    await db.commit()
    await db.refresh(goal)
    return goal


@router.patch("/{goal_id}", response_model=GoalOut)
async def update_goal(
    goal_id: str,
    data: GoalUpdate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    result = await db.execute(
        select(Goal).where(Goal.id == goal_id, Goal.user_id == current_user.id)
    )
    goal = result.scalar_one_or_none()
    if not goal:
        raise HTTPException(status_code=404, detail="目标不存在")

    payload = data.model_dump(exclude_none=True)
    if "goal_date" in payload:
        payload["goal_date"] = payload["goal_date"].isoformat()

    for field, value in payload.items():
        setattr(goal, field, value)

    await db.commit()
    await db.refresh(goal)
    return goal


@router.delete("/{goal_id}", status_code=204)
async def delete_goal(
    goal_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    result = await db.execute(
        select(Goal).where(Goal.id == goal_id, Goal.user_id == current_user.id)
    )
    goal = result.scalar_one_or_none()
    if not goal:
        raise HTTPException(status_code=404, detail="目标不存在")

    await db.delete(goal)
    await db.commit()
