from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from datetime import date
from app.database import get_db
from app.models.todo import DailyTodo, TodoSource
from app.models.user import User
from app.routers.auth import get_current_user
from app.schemas.todo import (
    TodoCreate, TodoUpdate, TodoOut, TodoListOut, TodoSummaryOut
)
from app.services.todo_service import generate_daily_todos

router = APIRouter(prefix="/api/todos", tags=["待办"])


@router.get("", response_model=TodoListOut)
async def list_todos(
    date_str: str = Query(default=None),  # YYYY-MM-DD，默认当天
    page: int = Query(default=1, ge=1),
    page_size: int = Query(default=50, ge=1, le=100),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    target_date = date_str or date.today().isoformat()
    offset = (page - 1) * page_size

    # 查询总数
    count_q = select(func.count()).select_from(DailyTodo).where(
        DailyTodo.user_id == current_user.id,
        DailyTodo.todo_date == target_date,
    )
    total = (await db.execute(count_q)).scalar()

    # 查询列表
    q = select(DailyTodo).where(
        DailyTodo.user_id == current_user.id,
        DailyTodo.todo_date == target_date,
    ).order_by(DailyTodo.created_at.desc()).offset(offset).limit(page_size)

    items = (await db.execute(q)).scalars().all()
    return TodoListOut(items=items, total=total, page=page, page_size=page_size)


@router.post("", response_model=TodoOut, status_code=201)
async def create_todo(
    data: TodoCreate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    todo = DailyTodo(
        user_id=current_user.id,
        title=data.title,
        source=TodoSource.MANUAL,
        todo_date=date.today().isoformat(),
    )
    db.add(todo)
    await db.commit()
    await db.refresh(todo)
    return todo


@router.patch("/{todo_id}", response_model=TodoOut)
async def update_todo(
    todo_id: str,
    data: TodoUpdate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    result = await db.execute(
        select(DailyTodo).where(DailyTodo.id == todo_id, DailyTodo.user_id == current_user.id)
    )
    todo = result.scalar_one_or_none()
    if not todo:
        raise HTTPException(status_code=404, detail="待办不存在")

    # 历史日期不允许修改
    if todo.todo_date != date.today().isoformat():
        raise HTTPException(status_code=403, detail="历史待办不可修改")

    if data.title is not None:
        todo.title = data.title
    if data.is_completed is not None:
        from datetime import UTC, datetime
        todo.is_completed = data.is_completed
        todo.completed_at = datetime.now(UTC) if data.is_completed else None

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


@router.delete("/{todo_id}", status_code=204)
async def delete_todo(
    todo_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    result = await db.execute(
        select(DailyTodo).where(DailyTodo.id == todo_id, DailyTodo.user_id == current_user.id)
    )
    todo = result.scalar_one_or_none()
    if not todo:
        raise HTTPException(status_code=404, detail="待办不存在")
    if todo.todo_date != date.today().isoformat():
        raise HTTPException(status_code=403, detail="历史待办不可删除")

    await db.delete(todo)
    await db.commit()


@router.post("/ai-generate", response_model=TodoListOut)
async def ai_generate_todos(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    target_date = date.today().isoformat()

    # 幂等检查：是否已有AI生成记录
    check_q = select(func.count()).select_from(DailyTodo).where(
        DailyTodo.user_id == current_user.id,
        DailyTodo.todo_date == target_date,
        DailyTodo.source.in_([TodoSource.AI_KANBAN, TodoSource.AI_CHAT]),
    )
    count = (await db.execute(check_q)).scalar()

    if count > 0:
        # 已生成，返回现有记录
        q = select(DailyTodo).where(
            DailyTodo.user_id == current_user.id,
            DailyTodo.todo_date == target_date,
        ).order_by(DailyTodo.created_at.desc())
        items = (await db.execute(q)).scalars().all()
        return TodoListOut(items=items, total=len(items), page=1, page_size=50)

    # 执行AI生成
    todos = await generate_daily_todos(current_user.id, db)
    return TodoListOut(items=todos, total=len(todos), page=1, page_size=50)


@router.get("/summary", response_model=TodoSummaryOut)
async def get_summary(
    date_str: str = Query(default=None),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    target_date = date_str or date.today().isoformat()
    q = select(DailyTodo).where(
        DailyTodo.user_id == current_user.id,
        DailyTodo.todo_date == target_date,
    )
    todos = (await db.execute(q)).scalars().all()
    completed = sum(1 for t in todos if t.is_completed)
    return TodoSummaryOut(date=target_date, total=len(todos), completed=completed, pending=len(todos) - completed)
