"""
Son of Anton — Attachment Upload Routes
Handles file uploads for chat messages.
"""

import os
import uuid
import shutil
from pathlib import Path
from datetime import datetime, timezone

from fastapi import APIRouter, Depends, UploadFile, File, HTTPException, Form
from typing import List

from ..auth import get_current_user
from ..database import get_db
from ..services.file_processor import classify_media, validate_file

router = APIRouter(prefix="/chats/{chat_id}/attachments", tags=["attachments"])

UPLOAD_DIR = os.getenv("UPLOAD_DIR", "uploads")
Path(UPLOAD_DIR).mkdir(parents=True, exist_ok=True)


@router.post("")
async def upload_attachments(
    chat_id: str,
    files: List[UploadFile] = File(...),
    user=Depends(get_current_user),
    db=Depends(get_db),
):
    """Upload one or more files to a chat. Returns attachment metadata."""

    # Verify chat belongs to user
    chat = await db.fetchrow(
        "SELECT id, user_id FROM chats WHERE id = $1", uuid.UUID(chat_id)
    )
    if not chat:
        raise HTTPException(404, "Chat not found")
    if str(chat["user_id"]) != str(user["id"]):
        raise HTTPException(403, "Not your chat")

    if len(files) > 10:
        raise HTTPException(400, "Maximum 10 files per upload")

    results = []

    for f in files:
        # Read file content to get size
        content = await f.read()
        size = len(content)

        # Validate
        ok, error = validate_file(f.filename or "file", f.content_type or "", size)
        if not ok:
            raise HTTPException(400, f"File '{f.filename}': {error}")

        media_type = classify_media(f.content_type or "")

        # Generate unique storage filename
        ext = Path(f.filename or "file").suffix or ".bin"
        storage_name = f"{uuid.uuid4().hex}{ext}"
        chat_dir = Path(UPLOAD_DIR) / chat_id
        chat_dir.mkdir(parents=True, exist_ok=True)
        storage_path = f"{chat_id}/{storage_name}"
        full_path = chat_dir / storage_name

        # Write file
        full_path.write_bytes(content)

        # Insert DB record
        att = await db.fetchrow(
            """
            INSERT INTO attachments (chat_id, user_id, filename, original_filename, mime_type, file_size, media_type, storage_path)
            VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
            RETURNING id, filename, original_filename, mime_type, file_size, media_type, created_at
            """,
            uuid.UUID(chat_id),
            user["id"],
            storage_name,
            f.filename or "file",
            f.content_type or "application/octet-stream",
            size,
            media_type,
            storage_path,
        )

        results.append({
            "id": str(att["id"]),
            "filename": att["original_filename"],
            "mime_type": att["mime_type"],
            "file_size": att["file_size"],
            "media_type": att["media_type"],
            "created_at": att["created_at"].isoformat(),
        })

    return results


@router.get("")
async def list_attachments(
    chat_id: str,
    user=Depends(get_current_user),
    db=Depends(get_db),
):
    """List all attachments for a chat."""
    chat = await db.fetchrow(
        "SELECT id, user_id FROM chats WHERE id = $1", uuid.UUID(chat_id)
    )
    if not chat:
        raise HTTPException(404, "Chat not found")
    if str(chat["user_id"]) != str(user["id"]):
        raise HTTPException(403, "Not your chat")

    rows = await db.fetch(
        """
        SELECT id, original_filename as filename, mime_type, file_size, media_type, message_id, created_at
        FROM attachments WHERE chat_id = $1 ORDER BY created_at
        """,
        uuid.UUID(chat_id),
    )
    return [dict(r) for r in rows]


@router.get("/{attachment_id}/preview")
async def preview_attachment(
    chat_id: str,
    attachment_id: str,
    user=Depends(get_current_user),
    db=Depends(get_db),
):
    """Return raw file content for preview (images mainly)."""
    from fastapi.responses import FileResponse

    att = await db.fetchrow(
        """
        SELECT a.*, c.user_id as chat_owner
        FROM attachments a JOIN chats c ON a.chat_id = c.id
        WHERE a.id = $1 AND a.chat_id = $2
        """,
        uuid.UUID(attachment_id),
        uuid.UUID(chat_id),
    )
    if not att:
        raise HTTPException(404, "Attachment not found")
    if str(att["chat_owner"]) != str(user["id"]):
        raise HTTPException(403, "Not your attachment")

    full_path = Path(UPLOAD_DIR) / att["storage_path"]
    if not full_path.exists():
        raise HTTPException(404, "File not found on disk")

    return FileResponse(
        path=str(full_path),
        media_type=att["mime_type"],
        filename=att["original_filename"],
    )