"""
Linux BenchTools - Documents API
"""

import os
import hashlib
from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Form
from fastapi.responses import FileResponse
from sqlalchemy.orm import Session
from typing import List
from datetime import datetime

from app.db.session import get_db
from app.core.config import settings
from app.schemas.document import DocumentResponse
from app.models.document import Document
from app.models.device import Device

router = APIRouter()


def generate_file_hash(content: bytes) -> str:
    """Generate a unique hash for file storage"""
    return hashlib.sha256(content).hexdigest()[:16]


@router.get("/devices/{device_id}/docs", response_model=List[DocumentResponse])
async def get_device_documents(
    device_id: int,
    db: Session = Depends(get_db)
):
    """Get all documents for a device"""
    device = db.query(Device).filter(Device.id == device_id).first()
    if not device:
        raise HTTPException(status_code=404, detail="Device not found")

    docs = db.query(Document).filter(Document.device_id == device_id).all()

    return [
        DocumentResponse(
            id=doc.id,
            device_id=doc.device_id,
            doc_type=doc.doc_type,
            filename=doc.filename,
            mime_type=doc.mime_type,
            size_bytes=doc.size_bytes,
            uploaded_at=doc.uploaded_at.isoformat()
        )
        for doc in docs
    ]


@router.post("/devices/{device_id}/docs", response_model=DocumentResponse, status_code=status.HTTP_201_CREATED)
async def upload_document(
    device_id: int,
    file: UploadFile = File(...),
    doc_type: str = Form(...),
    db: Session = Depends(get_db)
):
    """Upload a document for a device"""
    device = db.query(Device).filter(Device.id == device_id).first()
    if not device:
        raise HTTPException(status_code=404, detail="Device not found")

    # Read file content
    content = await file.read()
    file_size = len(content)

    # Check file size
    if file_size > settings.MAX_UPLOAD_SIZE:
        raise HTTPException(
            status_code=413,
            detail=f"File too large. Maximum size: {settings.MAX_UPLOAD_SIZE} bytes"
        )

    # Generate unique filename
    file_hash = generate_file_hash(content)
    ext = os.path.splitext(file.filename)[1]
    stored_filename = f"{file_hash}_{device_id}{ext}"
    stored_path = os.path.join(settings.UPLOAD_DIR, stored_filename)

    # Ensure upload directory exists
    os.makedirs(settings.UPLOAD_DIR, exist_ok=True)

    # Save file
    with open(stored_path, "wb") as f:
        f.write(content)

    # Create database record
    doc = Document(
        device_id=device_id,
        doc_type=doc_type,
        filename=file.filename,
        stored_path=stored_path,
        mime_type=file.content_type or "application/octet-stream",
        size_bytes=file_size,
        uploaded_at=datetime.utcnow()
    )

    db.add(doc)
    db.commit()
    db.refresh(doc)

    return DocumentResponse(
        id=doc.id,
        device_id=doc.device_id,
        doc_type=doc.doc_type,
        filename=doc.filename,
        mime_type=doc.mime_type,
        size_bytes=doc.size_bytes,
        uploaded_at=doc.uploaded_at.isoformat()
    )


@router.get("/docs/{doc_id}/download")
async def download_document(
    doc_id: int,
    db: Session = Depends(get_db)
):
    """Download a document"""
    doc = db.query(Document).filter(Document.id == doc_id).first()
    if not doc:
        raise HTTPException(status_code=404, detail="Document not found")

    if not os.path.exists(doc.stored_path):
        raise HTTPException(status_code=404, detail="File not found on disk")

    return FileResponse(
        path=doc.stored_path,
        filename=doc.filename,
        media_type=doc.mime_type
    )


@router.delete("/docs/{doc_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_document(
    doc_id: int,
    db: Session = Depends(get_db)
):
    """Delete a document"""
    doc = db.query(Document).filter(Document.id == doc_id).first()
    if not doc:
        raise HTTPException(status_code=404, detail="Document not found")

    # Delete file from disk
    if os.path.exists(doc.stored_path):
        os.remove(doc.stored_path)

    # Delete from database
    db.delete(doc)
    db.commit()

    return None
