import { type FormEvent, useCallback, useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { useSchoolYearOptions } from '../../hooks/useSchoolYearOptions'
import {
  downloadFinancialReportCsv,
  fetchFinancialReportDetailed,
  type FinancialDetailedJson,
} from '../../api/paymentManagement'

function fmt(n: number): string {
  return `$${Number(n || 0).toFixed(2)}`
}

type InvRow = {
  invoice_number?: string
  parent_name?: string
  school_year?: string
  total_amount?: number
  id?: number
  parent_id?: number
}

export function FinancialReportPage() {
  const [schoolYear, setSchoolYear] = useState('')
  const [dateFrom, setDateFrom] = useState('')
  const [dateTo, setDateTo] = useState('')
  const [schoolYears, setSchoolYears] = useState<string[]>([])
  const [data, setData] = useState<FinancialDetailedJson | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [lastRef, setLastRef] = useState<string | null>(null)
  const { options, selectedYear: defaultYear } = useSchoolYearOptions({
    legacyYears: schoolYears,
    preferredYear: schoolYear,
  })

  const hydrate = useCallback(() => {
    setLoading(true)
    setError(null)
    fetchFinancialReportDetailed({
      school_year: schoolYear || undefined,
      date_from: dateFrom || undefined,
      date_to: dateTo || undefined,
    })
      .then((d) => {
        setData(d)
        const ys = (d as { schoolYears?: string[] }).schoolYears
        if (Array.isArray(ys) && ys.length) setSchoolYears(ys)
        setLastRef(new Date().toLocaleString())
      })
      .catch((e: unknown) =>
        setError(e instanceof ApiHttpError ? e.message : 'Failed to load report.'),
      )
      .finally(() => setLoading(false))
  }, [schoolYear, dateFrom, dateTo])

  useEffect(() => {
    hydrate()
  }, [hydrate])

  const invoiceRows = useMemo(() => {
    const invoices = (data?.invoices ?? []) as InvRow[]
    const payments = data?.payments ?? []
    const refunds = data?.refunds ?? []
    const discounts = data?.discounts ?? []
    const breakdown = data?.paymentBreakdown ?? {}

    return invoices.map((inv) => {
      const id = Number(inv.id ?? 0)
      const payMatches = payments.filter(
        (p) => Number((p as { invoice_id?: number }).invoice_id) === id,
      )
      const pay = payMatches[0] as { paid_amount?: number } | undefined
      const paid = Number(pay?.paid_amount ?? 0)
      const bd = breakdown[id] ?? {}
      const cash = Number(bd.cash ?? 0)
      const credit = Number(bd.credit ?? 0)
      const chk = Number(bd.check ?? 0)
      const refMatches = refunds.filter(
        (r) => Number((r as { invoice_id?: number }).invoice_id) === id,
      )
      const ref = refMatches[0] as { total_refunded?: number } | undefined
      const refunded = Number(ref?.total_refunded ?? 0)
      const discMatches = discounts.filter(
        (d) => Number((d as { invoice_id?: number }).invoice_id) === id,
      )
      const disc = discMatches[0] as { discount_amount?: number } | undefined
      const discounted = Number(disc?.discount_amount ?? 0)
      const totalAmount = Number(inv.total_amount ?? 0)
      let balance = totalAmount - discounted - paid - refunded
      if (balance < 0 || !Number.isFinite(balance)) balance = 0
      let status = 'Unpaid'
      let statusClass = 'bg-danger'
      if (balance <= 0.00001) {
        status = 'Paid'
        statusClass = 'bg-success'
      } else if (paid > 0.00001) {
        status = 'Partially Paid'
        statusClass = 'bg-warning text-dark'
      }
      return {
        inv,
        paid,
        cash,
        credit,
        check: chk,
        balance,
        refunded,
        discounted,
        totalAmount,
        status,
        statusClass,
      }
    })
  }, [data])

  function onFilterSubmit(e: FormEvent) {
    e.preventDefault()
    hydrate()
  }

  async function onDownloadCsv() {
    try {
      await downloadFinancialReportCsv({
        school_year: schoolYear || undefined,
        date_from: dateFrom || undefined,
        date_to: dateTo || undefined,
      })
    } catch (e: unknown) {
      setError(e instanceof ApiHttpError ? e.message : 'CSV download failed.')
    }
  }

  const pt = data?.paymentTotals ?? {}
  const totalCash = Number(pt.total_cash ?? 0)
  const totalCredit = Number(pt.total_credit ?? 0)
  const totalCheck = Number(pt.total_check ?? 0)
  const grandTotal = Number(pt.total_all ?? totalCash + totalCredit + totalCheck)

  return (
    <div className="container-fluid mt-4">
      <h2 className="text-center mt-4 mb-3">Detailed Financial Report</h2>

      <form
        id="financialFilterForm"
        onSubmit={onFilterSubmit}
        className="d-flex align-items-end gap-3 flex-nowrap justify-content-center mb-3 w-100 overflow-auto"
        style={{ whiteSpace: 'nowrap' }}
      >
        <div className="d-flex align-items-center gap-2 flex-nowrap">
          <label className="form-label mb-0 me-2">School year</label>
          <select
            name="school_year"
            className="form-select form-select-sm rounded-pill px-3"
            style={{ minWidth: 180 }}
            value={schoolYear || defaultYear}
            onChange={(e) => setSchoolYear(e.target.value)}
          >
            {options.map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        </div>
        <div className="d-flex align-items-end gap-2 flex-nowrap">
          <div className="d-flex flex-column">
            <label className="form-label">Date From:</label>
            <input
              type="date"
              name="date_from"
              className="form-control"
              value={dateFrom}
              onChange={(e) => setDateFrom(e.target.value)}
            />
          </div>
          <div className="d-flex flex-column">
            <label className="form-label">Date To:</label>
            <input
              type="date"
              name="date_to"
              className="form-control"
              value={dateTo}
              onChange={(e) => setDateTo(e.target.value)}
            />
          </div>
          <button type="submit" className="btn btn-secondary ms-2">
            Filter
          </button>
        </div>
      </form>

      {loading ? (
        <div className="text-center my-4">
          <div className="spinner-border text-primary" role="status" />
          <div className="mt-2">Loading report…</div>
          {lastRef ? <div className="text-muted small">{lastRef}</div> : null}
        </div>
      ) : null}

      {error ? (
        <div className="alert alert-danger">
          {error}{' '}
          <button type="button" className="btn btn-link alert-link p-0" onClick={() => hydrate()}>
            Retry
          </button>
        </div>
      ) : null}

      <div className="d-flex gap-2 mb-3 justify-content-end flex-nowrap w-100 overflow-auto" style={{ whiteSpace: 'nowrap' }}>
        <button type="button" className="btn btn-success" onClick={onDownloadCsv}>
          Download CSV
        </button>
        <button type="button" className="btn btn-primary" onClick={() => window.print()}>
          Print Report
        </button>
        <Link
          className="btn btn-info"
          to={`/app/administrator/payment/financial-report-summary?school_year=${encodeURIComponent(schoolYear || defaultYear)}`}
        >
          Display Summary Report
        </Link>
      </div>

      {data?.eventFeesTotal != null ? (
        <div className="alert alert-info mb-3">
          <strong>Event fees total:</strong> {fmt(Number(data.eventFeesTotal))}
        </div>
      ) : null}

      <div className="table-responsive">
        <table className="table table-bordered table-striped align-middle w-100">
          <thead style={{ position: 'sticky', top: 0, zIndex: 2, backgroundColor: '#f8f9fa' }}>
            <tr>
              <th>Invoice #</th>
              <th>Parent</th>
              <th>School Year</th>
              <th>Total</th>
              <th>Paid</th>
              <th>Cash</th>
              <th>Credit</th>
              <th>Check</th>
              <th>Balance</th>
              <th>Refund</th>
              <th>Discount</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            {invoiceRows.map(({ inv, paid, cash, credit, check, balance, refunded, discounted, totalAmount, status, statusClass }) => (
              <tr key={String(inv.id)}>
                <td>{String(inv.invoice_number ?? '')}</td>
                <td>
                  {inv.parent_id ? (
                    <Link
                      to={`/app/administrator/family?guardian_id=${Number(inv.parent_id)}`}
                      className="text-decoration-none"
                    >
                      {String(inv.parent_name ?? '')}
                    </Link>
                  ) : (
                    String(inv.parent_name ?? '')
                  )}
                </td>
                <td>{String(inv.school_year ?? '')}</td>
                <td>{fmt(totalAmount)}</td>
                <td>{fmt(paid)}</td>
                <td>{fmt(cash)}</td>
                <td>{fmt(credit)}</td>
                <td>{fmt(check)}</td>
                <td>{fmt(balance)}</td>
                <td>{fmt(refunded)}</td>
                <td>{fmt(discounted)}</td>
                <td>
                  <span className={`badge ${statusClass}`}>{status}</span>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <h3 className="mt-5">Payments by Method (Filtered)</h3>
      <div className="table-responsive">
        <table className="table table-bordered align-middle w-100">
          <thead>
            <tr>
              <th>Cash</th>
              <th>Credit</th>
              <th>Check</th>
              <th>Grand Total (All Payments)</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>{fmt(totalCash)}</td>
              <td>{fmt(totalCredit)}</td>
              <td>{fmt(totalCheck)}</td>
              <td className="fw-bold">{fmt(grandTotal)}</td>
            </tr>
          </tbody>
        </table>
      </div>

      <h3 className="mt-5">Expenses Summary</h3>
      <div className="table-responsive">
        <table className="table table-bordered align-middle w-100">
          <thead>
            <tr>
              <th>Category</th>
              <th>Total Amount</th>
            </tr>
          </thead>
          <tbody>
            {(data?.expenses ?? []).map((exp, i) => (
              <tr key={i}>
                <td>{String(exp.category ?? '')}</td>
                <td>{fmt(Number(exp.total_amount ?? 0))}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <h3 className="mt-5">Reimbursements Summary</h3>
      <div className="table-responsive">
        <table className="table table-bordered align-middle w-100">
          <thead>
            <tr>
              <th>Status</th>
              <th>Total Amount</th>
            </tr>
          </thead>
          <tbody>
            {(data?.reimbursements ?? []).map((r, i) => (
              <tr key={i}>
                <td>{String(r.status ?? '')}</td>
                <td>{fmt(Number(r.total_amount ?? 0))}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  )
}
