from fastapi import APIRouter, UploadFile, File, HTTPException, Depends, Form
from fastapi.responses import JSONResponse
from sqlalchemy.orm import Session
from typing import Optional, Dict, Any
import logging

from app.core.database import get_db
from app.services.file_service import file_service
from app.models.trip import Trip
from app.models.expense import Expense

logger = logging.getLogger(__name__)

router = APIRouter()

@router.post("/receipt")
async def upload_receipt(
    file: UploadFile = File(...),
    trip_id: int = Form(...),
    expense_id: Optional[int] = Form(None),
    db: Session = Depends(get_db)
):
    """
    Upload a receipt image for a trip expense.

    Args:
        file: Image file to upload
        trip_id: ID of the trip
        expense_id: Optional ID of the expense (for better file organization)
        db: Database session

    Returns:
        JSON response with file URLs and metadata
    """
    try:
        # Validate that trip exists and user has access
        trip = db.query(Trip).filter(Trip.id == trip_id, Trip.is_active == "active").first()
        if not trip:
            raise HTTPException(status_code=404, detail="Trip not found")

        # If expense_id is provided, validate it exists and belongs to the trip
        if expense_id:
            expense = db.query(Expense).filter(
                Expense.id == expense_id,
                Expense.trip_id == trip_id
            ).first()
            if not expense:
                raise HTTPException(status_code=404, detail="Expense not found or doesn't belong to this trip")

        # Upload and process the file
        file_url, thumbnail_url, metadata = await file_service.save_upload_file(
            file=file,
            trip_id=trip_id,
            expense_id=expense_id
        )

        # Return success response
        response_data = {
            "success": True,
            "file_url": file_url,
            "thumbnail_url": thumbnail_url,
            "metadata": {
                "filename": metadata.get("filename"),
                "file_size": metadata.get("file_size"),
                "original_size": metadata.get("original_size"),
                "resized": metadata.get("resized"),
                "new_size": metadata.get("new_size"),
                "format": metadata.get("format")
            }
        }

        logger.info(f"Successfully uploaded receipt for trip {trip_id}, expense {expense_id}: {file_url}")
        return JSONResponse(content=response_data)

    except HTTPException:
        # Re-raise HTTP exceptions (validation errors, etc.)
        raise
    except Exception as e:
        logger.error(f"Error uploading receipt: {e}")
        raise HTTPException(status_code=500, detail="Failed to upload receipt")

@router.delete("/receipt")
async def delete_receipt(
    file_url: str,
    db: Session = Depends(get_db)
):
    """
    Delete a receipt image file.

    Args:
        file_url: URL of the file to delete
        db: Database session

    Returns:
        JSON response indicating success or failure
    """
    try:
        # Validate file exists
        if not file_service.file_exists(file_url):
            raise HTTPException(status_code=404, detail="File not found")

        # Delete the file
        success = file_service.delete_file(file_url)

        if success:
            logger.info(f"Successfully deleted receipt: {file_url}")
            return JSONResponse(content={"success": True, "message": "File deleted successfully"})
        else:
            raise HTTPException(status_code=500, detail="Failed to delete file")

    except HTTPException:
        # Re-raise HTTP exceptions
        raise
    except Exception as e:
        logger.error(f"Error deleting receipt: {e}")
        raise HTTPException(status_code=500, detail="Failed to delete receipt")

@router.get("/receipt/validate")
async def validate_receipt_url(
    file_url: str,
    db: Session = Depends(get_db)
):
    """
    Validate that a receipt file exists and is accessible.

    Args:
        file_url: URL of the file to validate
        db: Database session

    Returns:
        JSON response with validation result
    """
    try:
        exists = file_service.file_exists(file_url)
        file_path = file_service.get_file_path(file_url)

        if exists:
            # Get additional file info
            stat = file_path.stat()
            return JSONResponse(content={
                "success": True,
                "exists": True,
                "file_size": stat.st_size,
                "modified": stat.st_mtime
            })
        else:
            return JSONResponse(content={
                "success": False,
                "exists": False,
                "message": "File not found"
            })

    except Exception as e:
        logger.error(f"Error validating receipt URL: {e}")
        raise HTTPException(status_code=500, detail="Failed to validate receipt")

@router.post("/cleanup")
async def cleanup_orphaned_files(
    valid_file_urls: list[str],
    db: Session = Depends(get_db)
):
    """
    Clean up orphaned receipt files that are no longer referenced.

    This is a maintenance endpoint that should be called periodically
    to clean up files that are no longer associated with any expenses.

    Args:
        valid_file_urls: List of file URLs that should be kept
        db: Database session

    Returns:
        JSON response with cleanup results
    """
    try:
        deleted_count = file_service.cleanup_orphaned_files(valid_file_urls)

        logger.info(f"Cleanup completed. Deleted {deleted_count} orphaned files")

        return JSONResponse(content={
            "success": True,
            "deleted_count": deleted_count,
            "message": f"Cleaned up {deleted_count} orphaned files"
        })

    except Exception as e:
        logger.error(f"Error during cleanup: {e}")
        raise HTTPException(status_code=500, detail="Failed to cleanup orphaned files")

@router.delete("/receipt/{expense_id}")
async def delete_expense_receipt(
    expense_id: int,
    db: Session = Depends(get_db)
):
    """
    Delete receipt files associated with a specific expense.

    Args:
        expense_id: ID of the expense whose receipt should be deleted
        db: Database session

    Returns:
        JSON response indicating success or failure
    """
    try:
        # Validate that expense exists
        expense = db.query(Expense).filter(Expense.id == expense_id).first()
        if not expense:
            raise HTTPException(status_code=404, detail="Expense not found")

        # Delete the receipt files
        success = file_service.delete_expense_files(expense_id, expense.receipt_url)

        if success:
            # Update the expense to remove the receipt_url reference
            expense.receipt_url = None
            db.commit()

            logger.info(f"Successfully deleted receipt files for expense {expense_id}")
            return JSONResponse(content={
                "success": True,
                "message": "Receipt files deleted successfully"
            })
        else:
            raise HTTPException(status_code=500, detail="Failed to delete receipt files")

    except HTTPException:
        # Re-raise HTTP exceptions
        raise
    except Exception as e:
        logger.error(f"Error deleting receipt files for expense {expense_id}: {e}")
        raise HTTPException(status_code=500, detail="Failed to delete receipt files")

@router.delete("/files/batch")
async def batch_delete_receipt_files(
    file_urls: list[str],
    db: Session = Depends(get_db)
):
    """
    Delete multiple receipt files in batch.

    Args:
        file_urls: List of file URLs to delete
        db: Database session

    Returns:
        JSON response with batch deletion results
    """
    try:
        if not file_urls:
            raise HTTPException(status_code=400, detail="No file URLs provided")

        deleted_count = 0
        failed_files = []

        for file_url in file_urls:
            if file_service.delete_receipt_file(file_url):
                deleted_count += 1
            else:
                failed_files.append(file_url)

        logger.info(f"Batch deletion completed. Deleted: {deleted_count}, Failed: {len(failed_files)}")

        return JSONResponse(content={
            "success": True,
            "deleted_count": deleted_count,
            "failed_count": len(failed_files),
            "failed_files": failed_files,
            "message": f"Deleted {deleted_count} files, {len(failed_files)} failed"
        })

    except HTTPException:
        # Re-raise HTTP exceptions
        raise
    except Exception as e:
        logger.error(f"Error during batch file deletion: {e}")
        raise HTTPException(status_code=500, detail="Failed to delete files")