"""Extended Finance API endpoints."""
from datetime import date as date_cls

from rest_framework.authentication import TokenAuthentication
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from procurement.models import PurchaseOrder
from sales_and_marketing.models import CustomerOrder, SalesQuotation

from .finance_extended import (
    build_batch_payment_candidates,
    build_exchange_loss_report,
    build_pl_month_on_month,
    build_vat_registers,
    build_withholding_register,
    dispatch_due_reminders,
    execute_batch_payment,
    export_kra_vat_csv,
    export_kra_whvat_csv,
    generate_due_reminders,
    generate_withholding_entries,
    get_exchange_rate,
    import_mpesa_csv,
    log_finance_audit,
    match_vendor_invoice_3way,
    post_fx_revaluation,
    reconcile_mpesa_report,
    run_depreciation_for_period,
    run_year_end_close,
    update_tax_loss_carry_forward,
)
from .models import (
    CurrencyExchangeRate,
    FinanceAuditLog,
    MpesaApiConfig,
    Refund,
    ScheduledPaymentReminder,
    TaxLossCarryForward,
    VendorInvoice,
    WithholdingTaxEntry,
)
from .posting_hooks import post_vendor_invoice
from .views_accounting import _finance_auth, _require_finance_staff, _require_finance_write


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_currency_exchange_rates(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        rates = CurrencyExchangeRate.objects.filter(
            company_branch=staff.company_branch,
        ).order_by("-rate_date")[:200]
        payload["rates"] = [{
            "rate_id": str(r.id),
            "from_currency": r.from_currency,
            "to_currency": r.to_currency,
            "rate_date": r.rate_date.isoformat(),
            "exchange_rate": str(r.exchange_rate),
            "notes": r.notes,
        } for r in rates]
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def save_currency_exchange_rate(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        data = request.data
        rate, _ = CurrencyExchangeRate.objects.update_or_create(
            company_branch=staff.company_branch,
            from_currency=data.get("from_currency", "usd").lower(),
            to_currency=data.get("to_currency", "kes").lower(),
            rate_date=date_cls.fromisoformat(data["rate_date"]),
            defaults={
                "exchange_rate": data.get("exchange_rate", 1),
                "notes": data.get("notes", ""),
                "created_by": staff,
            },
        )
        log_finance_audit(staff.company_branch, staff, "currency_rate", rate.id, "saved")
        payload["rate_id"] = str(rate.id)
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_exchange_loss_report(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        payload["report"] = build_exchange_loss_report(
            staff.company_branch, request.data.get("as_of_date"))
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def generate_pl_month_on_month(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        payload["report"] = build_pl_month_on_month(
            staff.company_branch,
            request.data["date_from"],
            request.data["date_to"],
        )
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def close_fiscal_year(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        result = run_year_end_close(
            staff.company_branch,
            staff,
            request.data["period_id"],
            request.data["retained_earnings_account_id"],
        )
        if result.get("error"):
            return Response({"message": "false", "payload": result}, status=400)
        net = result.get("net_income", 0)
        update_tax_loss_carry_forward(
            staff.company_branch,
            date_cls.today().year,
            net,
        )
        payload.update(result)
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_finance_audit_logs(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        logs = FinanceAuditLog.objects.filter(
            company_branch=staff.company_branch,
        ).select_related("actor")[:300]
        payload["audit_logs"] = [{
            "log_id": str(l.id),
            "entity_type": l.entity_type,
            "entity_id": l.entity_id,
            "action": l.action,
            "notes": l.notes,
            "actor_name": f"{l.actor.first_name} {l.actor.last_name}" if l.actor else "",
            "created_on": l.created_on.isoformat(),
        } for l in logs]
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def create_vendor_invoice(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        data = request.data
        po = PurchaseOrder.objects.get(id=int(data["purchase_order_id"]))
        inv = VendorInvoice.objects.create(
            company_branch=staff.company_branch,
            purchase_order=po,
            supplier_invoice_number=data.get("supplier_invoice_number", ""),
            invoice_date=date_cls.fromisoformat(data["invoice_date"]),
            invoice_amount=data.get("invoice_amount", "0.00"),
            attachment_reference=data.get("attachment_reference", ""),
            account_manager_id=data.get("account_manager_id", ""),
            created_by=staff,
        )
        inv = match_vendor_invoice_3way(inv)
        gl_post = post_vendor_invoice(staff.company_branch, staff, inv)
        log_finance_audit(staff.company_branch, staff, "vendor_invoice", inv.id, "created")
        payload["vendor_invoice"] = {
            "vendor_invoice_id": str(inv.id),
            "match_status": inv.match_status,
            "match_notes": inv.match_notes,
            "po_amount": inv.po_amount,
            "received_amount": inv.received_amount,
            "invoice_amount": inv.invoice_amount,
        }
        payload["gl_posting"] = gl_post
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_vendor_invoices(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        invoices = VendorInvoice.objects.filter(
            company_branch=staff.company_branch, recycle_bin=False,
        ).select_related("purchase_order").order_by("-created_on")[:200]
        payload["vendor_invoices"] = [{
            "vendor_invoice_id": str(v.id),
            "supplier_invoice_number": v.supplier_invoice_number,
            "invoice_date": v.invoice_date.isoformat(),
            "invoice_amount": v.invoice_amount,
            "po_amount": v.po_amount,
            "received_amount": v.received_amount,
            "match_status": v.match_status,
            "match_notes": v.match_notes,
            "purchase_order_number": v.purchase_order.purchase_order_number if v.purchase_order else "",
        } for v in invoices]
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_vat_registers(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        registers = build_vat_registers(
            staff.company_branch,
            request.data["date_from"],
            request.data["date_to"],
        )
        payload["registers"] = registers
        if request.data.get("export_csv"):
            payload["csv"] = export_kra_vat_csv(registers)
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def import_mpesa_statement(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        result = import_mpesa_csv(
            staff.company_branch,
            request.data["account_id"],
            request.data["csv_text"],
            staff,
        )
        payload.update(result)
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_mpesa_reconciliation(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        payload["report"] = reconcile_mpesa_report(staff.company_branch)
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def run_depreciation_schedule(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        result = run_depreciation_for_period(
            staff.company_branch,
            staff,
            request.data["period_month"],
            request.data["expense_account_id"],
            request.data["accumulated_depreciation_account_id"],
        )
        payload.update(result)
        log_finance_audit(staff.company_branch, staff, "depreciation", request.data["period_month"], "posted")
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_tax_loss_carry_forwards(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        rows = TaxLossCarryForward.objects.filter(
            company_branch=staff.company_branch,
        ).order_by("-tax_year")
        payload["tax_losses"] = [{
            "tax_year": r.tax_year,
            "assessed_loss": float(r.assessed_loss),
            "utilized": float(r.utilized),
            "balance": float(r.balance),
            "notes": r.notes,
        } for r in rows]
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def generate_payment_reminders(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        payload.update(generate_due_reminders(staff.company_branch))
        log_finance_audit(staff.company_branch, staff, "reminders", "batch", "generated")
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_pending_refunds(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        refunds = Refund.objects.filter(
            recycle_bin=False,
            refund_approved=False,
        ).select_related("payment", "order_item_return").order_by("-created_on")[:100]
        payload["pending_refunds"] = [{
            "refund_id": str(r.id),
            "refund_amount": r.refund_amount,
            "payment_number": r.payment.payment_number if r.payment else "",
            "created_on": r.created_on.isoformat(),
        } for r in refunds]
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def approve_refund(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        refund = Refund.objects.get(id=int(request.data["refund_id"]))
        refund.refund_approved = True
        refund.last_updated_by = staff
        refund.save()
        log_finance_audit(staff.company_branch, staff, "refund", refund.id, "approved")
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def reject_refund(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        refund = Refund.objects.get(id=int(request.data["refund_id"]))
        refund.recycle_bin = True
        refund.last_updated_by = staff
        refund.save()
        log_finance_audit(staff.company_branch, staff, "refund", refund.id, "rejected",
                          request.data.get("reason", ""))
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def convert_quotation_to_order(request):
    payload = {}
    try:
        company_profile, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        quotation = SalesQuotation.objects.get(
            id=int(request.data["quotation_id"]),
            company_branch=staff.company_branch,
        )
        if CustomerOrder.objects.filter(source_quotation=quotation, recycle_bin=False).exists():
            return Response({"message": "false", "payload": {"error": "Quotation already converted"}}, status=400)

        from sales_and_marketing.models import CustomerOrderItem, SalesQuotationItem
        from decimal import Decimal

        order = CustomerOrder.objects.create(
            company_branch=staff.company_branch,
            customer_profile=quotation.customer_profile,
            source_quotation=quotation,
            customer_order_description=f"From quotation {quotation.sales_quotation_number}",
            customer_order_total_net_value=quotation.quotation_net_value,
            customer_order_total_gross_value=quotation.quotation_net_value,
            expected_delivery_date=date_cls.today(),
            created_by=staff,
            last_updated_by=staff,
        )

        # Copy quotation line items onto the new order and recompute totals.
        def _d(v):
            return Decimal(str(v or "0").replace(",", "") or "0")

        gross_total = Decimal("0")
        discount_total = Decimal("0")
        net_total = Decimal("0")
        items_copied = 0
        for qi in SalesQuotationItem.objects.filter(sales_quotation=quotation):
            CustomerOrderItem.objects.create(
                customer_order=order,
                product=qi.product,
                quantity=qi.quantity,
                price_per_item=qi.price_per_item,
                discount_per_item=qi.discount_per_item,
                gross_subtotal=qi.gross_subtotal,
                total_discount=qi.total_discount,
                net_subtotal=qi.net_subtotal,
            )
            gross_total += _d(qi.gross_subtotal)
            discount_total += _d(qi.total_discount)
            net_total += _d(qi.net_subtotal)
            items_copied += 1

        if items_copied:
            order.customer_order_total_gross_value = str(gross_total.quantize(Decimal("0.01")))
            order.customer_order_total_discount = str(discount_total.quantize(Decimal("0.01")))
            order.customer_order_total_net_value = str(net_total.quantize(Decimal("0.01")))
            order.save()

        log_finance_audit(staff.company_branch, staff, "customer_order", order.id, "converted_from_quotation",
                          after={"quotation_id": str(quotation.id), "items_copied": items_copied})
        payload["customer_order_id"] = str(order.id)
        payload["customer_order_number"] = order.customer_order_number
        payload["source_quotation_number"] = quotation.sales_quotation_number
        payload["items_copied"] = items_copied
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


# ---------------------------------------------------------------------------
# FX REVALUATION
# ---------------------------------------------------------------------------

@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def post_fx_revaluation_view(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        result = post_fx_revaluation(
            staff.company_branch, staff,
            request.data.get("as_of_date"),
            request.data["gain_loss_account_id"],
        )
        payload.update(result)
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


# ---------------------------------------------------------------------------
# WITHHOLDING TAX (WHVAT / WHT)
# ---------------------------------------------------------------------------

@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_withholding_register(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        register = build_withholding_register(
            staff.company_branch,
            request.data.get("date_from"),
            request.data.get("date_to"),
            request.data.get("tax_type") or None,
        )
        payload["register"] = register
        if request.data.get("export_csv"):
            payload["csv"] = export_kra_whvat_csv(register)
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def generate_withholding_register(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        created = generate_withholding_entries(
            staff.company_branch,
            request.data["date_from"],
            request.data["date_to"],
            float(request.data.get("rate", 2.0)),
        )
        log_finance_audit(staff.company_branch, staff, "withholding", "batch", "generated", f"{created} entries")
        payload["created"] = created
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def update_withholding_entry(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        entry = WithholdingTaxEntry.objects.get(
            id=int(request.data["entry_id"]), company_branch=staff.company_branch)
        if "certificate_number" in request.data:
            entry.certificate_number = request.data["certificate_number"]
        if "supplier_pin" in request.data:
            entry.supplier_pin = request.data["supplier_pin"]
        if request.data.get("status"):
            entry.status = request.data["status"]
        entry.save()
        log_finance_audit(staff.company_branch, staff, "withholding", entry.id, "updated")
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


# ---------------------------------------------------------------------------
# BATCH / SCHEDULED SUPPLIER PAYMENTS
# ---------------------------------------------------------------------------

@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_batch_payment_candidates(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        payload["candidates"] = build_batch_payment_candidates(staff.company_branch)
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def run_batch_payment(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        result = execute_batch_payment(
            staff.company_branch, staff,
            request.data.get("payment_date"),
            request.data["source_account_id"],
            request.data.get("lines", []),
            request.data.get("payable_account_id"),
            request.data.get("notes", ""),
        )
        if result.get("error"):
            return Response({"message": "false", "payload": result}, status=400)
        payload.update(result)
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


# ---------------------------------------------------------------------------
# M-PESA DARAJA API
# ---------------------------------------------------------------------------

@api_view(["POST"])
@authentication_classes([])
@permission_classes([])
def mpesa_c2b_confirmation(request):
    """Public Daraja C2B confirmation callback. Resolves branch by ShortCode."""
    try:
        from .mpesa_daraja import ingest_c2b_confirmation
        data = request.data
        short_code = str(data.get("BusinessShortCode") or data.get("ShortCode") or "")
        cfg = MpesaApiConfig.objects.filter(short_code=short_code, is_active=True).first()
        if not cfg:
            cfg = MpesaApiConfig.objects.filter(is_active=True).first()
        if cfg:
            ingest_c2b_confirmation(cfg.company_branch, cfg, data)
        # Daraja expects this acknowledgement shape regardless.
        return Response({"ResultCode": 0, "ResultDesc": "Accepted"}, status=200)
    except Exception as e:
        print(e)
        return Response({"ResultCode": 0, "ResultDesc": "Accepted"}, status=200)


# ---------------------------------------------------------------------------
# REMINDER EMAIL DISPATCH
# ---------------------------------------------------------------------------

@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def dispatch_payment_reminders(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_write(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        payload.update(dispatch_due_reminders(staff.company_branch))
        log_finance_audit(staff.company_branch, staff, "reminders", "dispatch", "emailed",
                          f"{payload.get('sent', 0)} sent")
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def get_payment_reminders(request):
    payload = {}
    try:
        _, staff = _finance_auth(request)
        if not _require_finance_staff(staff):
            return Response({"message": "false", "payload": payload}, status=401)
        reminders = ScheduledPaymentReminder.objects.filter(
            company_branch=staff.company_branch).order_by("-created_on")[:300]
        payload["reminders"] = [{
            "reminder_id": str(r.id),
            "reminder_type": r.reminder_type,
            "entity_type": r.entity_type,
            "recipient_email": r.recipient_email,
            "due_date": r.due_date.isoformat() if r.due_date else "",
            "amount_due": r.amount_due,
            "sent": r.sent,
            "sent_on": r.sent_on.isoformat() if r.sent_on else "",
            "last_error": r.last_error,
        } for r in reminders]
        return Response({"message": "true", "payload": payload}, status=200)
    except Exception as e:
        print(e)
        return Response({"message": "false", "payload": payload}, status=500)
