"""
Dashboard Note API Route
========================
REST API for notes/memos in the AI Dashboard.
Uses PostgreSQL-based note_service.
"""

import logging
from typing import Any

from fastapi import APIRouter, HTTPException, Request
from pydantic import BaseModel

from common.note_service import (
    count_unread_notifications,
    create_comment,
    create_note,
    create_notification,
    delete_comment,
    delete_note,
    delete_notification,
    get_activity_stats,
    get_all_tags,
    get_comment_counts_batch,
    get_comments,
    get_note_by_uid,
    get_note_stats,
    get_notes,
    hard_delete_note,
    list_notifications,
    mark_all_notifications_read,
    mark_notification_read,
    toggle_pin,
    update_note,
)

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/notes/v2", tags=["Dashboard Notes"])


# =============================================================================
# REQUEST / RESPONSE MODELS
# =============================================================================

class NoteCreate(BaseModel):
    content: str
    tags: list[str] = []
    visibility: str = "PRIVATE"
    parent_id: int | None = None


class NoteUpdate(BaseModel):
    content: str | None = None
    tags: list[str] | None = None
    visibility: str | None = None
    pinned: bool | None = None
    row_status: str | None = None


class CommentCreate(BaseModel):
    content: str
    creator_id: str = "anonymous"
    creator_name: str | None = None
    visibility: str = "PUBLIC"


# =============================================================================
# NOTE ENDPOINTS
# =============================================================================

@router.get("/", summary="List Notes")
def list_notes(
    creator_id: str | None = None,
    tag: str | None = None,
    search: str | None = None,
    pinned_only: bool = False,
    limit: int = 50,
    offset: int = 0,
    include_archived: bool = False,
):
    """List notes with optional filtering by tag, search text, pin status."""
    notes = get_notes(
        creator_id=creator_id,
        tag=tag,
        search=search,
        pinned_only=pinned_only,
        limit=limit,
        offset=offset,
        include_archived=include_archived,
    )

    # Batch fetch comment counts for all notes
    if notes:
        uids = [n["uid"] for n in notes]
        counts = get_comment_counts_batch(uids)
        for note in notes:
            note["comment_count"] = counts.get(note["uid"], 0)

    return {"status": "ok", "data": notes, "count": len(notes)}


@router.post("/", summary="Create Note")
def create_new_note(body: NoteCreate):
    """Create a new note/memo."""
    note = create_note(
        creator_id="system",
        content=body.content,
        tags=body.tags,
        visibility=body.visibility,
        parent_id=body.parent_id,
    )
    return {"status": "ok", "data": note}


@router.get("/tags", summary="List All Tags")
def list_tags(creator_id: str | None = None):
    """Get all unique tags."""
    tags = get_all_tags(creator_id)
    return {"status": "ok", "data": tags}


@router.get("/stats", summary="Note Stats")
def note_stats(creator_id: str | None = None):
    """Get note statistics."""
    stats = get_note_stats(creator_id)
    return {"status": "ok", "data": stats}


@router.get("/activity", summary="Activity Stats")
def activity_stats(creator_id: str | None = None, year: int | None = None):
    """Get daily memo count for calendar heatmap."""
    data = get_activity_stats(creator_id=creator_id, year=year)
    return {"status": "ok", "data": data}


@router.get("/{uid}", summary="Get Note")
def get_single_note(uid: str):
    """Get a single note by UID."""
    # Prevent conflicting with /notifications, /tags, /stats
    if uid in ("notifications", "tags", "stats", "activity"):
        raise HTTPException(status_code=400, detail="Invalid UID")
    note = get_note_by_uid(uid)
    if not note:
        raise HTTPException(status_code=404, detail="Note not found")
    # Include comment count
    from common.note_service import get_comment_count
    note["comment_count"] = get_comment_count(uid)
    return {"status": "ok", "data": note}


@router.patch("/{uid}", summary="Update Note")
def update_existing_note(uid: str, body: NoteUpdate):
    """Update a note (content, tags, visibility, etc.)."""
    fields = body.model_dump(exclude_none=True)
    note = update_note(uid, **fields)
    if not note:
        raise HTTPException(status_code=404, detail="Note not found")
    return {"status": "ok", "data": note}


@router.post("/{uid}/pin", summary="Toggle Pin")
def pin_note(uid: str):
    """Toggle pin/unpin a note."""
    note = toggle_pin(uid)
    if not note:
        raise HTTPException(status_code=404, detail="Note not found")
    return {"status": "ok", "data": note}


@router.delete("/{uid}", summary="Delete Note")
def delete_existing_note(uid: str, hard: bool = False):
    """Delete (archive) a note. Use hard=true for permanent deletion."""
    if hard:
        ok = hard_delete_note(uid)
    else:
        ok = delete_note(uid)

    if not ok:
        raise HTTPException(status_code=404, detail="Note not found")
    return {"status": "ok", "message": "Note deleted"}


# =============================================================================
# COMMENT ENDPOINTS
# =============================================================================

@router.get("/{uid}/comments", summary="List Comments")
def list_note_comments(uid: str, limit: int = 100, offset: int = 0):
    """Get all comments for a note."""
    note = get_note_by_uid(uid)
    if not note:
        raise HTTPException(status_code=404, detail="Note not found")

    comments = get_comments(uid, limit=limit, offset=offset)
    return {"status": "ok", "data": comments, "count": len(comments)}


@router.post("/{uid}/comments", summary="Create Comment")
def create_note_comment(uid: str, body: CommentCreate):
    """Create a comment on a note."""
    note = get_note_by_uid(uid)
    if not note:
        raise HTTPException(status_code=404, detail="Note not found")

    comment = create_comment(
        parent_note_uid=uid,
        content=body.content,
        creator_id=body.creator_id,
        creator_name=body.creator_name,
        visibility=body.visibility,
    )

    # Create notification for note owner (don't notify self)
    if note["creator_id"] != body.creator_id:
        try:
            create_notification(
                recipient_id=note["creator_id"],
                sender_id=body.creator_id,
                sender_name=body.creator_name,
                note_uid=uid,
                notification_type="COMMENT",
                comment_uid=comment["uid"],
            )
        except Exception as e:
            logger.warning("Failed to create notification: %s", e)

    return {"status": "ok", "data": comment}


@router.delete("/comments/{comment_uid}", summary="Delete Comment")
def remove_comment(comment_uid: str):
    """Delete a comment by its UID."""
    ok = delete_comment(comment_uid)
    if not ok:
        raise HTTPException(status_code=404, detail="Comment not found")
    return {"status": "ok", "message": "Comment deleted"}


# =============================================================================
# NOTIFICATION ENDPOINTS
# =============================================================================

@router.get("/notifications/list", summary="List Notifications")
def get_notifications(
    recipient_id: str = "system",
    status: str | None = None,
    limit: int = 50,
    offset: int = 0,
):
    """List notifications for a user."""
    notifications = list_notifications(
        recipient_id=recipient_id,
        status=status,
        limit=limit,
        offset=offset,
    )
    unread = count_unread_notifications(recipient_id)
    return {
        "status": "ok",
        "data": notifications,
        "count": len(notifications),
        "unread_count": unread,
    }


@router.patch("/notifications/{notification_id}/read", summary="Mark Read")
def mark_read(notification_id: int):
    """Mark a notification as read."""
    ok = mark_notification_read(notification_id)
    if not ok:
        raise HTTPException(status_code=404, detail="Notification not found")
    return {"status": "ok", "message": "Marked as read"}


@router.post("/notifications/read-all", summary="Mark All Read")
def mark_all_read(recipient_id: str = "system"):
    """Mark all notifications as read for a user."""
    mark_all_notifications_read(recipient_id)
    return {"status": "ok", "message": "All marked as read"}


@router.delete("/notifications/{notification_id}", summary="Delete Notification")
def remove_notification(notification_id: int):
    """Delete a notification."""
    ok = delete_notification(notification_id)
    if not ok:
        raise HTTPException(status_code=404, detail="Notification not found")
    return {"status": "ok", "message": "Notification deleted"}
