"""Phase 5.10 — Financial Reporting API."""
from __future__ import annotations

from uuid import UUID

from fastapi import APIRouter, Depends
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_db, require_tenant
from app.core.security import get_current_user
from app.models.reporting import Dashboard, ReportTemplate
from app.models.types import ReportExportFormat, ReportType
from app.repositories.base import TenantBaseRepository
from app.services.reporting_service import FinancialReportEngine
from shared.security import CurrentUser

router = APIRouter()


class ReportTemplateCreate(BaseModel):
    name: str
    report_type: ReportType
    template_config: str


class DashboardCreate(BaseModel):
    name: str
    dashboard_type: str
    description: str | None = None


class ExportRequest(BaseModel):
    export_format: ReportExportFormat = ReportExportFormat.JSON


class ReportTemplateRepo(TenantBaseRepository[ReportTemplate]):
    model = ReportTemplate


class DashboardRepo(TenantBaseRepository[Dashboard]):
    model = Dashboard


@router.post("/trial-balance")
async def generate_trial_balance(
    fiscal_period_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    engine = FinancialReportEngine(db)
    report = await engine.generate_trial_balance_report(tenant_id, fiscal_period_id, generated_by=user.user_id)
    await db.commit()
    return {"id": str(report.id), "report_type": report.report_type.value, "data": report.report_data}


@router.post("/balance-sheet")
async def generate_balance_sheet(
    fiscal_period_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    engine = FinancialReportEngine(db)
    report = await engine.generate_balance_sheet(tenant_id, fiscal_period_id, generated_by=user.user_id)
    await db.commit()
    return {"id": str(report.id), "data": report.report_data}


@router.post("/income-statement")
async def generate_income_statement(
    fiscal_period_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    engine = FinancialReportEngine(db)
    report = await engine.generate_income_statement(tenant_id, fiscal_period_id, generated_by=user.user_id)
    await db.commit()
    return {"id": str(report.id), "data": report.report_data}


@router.post("/subsidiary-ledger")
async def generate_subsidiary_ledger(
    fiscal_period_id: UUID,
    account_id: UUID | None = None,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    """گزارش معین — مانده/گردش حساب‌های سطح معین از داده دفتر."""
    engine = FinancialReportEngine(db)
    report = await engine.generate_level_ledger_report(
        tenant_id,
        fiscal_period_id,
        mode="subsidiary",
        account_id=account_id,
        generated_by=user.user_id,
    )
    await db.commit()
    return {"id": str(report.id), "report_type": report.report_type.value, "data": report.report_data}


@router.post("/detail-ledger")
async def generate_detail_ledger(
    fiscal_period_id: UUID,
    account_id: UUID | None = None,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    """گزارش تفصیلی — مانده/گردش حساب‌های سطح تفصیلی از داده دفتر."""
    engine = FinancialReportEngine(db)
    report = await engine.generate_level_ledger_report(
        tenant_id,
        fiscal_period_id,
        mode="detail",
        account_id=account_id,
        generated_by=user.user_id,
    )
    await db.commit()
    return {"id": str(report.id), "report_type": report.report_type.value, "data": report.report_data}


@router.post("/analytical")
async def generate_analytical(
    fiscal_period_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    engine = FinancialReportEngine(db)
    report = await engine.generate_analytical_report(
        tenant_id, fiscal_period_id, generated_by=user.user_id
    )
    await db.commit()
    return {"id": str(report.id), "report_type": report.report_type.value, "data": report.report_data}


@router.post("/cash-flow")
async def generate_cash_flow(
    fiscal_period_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    engine = FinancialReportEngine(db)
    report = await engine.generate_cash_flow_report(
        tenant_id, fiscal_period_id, generated_by=user.user_id
    )
    await db.commit()
    return {"id": str(report.id), "report_type": report.report_type.value, "data": report.report_data}


@router.post("/equity-statement")
async def generate_equity_statement(
    fiscal_period_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    engine = FinancialReportEngine(db)
    report = await engine.generate_equity_statement(
        tenant_id, fiscal_period_id, generated_by=user.user_id
    )
    await db.commit()
    return {"id": str(report.id), "report_type": report.report_type.value, "data": report.report_data}


@router.post("/reports/{report_id}/export")
async def export_report(
    report_id: UUID,
    body: ExportRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    engine = FinancialReportEngine(db)
    export = await engine.export_report(tenant_id, report_id, body.export_format, exported_by=user.user_id)
    await db.commit()
    return {"id": str(export.id), "format": export.export_format.value, "file_path": export.file_path}


@router.post("/dashboards")
async def create_dashboard(
    body: DashboardCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    repo = DashboardRepo(db)
    entity = Dashboard(tenant_id=tenant_id, **body.model_dump())
    await repo.add(entity)
    await db.commit()
    return {"id": str(entity.id)}


@router.post("/templates")
async def create_report_template(
    body: ReportTemplateCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    repo = ReportTemplateRepo(db)
    entity = ReportTemplate(tenant_id=tenant_id, **body.model_dump())
    await repo.add(entity)
    await db.commit()
    return {"id": str(entity.id)}
