"""Notes CRUD router for BadNote."""

import json
from datetime import datetime, timezone
from uuid import uuid4

from fastapi import APIRouter, Depends, HTTPException, Query, status

from ..auth import get_current_user
from ..database import get_db
from ..models import NoteCreate, NoteResponse, NoteUpdate

router = APIRouter()


def _row_to_note(row) -> NoteResponse:
    return NoteResponse(
        id=row["id"],
        user_id=row["user_id"],
        title=row["title"],
        created_at=row["created_at"],
        updated_at=row["updated_at"],
        tags=json.loads(row["tags"]),
        strokes_json=row["strokes_json"],
    )


@router.get("", response_model=list[NoteResponse])
async def list_notes(
    since: str | None = Query(None, description="ISO8601 timestamp filter"),
    user_id: str = Depends(get_current_user),
) -> list[NoteResponse]:
    """List notes, optionally filtered by updated_at > since."""
    db = await get_db()
    if since:
        cursor = await db.execute(
            "SELECT * FROM notes WHERE user_id = ? AND updated_at > ? ORDER BY updated_at",
            (user_id, since),
        )
    else:
        cursor = await db.execute(
            "SELECT * FROM notes WHERE user_id = ? ORDER BY updated_at",
            (user_id,),
        )
    rows = await cursor.fetchall()
    return [_row_to_note(r) for r in rows]


@router.get("/{note_id}", response_model=NoteResponse)
async def get_note(
    note_id: str,
    user_id: str = Depends(get_current_user),
) -> NoteResponse:
    """Get a single note by ID."""
    db = await get_db()
    cursor = await db.execute(
        "SELECT * FROM notes WHERE id = ? AND user_id = ?", (note_id, user_id)
    )
    row = await cursor.fetchone()
    if row is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Note not found")
    return _row_to_note(row)


@router.post("", response_model=NoteResponse, status_code=status.HTTP_201_CREATED)
async def upsert_note(
    body: NoteCreate,
    user_id: str = Depends(get_current_user),
) -> NoteResponse:
    """Create or update a note (upsert by id)."""
    db = await get_db()
    now = datetime.now(timezone.utc).isoformat()
    tags_json = json.dumps(body.tags)

    existing = await (
        await db.execute(
            "SELECT id FROM notes WHERE id = ? AND user_id = ?", (body.id, user_id)
        )
    ).fetchone()

    if existing:
        await db.execute(
            """UPDATE notes SET title = ?, tags = ?, strokes_json = ?, updated_at = ?
               WHERE id = ? AND user_id = ?""",
            (body.title, tags_json, body.strokes_json, now, body.id, user_id),
        )
    else:
        await db.execute(
            """INSERT INTO notes (id, user_id, title, created_at, updated_at, tags, strokes_json)
               VALUES (?, ?, ?, ?, ?, ?, ?)""",
            (body.id, user_id, body.title, now, now, tags_json, body.strokes_json),
        )
    await db.commit()

    cursor = await db.execute(
        "SELECT * FROM notes WHERE id = ? AND user_id = ?", (body.id, user_id)
    )
    row = await cursor.fetchone()
    return _row_to_note(row)


@router.delete("/{note_id}", status_code=status.HTTP_200_OK)
async def delete_note(
    note_id: str,
    user_id: str = Depends(get_current_user),
) -> dict:
    """Delete a note."""
    db = await get_db()
    cursor = await db.execute(
        "SELECT id FROM notes WHERE id = ? AND user_id = ?", (note_id, user_id)
    )
    if await cursor.fetchone() is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Note not found")

    await db.execute("DELETE FROM notes WHERE id = ? AND user_id = ?", (note_id, user_id))
    await db.commit()
    return {"deleted": note_id}
