"""Reports & Analytics — shared constants and the report-type security matrix.

Every report is identified by a URL-safe *slug*. The slug is the single source of
truth used for: request routing, the server-side allowlist (blocks path traversal /
header injection via ``{report_type}``), the minimum-role matrix, filenames, and the
human-readable title printed on PDF/Excel output.
"""
from __future__ import annotations

from src.core.constants import UserRole

# ── Report slugs ────────────────────────────────────────────────────────────
MONTHLY_SALES = "monthly-sales"
BURIAL_REGISTER = "burial-register"
CAPACITY = "capacity"
REVENUE_BY_SECTION = "revenue-by-section"
OUTSTANDING_BALANCES = "outstanding-balances"
SERVICE_SCHEDULE = "service-schedule"
AUDIT_LOG = "audit-log"
MEMORIAL_STATUS = "memorial-status"

# Server-side allowlist. Any {report_type} value outside this set is rejected with
# HTTP 422 *before* any query runs or any header/filename is built (OWASP A03/API8).
VALID_REPORT_TYPES: frozenset[str] = frozenset({
    MONTHLY_SALES,
    BURIAL_REGISTER,
    CAPACITY,
    REVENUE_BY_SECTION,
    OUTSTANDING_BALANCES,
    SERVICE_SCHEDULE,
    AUDIT_LOG,
    MEMORIAL_STATUS,
})

# Minimum role required per report type. Enforced server-side on BOTH the data
# endpoints and their PDF/Excel export variants (OWASP API5 — broken function-level
# authorization). Financial and compliance reports are gated to manager+.
REPORT_MIN_ROLES: dict[str, UserRole] = {
    MONTHLY_SALES: UserRole.STAFF,
    BURIAL_REGISTER: UserRole.STAFF,
    CAPACITY: UserRole.STAFF,
    REVENUE_BY_SECTION: UserRole.MANAGER,
    OUTSTANDING_BALANCES: UserRole.MANAGER,
    SERVICE_SCHEDULE: UserRole.STAFF,
    AUDIT_LOG: UserRole.MANAGER,
    MEMORIAL_STATUS: UserRole.STAFF,
}

# Human-readable titles for PDF/Excel headers and Excel sheet names.
REPORT_TITLES: dict[str, str] = {
    MONTHLY_SALES: "Monthly Sales Summary",
    BURIAL_REGISTER: "Burial Register",
    CAPACITY: "Capacity Report",
    REVENUE_BY_SECTION: "Revenue by Section",
    OUTSTANDING_BALANCES: "Outstanding Balances",
    SERVICE_SCHEDULE: "Service Schedule",
    AUDIT_LOG: "Audit Activity Log",
    MEMORIAL_STATUS: "Memorial Status",
}

# The bulk-CSV export combines several report types into one download; it is the most
# data-dense surface, so it requires manager+ and a mandatory bounded date range.
BULK_CSV_MIN_ROLE = UserRole.MANAGER

# ── Resource-consumption limits (OWASP API4 / ASVS V13.4.1) ─────────────────
# Any report date range wider than this is rejected with HTTP 422 to prevent
# unbounded queries and out-of-memory export generation.
MAX_DATE_RANGE_DAYS = 366

# Hard cap on the number of rows any single export may contain.
MAX_EXPORT_ROWS = 10_000

# ── Per-user export rate limit (OWASP API6 — sensitive business flow) ────────
# Sliding window: no more than EXPORT_RATE_LIMIT export requests per user per
# EXPORT_RATE_WINDOW_SECONDS. NOTE: the default limiter is in-process (per worker);
# for multi-worker production a Redis-backed limiter is recommended.
EXPORT_RATE_LIMIT = 30
EXPORT_RATE_WINDOW_SECONDS = 60
