"""
Fiscal Period Management API Routes

Endpoints for managing fiscal years, periods, and period-end processes
"""

from fastapi import APIRouter, Depends, HTTPException, Query, Path, Response
from sqlalchemy.orm import Session
from typing import List, Optional

from app.core.database import get_db
from app.core.security import get_current_user
from app.models.user import User
from app.models.fiscal_period import (
    FiscalYear, FiscalPeriod, PeriodEndStatement, PeriodCloseChecklist
)
from app.schemas.fiscal_period import (
    FiscalYearCreate, FiscalYearUpdate, FiscalYearResponse, FiscalYearWithPeriods,
    FiscalPeriodCreate, FiscalPeriodUpdate, FiscalPeriodResponse,
    PeriodActionRequest, PeriodEndStatementResponse, PeriodEndStatementDetail,
    GenerateStatementsRequest, PeriodCloseChecklistResponse, UpdateChecklistRequest,
    FiscalYearDashboard, PeriodSummary
)
from app.services.fiscal_period_service import FiscalPeriodService


router = APIRouter(prefix="/api/v1/fiscal-periods", tags=["Fiscal Periods"])


# ==================== FISCAL YEAR ENDPOINTS ====================

@router.post("/bootstrap", response_model=FiscalYearResponse)
def bootstrap_fiscal_year(
    branch_id: Optional[str] = Query(None, description="Branch ID (HQ branch if omitted)"),
    start_month: int = Query(1, ge=1, le=12, description="Fiscal year start month"),
    activate: bool = Query(True, description="Activate if year has started"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    Create the default fiscal year for today when none exists.
    Safe to call repeatedly — returns the existing year if already present.
    """
    service = FiscalPeriodService(db)
    effective_branch = branch_id or getattr(current_user, "branch_id", None)

    try:
        year = service.bootstrap_default_fiscal_year(
            branch_id=effective_branch,
            start_month=start_month,
            user_id=current_user.id,
            activate=activate,
        )
        if not year:
            raise HTTPException(status_code=500, detail="Could not bootstrap fiscal year")
        return year
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Bootstrap failed: {str(e)}")


@router.post("/years", response_model=FiscalYearResponse, status_code=201)
def create_fiscal_year(
    fiscal_year: FiscalYearCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Create a new fiscal year

    Creates a fiscal year with optional auto-generation of periods.
    Validates that dates don't overlap with existing fiscal years.

    **Permissions Required:** Finance Manager or higher
    """
    service = FiscalPeriodService(db)

    try:
        new_year = service.create_fiscal_year(
            year_name=fiscal_year.year_name,
            year_code=fiscal_year.year_code,
            start_date=fiscal_year.start_date,
            end_date=fiscal_year.end_date,
            period_type=fiscal_year.period_type_default,
            auto_create_periods=fiscal_year.auto_create_periods,
            branch_id=fiscal_year.branch_id,
            notes=fiscal_year.notes
        )

        return new_year

    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error creating fiscal year: {str(e)}")


@router.get("/years", response_model=List[FiscalYearResponse])
def list_fiscal_years(
    branch_id: Optional[str] = Query(None, description="Filter by branch"),
    is_active: Optional[bool] = Query(None, description="Filter by active status"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    List all fiscal years

    Returns all fiscal years with optional filtering.
    """
    query = db.query(FiscalYear)

    if branch_id:
        query = query.filter(FiscalYear.branch_id == branch_id)

    if is_active is not None:
        query = query.filter(FiscalYear.is_active == is_active)

    years = query.order_by(FiscalYear.start_date.desc()).all()
    return years


@router.get("/years/{year_id}", response_model=FiscalYearWithPeriods)
def get_fiscal_year(
    year_id: str = Path(..., description="Fiscal year ID"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Get a specific fiscal year with its periods

    Returns detailed information about a fiscal year including all its periods.
    """
    year = db.query(FiscalYear).filter(FiscalYear.id == year_id).first()

    if not year:
        raise HTTPException(status_code=404, detail="Fiscal year not found")

    return year


@router.patch("/years/{year_id}", response_model=FiscalYearResponse)
def update_fiscal_year(
    year_id: str,
    update_data: FiscalYearUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Update a fiscal year

    **Permissions Required:** Finance Manager
    """
    year = db.query(FiscalYear).filter(FiscalYear.id == year_id).first()

    if not year:
        raise HTTPException(status_code=404, detail="Fiscal year not found")

    # Update allowed fields
    update_dict = update_data.dict(exclude_unset=True)
    for field, value in update_dict.items():
        setattr(year, field, value)

    db.commit()
    db.refresh(year)

    return year


@router.post("/years/{year_id}/activate", response_model=FiscalYearResponse)
def activate_fiscal_year(
    year_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Activate a fiscal year

    Sets this year as the active fiscal year and deactivates others.

    **Permissions Required:** CFO
    """
    service = FiscalPeriodService(db)

    try:
        year = service.activate_fiscal_year(year_id, current_user.id)
        return year
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error activating fiscal year: {str(e)}")


@router.post("/years/{year_id}/opening-balances")
def apply_opening_balances(
    year_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Calculate and apply opening balances for a fiscal year.

    Uses prior year closing balances for balance sheet accounts and
    stores results in the OpeningBalance table.
    """
    service = FiscalPeriodService(db)

    try:
        return service.apply_opening_balances(year_id, current_user.id)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error applying opening balances: {str(e)}")


@router.get("/years/{year_id}/reports")
def get_year_end_reports(
    year_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """Get full year-end report package including tax reports."""
    service = FiscalPeriodService(db)

    try:
        return service.generate_year_end_reports(year_id)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error generating year-end reports: {str(e)}")


@router.post("/years/{year_id}/reports/save")
def save_year_end_reports(
    year_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """Persist year-end report package into saved statements."""
    service = FiscalPeriodService(db)

    try:
        return service.save_year_end_reports(year_id, current_user.id)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error saving year-end reports: {str(e)}")


@router.get("/years/{year_id}/reports/export")
def export_year_end_report(
    year_id: str,
    report_type: str = Query(..., description="Report type key"),
    format: str = Query("pdf", description="Export format: pdf or csv"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """Export a single year-end report as PDF or CSV."""
    service = FiscalPeriodService(db)

    try:
        content, filename, media_type = service.export_year_end_report(year_id, report_type, format)
        headers = {
            "Content-Disposition": f"attachment; filename=\"{filename}\""
        }
        return Response(content=content, media_type=media_type, headers=headers)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error exporting report: {str(e)}")


@router.post("/years/{year_id}/close", response_model=FiscalYearResponse)
def close_fiscal_year(
    year_id: str,
    action: PeriodActionRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Close a fiscal year

    Closes the fiscal year after ensuring all periods are closed.
    Optionally generates year-end financial statements.

    **Permissions Required:** CFO
    **Requires:** All periods must be hard-closed
    """
    service = FiscalPeriodService(db)

    try:
        year = service.close_fiscal_year(
            fiscal_year_id=year_id,
            user_id=current_user.id,
            generate_statements=action.generate_statements
        )
        return year
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/years/{year_id}/dashboard", response_model=FiscalYearDashboard)
def get_fiscal_year_dashboard(
    year_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Get fiscal year dashboard

    Returns summary dashboard view of fiscal year status and periods.
    """
    year = db.query(FiscalYear).filter(FiscalYear.id == year_id).first()

    if not year:
        raise HTTPException(status_code=404, detail="Fiscal year not found")

    # Get periods
    periods = db.query(FiscalPeriod).filter(
        FiscalPeriod.fiscal_year_id == year_id
    ).order_by(FiscalPeriod.period_number).all()

    # Build period summaries
    period_summaries = []
    total_transactions = 0
    open_count = 0
    closed_count = 0
    current_period_summary = None

    from datetime import date
    today = date.today()

    for period in periods:
        is_current = period.start_date <= today <= period.end_date

        summary = PeriodSummary(
            period_id=period.id,
            period_name=period.period_name,
            period_code=period.period_code,
            status=period.status.value if hasattr(period.status, "value") else period.status,
            is_locked=period.is_locked,
            is_current=is_current,
            transaction_count=period.transaction_count,
            total_debits=float(period.total_debits) if period.total_debits else None,
            total_credits=float(period.total_credits) if period.total_credits else None
        )

        period_summaries.append(summary)

        if period.transaction_count:
            total_transactions += period.transaction_count

        if period.status == "open":
            open_count += 1
        elif period.status in ["hard_closed", "locked"]:
            closed_count += 1

        if is_current:
            current_period_summary = summary

    return FiscalYearDashboard(
        fiscal_year=year,
        current_period=current_period_summary,
        periods=period_summaries,
        total_transactions=total_transactions,
        open_periods_count=open_count,
        closed_periods_count=closed_count
    )


@router.get("/years/{year_id}/periods/summary", response_model=List[PeriodSummary])
def get_fiscal_year_period_summaries(
    year_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Get period summaries with live debit/credit totals for a fiscal year.
    """
    service = FiscalPeriodService(db)
    return service.get_period_summaries(year_id)


# ==================== FISCAL PERIOD ENDPOINTS ====================

@router.post("/periods", response_model=FiscalPeriodResponse, status_code=201)
def create_fiscal_period(
    period: FiscalPeriodCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Create a new fiscal period manually

    Use this to add custom periods to a fiscal year.

    **Permissions Required:** Finance Manager
    """
    # Verify fiscal year exists
    fiscal_year = db.query(FiscalYear).filter(
        FiscalYear.id == period.fiscal_year_id
    ).first()

    if not fiscal_year:
        raise HTTPException(status_code=404, detail="Fiscal year not found")

    # Verify dates are within fiscal year
    if not (fiscal_year.start_date <= period.start_date <= fiscal_year.end_date):
        raise HTTPException(
            status_code=400,
            detail="Period start date must be within fiscal year"
        )

    if not (fiscal_year.start_date <= period.end_date <= fiscal_year.end_date):
        raise HTTPException(
            status_code=400,
            detail="Period end date must be within fiscal year"
        )

    # Create period
    new_period = FiscalPeriod(**period.dict())
    db.add(new_period)
    db.commit()
    db.refresh(new_period)

    return new_period


@router.get("/periods", response_model=List[FiscalPeriodResponse])
def list_fiscal_periods(
    fiscal_year_id: Optional[str] = Query(None, description="Filter by fiscal year"),
    status: Optional[str] = Query(None, description="Filter by status"),
    branch_id: Optional[str] = Query(None, description="Filter by branch"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    List fiscal periods

    Returns all periods with optional filtering.
    """
    query = db.query(FiscalPeriod)

    if fiscal_year_id:
        query = query.filter(FiscalPeriod.fiscal_year_id == fiscal_year_id)

    if status:
        query = query.filter(FiscalPeriod.status == status)

    if branch_id:
        query = query.filter(FiscalPeriod.branch_id == branch_id)

    periods = query.order_by(
        FiscalPeriod.fiscal_year_id,
        FiscalPeriod.period_number
    ).all()

    return periods


@router.get("/periods/current", response_model=FiscalPeriodResponse)
def get_current_period(
    branch_id: Optional[str] = Query(None, description="Branch ID"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Get the current active period for today's date
    """
    service = FiscalPeriodService(db)
    period = service.get_current_period(branch_id)

    if not period:
        raise HTTPException(status_code=404, detail="No active period found for current date")

    stats = service._calculate_period_statistics(period)
    period.transaction_count = stats['transaction_count']
    period.total_debits = stats['total_debits']
    period.total_credits = stats['total_credits']

    return period


@router.get("/periods/{period_id}", response_model=FiscalPeriodResponse)
def get_fiscal_period(
    period_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Get a specific fiscal period
    """
    period = db.query(FiscalPeriod).filter(FiscalPeriod.id == period_id).first()

    if not period:
        raise HTTPException(status_code=404, detail="Period not found")

    service = FiscalPeriodService(db)
    stats = service._calculate_period_statistics(period)
    period.transaction_count = stats['transaction_count']
    period.total_debits = stats['total_debits']
    period.total_credits = stats['total_credits']

    return period


@router.patch("/periods/{period_id}", response_model=FiscalPeriodResponse)
def update_fiscal_period(
    period_id: str,
    update_data: FiscalPeriodUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Update a fiscal period

    **Permissions Required:** Finance Manager
    """
    period = db.query(FiscalPeriod).filter(FiscalPeriod.id == period_id).first()

    if not period:
        raise HTTPException(status_code=404, detail="Period not found")

    update_dict = update_data.dict(exclude_unset=True)
    for field, value in update_dict.items():
        setattr(period, field, value)

    db.commit()
    db.refresh(period)

    return period


# ==================== PERIOD ACTIONS ====================

@router.post("/periods/{period_id}/open", response_model=FiscalPeriodResponse)
def open_period(
    period_id: str,
    action: PeriodActionRequest = PeriodActionRequest(),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Open a period for transactions

    **Permissions Required:** Finance Manager
    """
    service = FiscalPeriodService(db)

    try:
        period = service.open_period(
            period_id=period_id,
            user_id=current_user.id,
            create_checklist=True
        )
        return period
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/periods/{period_id}/soft-close", response_model=FiscalPeriodResponse)
def soft_close_period(
    period_id: str,
    action: PeriodActionRequest = PeriodActionRequest(),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Soft close a period

    Period can be reopened by Finance Manager.

    **Permissions Required:** Accountant
    """
    service = FiscalPeriodService(db)

    try:
        period = service.soft_close_period(
            period_id=period_id,
            user_id=current_user.id,
            notes=action.notes
        )
        return period
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/periods/{period_id}/hard-close", response_model=FiscalPeriodResponse)
def hard_close_period(
    period_id: str,
    action: PeriodActionRequest = PeriodActionRequest(),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Hard close a period

    Generates period-end statements and locks the period.
    Requires CFO approval to reopen.

    **Permissions Required:** Finance Manager
    **Requires:** Period-end checklist must be complete
    """
    service = FiscalPeriodService(db)

    try:
        period = service.hard_close_period(
            period_id=period_id,
            user_id=current_user.id,
            generate_statements=action.generate_statements,
            notes=action.notes
        )
        return period
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/periods/{period_id}/reopen", response_model=FiscalPeriodResponse)
def reopen_period(
    period_id: str,
    action: PeriodActionRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Reopen a closed period

    **Permissions Required:**
    - Soft-closed: Finance Manager
    - Hard-closed: CFO

    **Requires:** Reason must be provided
    """
    if not action.reason:
        raise HTTPException(status_code=400, detail="Reason is required to reopen a period")

    service = FiscalPeriodService(db)

    try:
        period = service.reopen_period(
            period_id=period_id,
            user_id=current_user.id,
            reason=action.reason
        )
        return period
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/periods/{period_id}/lock", response_model=FiscalPeriodResponse)
def lock_period(
    period_id: str,
    action: PeriodActionRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Lock a period (prevents any changes)

    Used for audit compliance.

    **Permissions Required:** CFO
    """
    service = FiscalPeriodService(db)

    try:
        period = service.lock_period(
            period_id=period_id,
            user_id=current_user.id,
            reason=action.reason or "Audit lock"
        )
        return period
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/periods/{period_id}/unlock", response_model=FiscalPeriodResponse)
def unlock_period(
    period_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Unlock a locked period

    **Permissions Required:** CFO
    """
    service = FiscalPeriodService(db)

    try:
        period = service.unlock_period(
            period_id=period_id,
            user_id=current_user.id
        )
        return period
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


# ==================== PERIOD-END STATEMENTS ====================

@router.post("/periods/{period_id}/statements", response_model=List[PeriodEndStatementResponse])
def generate_period_statements(
    period_id: str,
    request: GenerateStatementsRequest = GenerateStatementsRequest(),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Generate period-end financial statements

    Generates and saves financial statements for the period.

    **Permissions Required:** Finance Manager
    """
    service = FiscalPeriodService(db)

    try:
        statements = service.generate_period_statements(
            period_id=period_id,
            user_id=current_user.id,
            statement_types=request.statement_types
        )
        return statements
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/periods/{period_id}/statements", response_model=List[PeriodEndStatementResponse])
def list_period_statements(
    period_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    List all statements for a period
    """
    statements = db.query(PeriodEndStatement).filter(
        PeriodEndStatement.fiscal_period_id == period_id
    ).order_by(PeriodEndStatement.generated_date.desc()).all()

    return statements


@router.get("/statements/{statement_id}", response_model=PeriodEndStatementDetail)
def get_statement_detail(
    statement_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Get detailed statement including data
    """
    statement = db.query(PeriodEndStatement).filter(
        PeriodEndStatement.id == statement_id
    ).first()

    if not statement:
        raise HTTPException(status_code=404, detail="Statement not found")

    return statement


# ==================== PERIOD-END CHECKLIST ====================

@router.get("/periods/{period_id}/checklist", response_model=PeriodCloseChecklistResponse)
def get_period_checklist(
    period_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Get period-end checklist for a period
    """
    checklist = db.query(PeriodCloseChecklist).filter(
        PeriodCloseChecklist.fiscal_period_id == period_id,
        PeriodCloseChecklist.is_template == False
    ).first()

    if not checklist:
        raise HTTPException(status_code=404, detail="Checklist not found")

    return checklist


@router.put("/periods/{period_id}/checklist", response_model=PeriodCloseChecklistResponse)
def update_period_checklist(
    period_id: str,
    update: UpdateChecklistRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Update period-end checklist

    Updates checklist items and recalculates completion percentage.

    **Permissions Required:** Accountant
    """
    checklist = db.query(PeriodCloseChecklist).filter(
        PeriodCloseChecklist.fiscal_period_id == period_id,
        PeriodCloseChecklist.is_template == False
    ).first()

    if not checklist:
        raise HTTPException(status_code=404, detail="Checklist not found")

    # Update checklist items
    items_dict = [item.dict() for item in update.checklist_items]
    checklist.checklist_items = items_dict

    # Recalculate completion
    total = len(items_dict)
    completed = sum(1 for item in items_dict if item.get('status') == 'completed')

    checklist.total_items = total
    checklist.completed_items = completed
    checklist.completion_percentage = (completed / total * 100) if total > 0 else 0

    # Check if all required items are complete
    required_items = [item for item in items_dict if item.get('required', True)]
    required_completed = sum(
        1 for item in required_items
        if item.get('status') == 'completed'
    )

    checklist.is_complete = (required_completed == len(required_items))

    if checklist.is_complete and not checklist.completed_date:
        from datetime import datetime
        checklist.completed_date = datetime.utcnow()

    db.commit()
    db.refresh(checklist)

    return checklist


# ==================== HISTORICAL REPORTS & COMPARISON ====================

@router.get("/saved-reports")
def list_saved_reports(
    fiscal_year_id: Optional[str] = Query(None, description="Filter by fiscal year"),
    statement_type: Optional[str] = Query(None, description="Filter by statement type"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """List all saved period-end financial statement snapshots across all fiscal years."""
    service = FiscalPeriodService(db)
    try:
        return service.list_saved_reports(fiscal_year_id=fiscal_year_id, statement_type=statement_type)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/saved-reports/{statement_id}")
def get_saved_report(
    statement_id: str,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """Get a single saved report with its full data payload."""
    service = FiscalPeriodService(db)
    try:
        return service.get_saved_report(statement_id)
    except ValueError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/saved-reports/{statement_id}/export")
def export_saved_report(
    statement_id: str,
    format: str = Query("pdf", description="Export format: pdf, csv, xlsx"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """Export a saved period-end report as PDF, CSV, or XLSX."""
    service = FiscalPeriodService(db)
    try:
        content, filename, media_type = service.export_saved_report(statement_id, format)
        headers = {"Content-Disposition": f'attachment; filename="{filename}"'}
        return Response(content=content, media_type=media_type, headers=headers)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/comparison")
def compare_fiscal_years(
    year_ids: str = Query(..., description="Comma-separated fiscal year IDs to compare"),
    report_type: str = Query("income_statement", description="income_statement | balance_sheet | trial_balance"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    Compare a financial report side-by-side across multiple fiscal years.
    Returns per-year data plus variance analysis between earliest and latest year.
    """
    service = FiscalPeriodService(db)
    ids = [yid.strip() for yid in year_ids.split(",") if yid.strip()]
    if len(ids) < 2:
        raise HTTPException(status_code=400, detail="Provide at least 2 fiscal year IDs to compare")
    try:
        return service.compare_fiscal_years(ids, report_type)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/benchmarks")
def get_benchmarks(
    branch_id: Optional[str] = Query(None, description="Filter by branch"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    Return year-over-year KPI benchmarks for all closed/active fiscal years.
    Includes revenue, net income, expense ratio, net margin, and YoY growth rates.
    """
    service = FiscalPeriodService(db)
    try:
        return service.get_benchmarks(branch_id=branch_id)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/year-end-workflow")
def year_end_workflow(
    fiscal_year_id: str = Query(..., description="Fiscal year to close"),
    next_year_id: Optional[str] = Query(None, description="Next fiscal year to apply opening balances"),
    hard_close_remaining: bool = Query(False, description="Hard-close any remaining open/soft-closed periods"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    Execute the full year-end close workflow in one call:
    1. Optionally hard-close any still-open periods
    2. Close the fiscal year
    3. Save year-end report snapshots (balance sheet, P&L, trial balance, etc.)
    4. Optionally apply opening balances to the next fiscal year
    """
    service = FiscalPeriodService(db)
    try:
        return service.year_end_workflow(
            fiscal_year_id=fiscal_year_id,
            user_id=current_user.id,
            next_year_id=next_year_id,
            hard_close_remaining=hard_close_remaining,
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
