from fastapi import APIRouter, Depends, Form, UploadFile, File, Query, HTTPException
from fastapi.responses import FileResponse
from sqlalchemy.orm import Session
from typing import Literal
from . import controller, schemas
import logging
import os

try:
    from src.utils.db import get_db
except ImportError:
    from utils.db import get_db


logger = logging.getLogger(__name__)

router = APIRouter()


@router.post("/upload-csv")
async def upload_csv(
    company_id: int = Form(...),
    upload_type: Literal["product", "purchase_order", "purchase_receive", "sales_order", "sales_return", "purchase_return", "stock_transfer"] = Form(...),
    file: UploadFile = File(...),
    db: Session = Depends(get_db)
):
    """
    Upload CSV file and queue for async background processing.
    
    The CSV file is saved to disk and a Celery task is created to process it.
    Processing happens asynchronously - the response is returned immediately.
    
    CSV types are processed in dependency order:
    - product: No dependencies, processed first
    - purchase_order: Depends on product
    - purchase_receive: Depends on product, purchase_order
    - sales_order: Depends on product, purchase_order, purchase_receive
    - sales_return: Depends on product, purchase_order, purchase_receive, sales_order
    - purchase_return: Depends on product, purchase_order, purchase_receive
    - stock_transfer: Depends on all other types
    
    Returns:
        - task_id: Celery task ID for tracking
        - task_name: Unique task name
        - status: "pending" (processing) or "hold" (waiting for dependencies)
        - file_path: Path to saved CSV file
        - message: Status message
    """
    result = await controller.process_csv_file(db, file, company_id, upload_type)
    return result


@router.get("/csv-upload-logs", tags=["Smart Inventory - Frontend"])
def get_csv_upload_logs(
    company_id: int = Query(..., description="Company ID (required)"),
    page: int = Query(1, ge=1, description="Page number"),
    perpage: int = Query(10, ge=1, le=100, description="Number of items per page"),
    csv_type: str = Query(None, description="Filter by CSV type (product, purchase_order, purchase_receive, sales_order, sales_return, purchase_return, stock_transfer)"),
    processing_status: str = Query(None, description="Filter by processing status (succeeded, failed, partially_succeeded)"),
    db: Session = Depends(get_db)
):
    """
    Get CSV upload logs with pagination and optional filtering.
    Returns logs ordered by upload_date descending (latest first).
    All dates are returned in UTC timezone.
    """
    try:
        result = controller.get_csv_upload_logs(
            db=db,
            company_id=company_id,
            page=page,
            perpage=perpage,
            csv_type=csv_type,
            processing_status=processing_status
        )
        
        return schemas.CSVUploadLogResponse(
            success=result["success"],
            data=result["data"],
            page=result["page"],
            perpage=result["perpage"],
            total=result["total"],
            message=result["message"]
        )
        
    except Exception as e:
        logger.error(f"Error fetching CSV upload logs: {str(e)}")
        return schemas.CSVUploadLogResponse(
            success=False,
            data=[],
            page=page,
            perpage=perpage,
            total=0,
            message=f"Error fetching CSV upload logs: {str(e)}"
        )


@router.get("/download-csv/{log_id}", tags=["Smart Inventory - Frontend"])
def download_csv_file(
    log_id: int,
    db: Session = Depends(get_db)
):
    """
    Download a CSV file by log ID.
    
    Security: Validates that the log entry exists and the file is available.
    
    Args:
        log_id: CSV upload log ID
    
    Returns:
        FileResponse with the CSV file for download
    """
    try:
        # Import here to avoid circular imports
        from src.smart_inventory.apps.data_import.models import CSVUploadLog
        
        # Fetch log entry by ID
        log_entry = db.query(CSVUploadLog).filter(
            CSVUploadLog.id == log_id
        ).first()
        
        if not log_entry:
            raise HTTPException(
                status_code=404,
                detail="CSV upload log not found"
            )
        
        # Get file path from log entry
        file_path = log_entry.file_path
        
        # Check if file exists
        if not os.path.exists(file_path):
            raise HTTPException(
                status_code=404,
                detail="File not found on server"
            )
        
        # Extract filename for download
        filename = os.path.basename(file_path)
        
        # Return file for download
        return FileResponse(
            path=file_path,
            filename=filename,
            media_type="text/csv",
            headers={"Content-Disposition": f"attachment; filename={filename}"}
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error downloading CSV file: {str(e)}")
        raise HTTPException(
            status_code=500,
            detail=f"Error downloading file: {str(e)}"
        )
