import { useCallback, useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { useSchoolYearOptions } from '../../hooks/useSchoolYearOptions'
import {
  fetchInvoiceManagement,
  type InvoiceManagementRow,
  postInvoiceGenerate,
} from '../../api/invoices'

function fmtMoney(v: unknown): string {
  const n = typeof v === 'number' ? v : Number(v ?? 0)
  return `$${(Number.isFinite(n) ? n : 0).toFixed(2)}`
}

function formatDateTime(iso: unknown): string {
  if (iso == null || iso === '') return ''
  const d = new Date(String(iso))
  if (Number.isNaN(d.valueOf())) return String(iso)
  const p = (n: number) => String(n).padStart(2, '0')
  return `${p(d.getMonth() + 1)}-${p(d.getDate())}-${d.getFullYear()} ${p(d.getHours())}:${p(d.getMinutes())}`
}

function renderStudents(list: InvoiceManagementRow['enrolledKids']): string {
  if (!list?.length) return 'No students enrolled.'
  return list
    .map((k) => `${k.name ?? ''} (Grade: ${k.grade ?? '—'})`)
    .join('; ')
}

/** CI `invoice_payment/invoice_management.php` — DataTables replaced with filterable table. */
export function InvoiceManagementPage() {
  const [schoolYears, setSchoolYears] = useState<string[]>([])
  const [schoolYear, setSchoolYear] = useState('')
  const [invoices, setInvoices] = useState<InvoiceManagementRow[]>([])
  const [filter, setFilter] = useState('')
  const [loading, setLoading] = useState(true)
  const [generating, setGenerating] = useState<number | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [toast, setToast] = useState<{ ok: boolean; message: string } | null>(null)
  const { options, selectedYear: defaultYear } = useSchoolYearOptions({
    legacyYears: schoolYears,
    preferredYear: schoolYear,
  })

  const load = useCallback(async (year?: string) => {
    setLoading(true)
    setError(null)
    try {
      const sp = new URLSearchParams()
      if (year) sp.set('schoolYear', year)
      const data = await fetchInvoiceManagement(sp)
      const years = Array.isArray(data.schoolYears) ? data.schoolYears : []
      setSchoolYears(years)
      const sel = data.schoolYear ?? years[0] ?? defaultYear
      setSchoolYear(sel)
      setInvoices(Array.isArray(data.invoices) ? data.invoices : [])
    } catch (e: unknown) {
      setError(e instanceof ApiHttpError ? e.message : 'Failed to load invoices.')
      setInvoices([])
    } finally {
      setLoading(false)
    }
  }, [defaultYear])

  useEffect(() => {
    void load()
  }, [load])

  useEffect(() => {
    if (!toast) return
    const t = window.setTimeout(() => setToast(null), 3200)
    return () => window.clearTimeout(t)
  }, [toast])

  const filtered = useMemo(() => {
    const q = filter.trim().toLowerCase()
    if (!q) return invoices
    return invoices.filter((r) => {
      const name = String(r.parent_name ?? '').toLowerCase()
      const kids = JSON.stringify(r.enrolledKids ?? []).toLowerCase()
      return name.includes(q) || kids.includes(q)
    })
  }, [invoices, filter])

  async function onGenerate(parentId: number | undefined) {
    if (parentId == null || !Number.isFinite(parentId)) return
    setGenerating(parentId)
    setError(null)
    try {
      await postInvoiceGenerate(parentId)
      setToast({ ok: true, message: 'Invoice generated.' })
      const sp = new URLSearchParams()
      if (schoolYear) sp.set('schoolYear', schoolYear)
      const data = await fetchInvoiceManagement(sp)
      setInvoices(Array.isArray(data.invoices) ? data.invoices : [])
    } catch (e: unknown) {
      setToast({
        ok: false,
        message: e instanceof ApiHttpError ? e.message : 'Failed to generate invoice.',
      })
    } finally {
      setGenerating(null)
    }
  }

  async function onYearChange(nextYear: string) {
    setSchoolYear(nextYear)
    await load(nextYear || undefined)
    setToast({ ok: true, message: nextYear ? `Loaded ${nextYear}` : 'Loaded' })
  }

  return (
    <div className="container-fluid">
      <h2 className="text-center mt-4 mb-3">Invoice Management</h2>

      {toast ? (
        <div
          className={`alert ${toast.ok ? 'alert-success' : 'alert-danger'} py-2 mx-auto`}
          style={{ maxWidth: 480 }}
        >
          {toast.message}
        </div>
      ) : null}
      {error ? <div className="alert alert-danger">{error}</div> : null}

      <div className="row g-2 align-items-center justify-content-center mb-3">
        <div className="col-auto">
          <label htmlFor="schoolYearSelect" className="col-form-label">
            School year
          </label>
        </div>
        <div className="col-auto">
          <select
            id="schoolYearSelect"
            className="form-select form-select-sm"
            style={{ minWidth: 180 }}
            value={schoolYear}
            onChange={(e) => void onYearChange(e.target.value)}
          >
            {options.map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        </div>
        <div className="col-auto flex-grow-1" style={{ maxWidth: 320 }}>
          <input
            type="search"
            className="form-control form-control-sm"
            placeholder="Filter by parent or students…"
            value={filter}
            onChange={(e) => setFilter(e.target.value)}
          />
        </div>
      </div>

      <div className="table-responsive">
        <table className="table table-striped table-hover table-bordered w-100">
          <thead className="table-dark">
            <tr>
              <th scope="col">Parent Name</th>
              <th scope="col">Enrolled Students</th>
              <th scope="col">Invoice Generation</th>
              <th scope="col">Invoice Amount</th>
              <th scope="col">Refund Amount</th>
              <th scope="col">Date</th>
              <th scope="col">Actions</th>
            </tr>
          </thead>
          <tbody>
            {loading ? (
              <tr>
                <td colSpan={7} className="text-center text-muted py-4">
                  Loading…
                </td>
              </tr>
            ) : filtered.length === 0 ? (
              <tr>
                <td colSpan={7} className="text-center text-muted py-4">
                  No invoices.
                </td>
              </tr>
            ) : (
              filtered.map((r, idx) => {
                const pid = r.parent_id ?? 0
                const invoiceId = r.invoice_id
                return (
                  <tr key={`${pid}-${idx}`}>
                    <td>
                      {pid > 0 ? (
                        <Link
                          to={`/app/administrator/family?guardian_id=${encodeURIComponent(String(pid))}`}
                          className="text-decoration-none"
                        >
                          {r.parent_name ?? '—'}
                        </Link>
                      ) : (
                        (r.parent_name ?? '—')
                      )}
                    </td>
                    <td className="small">{renderStudents(r.enrolledKids)}</td>
                    <td>
                      <button
                        type="button"
                        className="btn btn-primary btn-sm"
                        disabled={generating === pid}
                        onClick={() => void onGenerate(pid)}
                      >
                        {generating === pid ? '…' : 'Generate Invoice'}
                      </button>
                    </td>
                    <td>{fmtMoney(r.invoice_amount)}</td>
                    <td>{fmtMoney(r.refund_amount)}</td>
                    <td>{formatDateTime(r.invoice_date)}</td>
                    <td>
                      {invoiceId ? (
                        <Link
                          className="btn btn-info btn-sm"
                          to={`/app/administrator/invoice-payment/pdf/${invoiceId}`}
                          target="_blank"
                          rel="noreferrer"
                        >
                          View / Print
                        </Link>
                      ) : (
                        <span className="text-muted">No invoice yet</span>
                      )}
                    </td>
                  </tr>
                )
              })
            )}
          </tbody>
        </table>
      </div>
    </div>
  )
}
