from fastapi import APIRouter, Depends, Query, status, HTTPException
from sqlalchemy.orm import Session
from typing import Optional
from datetime import date
from utils.utils import get_db, ReportType, ReportStatus
from . import handler
from .schema import (
    ReportCreate,
    ReportUpdate,
    ReportResponse,
    ReportDetailResponse,
    PaginatedReportResponse,
)

router = APIRouter(prefix="/reports", tags=["Reports"])


@router.post(
    "/",
    response_model=ReportResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Report",
    description="Creates a new report record. Validates that the user who generated the report exists. Returns 400 if the user does not exist.",
)
def create_report_route(data: ReportCreate, db: Session = Depends(get_db)):
    return handler.create_report(db, data)


@router.get(
    "/",
    response_model=PaginatedReportResponse,
    summary="List Reports",
    description="Returns a paginated list of reports. Supports optional filters on status, report_type, generated_by_user_id, start_date, and end_date.",
)
def list_reports_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    status_filter: Optional[ReportStatus] = Query(None),
    report_type_filter: Optional[ReportType] = Query(None),
    generated_by_user_id: Optional[str] = None,
    start_date: Optional[date] = None,
    end_date: Optional[date] = None,
    db: Session = Depends(get_db),
):
    return handler.list_reports(
        db,
        limit,
        offset,
        status_filter=status_filter,
        report_type_filter=report_type_filter,
        generated_by_user_id=generated_by_user_id,
        start_date=start_date,
        end_date=end_date,
    )


@router.get(
    "/{report_id}",
    response_model=ReportResponse,
    summary="Get Report By ID",
    description="Retrieves a single report by its unique identifier. Returns 404 if the report does not exist.",
)
def get_report_route(report_id: str, db: Session = Depends(get_db)):
    return handler.get_report_by_id(db, report_id)


@router.get(
    "/{report_id}/details",
    response_model=ReportDetailResponse,
    summary="Get Report Details",
    description="Retrieves a report with related user information (generated_by). Returns 404 if the report does not exist.",
)
def get_report_details_route(report_id: str, db: Session = Depends(get_db)):
    return handler.get_report_details(db, report_id)


@router.patch(
    "/{report_id}",
    response_model=ReportResponse,
    summary="Update Report",
    description="Updates an existing report record. Only provided fields are updated. Validates that the user exists if generated_by_user_id is updated. Returns 404 if the report does not exist.",
)
def update_report_route(report_id: str, data: ReportUpdate, db: Session = Depends(get_db)):
    return handler.update_report(db, report_id, data)


@router.delete(
    "/{report_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Delete Report",
    description="Deletes a report record. Returns 404 if the report does not exist. Returns 409 if the report is referenced by other records.",
)
def delete_report_route(report_id: str, db: Session = Depends(get_db)):
    handler.delete_report(db, report_id)


@router.post(
    "/{report_id}/generate",
    response_model=ReportResponse,
    summary="Generate Report",
    description="Triggers report generation for a report. Updates the report status to generating and then completed. Returns 400 if the report has already been generated. Returns 404 if the report does not exist.",
)
def generate_report_route(report_id: str, db: Session = Depends(get_db)):
    return handler.generate_report_service(db, report_id)


@router.get(
    "/{report_id}/download",
    summary="Download Report",
    description="Downloads the generated report file. Returns 404 if the report does not exist or the file is not available.",
)
def download_report_route(report_id: str, db: Session = Depends(get_db)):
    report = handler.get_report_by_id(db, report_id)
    if report.status != ReportStatus.COMPLETED or not report.file_path:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Report file not available. Report must be completed and have a file_path.",
        )
    return {"file_path": report.file_path, "message": "File download endpoint placeholder"}