import { type FormEvent, useCallback, useEffect, useState } from 'react'
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { useSchoolYearOptions } from '../../hooks/useSchoolYearOptions'
import {
  fetchChargeInvoicesForParent,
  fetchExtraChargesPage,
  submitExtraCharge,
  type ExtraChargeRow,
} from '../../api/paymentManagement'

function fmtMoney(n: unknown): string {
  const v = Number(n)
  return Number.isFinite(v) ? v.toFixed(2) : '0.00'
}

/** Extra charges admin — `GET|POST /api/v1/administrator/charges` (JWT). SPA: `/app/admin/charges`. */

export function ExtraChargesPage() {
  const navigate = useNavigate()
  const { pathname } = useLocation()
  const [searchParams] = useSearchParams()
  const schoolYear = searchParams.get('school_year') ?? ''
  const semester = searchParams.get('semester') ?? ''

  const [rows, setRows] = useState<ExtraChargeRow[]>([])
  const [schoolYears, setSchoolYears] = useState<string[]>([])
  const [activeYear, setActiveYear] = useState(schoolYear)
  const [activeSem, setActiveSem] = useState(semester)
  const [parents, setParents] = useState<Array<{ id: number; firstname?: string; lastname?: string }>>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [msg, setMsg] = useState<string | null>(null)
  const [invoiceOptions, setInvoiceOptions] = useState<Array<{ id?: number; invoice_number?: string }>>([])
  const [modalOpen, setModalOpen] = useState(false)
  const [selectedParentId, setSelectedParentId] = useState<string>('')
  const { options, selectedYear: defaultYear } = useSchoolYearOptions({
    legacyYears: schoolYears,
    preferredYear: activeYear || schoolYear,
  })

  useEffect(() => {
    setActiveYear(schoolYear)
    setActiveSem(semester)
  }, [schoolYear, semester])

  const loadCharges = useCallback(() => {
    setLoading(true)
    setError(null)
    fetchExtraChargesPage({
      school_year: schoolYear || undefined,
      semester: semester || undefined,
    })
      .then((d) => {
        setRows(d.rows ?? [])
        setSchoolYears(d.schoolYears ?? [])
        setParents((d.parents ?? []) as typeof parents)
        if (d.schoolYear) setActiveYear(String(d.schoolYear))
        if (d.semester) setActiveSem(String(d.semester))
      })
      .catch((e: unknown) =>
        setError(e instanceof ApiHttpError ? e.message : 'Could not load charges.'),
      )
      .finally(() => setLoading(false))
  }, [schoolYear, semester])

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

  useEffect(() => {
    if (!selectedParentId) {
      setInvoiceOptions([])
      return
    }
    fetchChargeInvoicesForParent(selectedParentId)
      .then(setInvoiceOptions)
      .catch(() => setInvoiceOptions([]))
  }, [selectedParentId])

  function onYearChange(e: React.ChangeEvent<HTMLSelectElement>) {
    const y = e.target.value
    setActiveYear(y)
    const next = new URLSearchParams(searchParams)
    if (y) next.set('school_year', y)
    else next.delete('school_year')
    navigate({ pathname, search: next.toString() })
  }

  async function onModalSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault()
    const fd = new FormData(e.currentTarget)
    if (activeYear) fd.set('school_year', activeYear)
    if (activeSem) fd.set('semester', activeSem)
    setMsg(null)
    try {
      await submitExtraCharge(fd)
      setMsg('Charge saved.')
      setModalOpen(false)
      loadCharges()
    } catch (err: unknown) {
      setMsg(err instanceof ApiHttpError ? err.message : 'Save failed.')
    }
  }

  let pageTotal = 0
  for (const r of rows) pageTotal += Number(r.amount ?? 0)

  return (
    <div className="container-fluid py-4">
      {msg ? <div className="alert alert-info">{msg}</div> : null}
      {error ? <div className="alert alert-danger">{error}</div> : null}

      <div className="d-flex justify-content-center mb-3 flex-wrap gap-3 align-items-center">
        <h3 className="mb-0">
          Add &amp; Deduct Charges
          <span className="text-muted ms-2">
            ({activeYear || '—'} — {activeSem || '—'})
          </span>
        </h3>
        <div className="d-flex align-items-center gap-2">
          <label className="form-label mb-0" htmlFor="schoolYearSel">
            School year
          </label>
          <select
            id="schoolYearSel"
            className="form-select form-select-sm rounded-pill px-3"
            style={{ minWidth: 180 }}
            value={activeYear || defaultYear}
            onChange={onYearChange}
          >
            {options.map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        </div>
        <button type="button" className="btn btn-success" onClick={() => setModalOpen(true)}>
          Add Charge
        </button>
      </div>

      {loading ? <p className="text-muted">Loading…</p> : null}

      <div className="card shadow-sm">
        <div className="card-body table-responsive">
          <table className="table table-bordered table-striped align-middle w-100">
            <thead className="table-light">
              <tr>
                <th>ID</th>
                <th>Type</th>
                <th>Title</th>
                <th className="text-end">Amount</th>
                <th>Parent</th>
                <th>Status</th>
                <th>Invoice</th>
                <th>Due</th>
              </tr>
            </thead>
            <tbody>
              {rows.length === 0 && !loading ? (
                <tr>
                  <td colSpan={8} className="text-center text-muted py-4">
                    No charges
                  </td>
                </tr>
              ) : (
                rows.map((r) => {
                  const ctype = String(r.charge_type ?? '').toLowerCase()
                  const amt = Number(r.amount ?? 0)
                  const isAdd = ctype === 'add' || amt > 0
                  const isDed = ctype === 'deduct' || amt < 0
                  const badge = isAdd ? 'bg-success' : isDed ? 'bg-danger' : 'bg-secondary'
                  const label = isAdd ? 'Add' : isDed ? 'Deduct' : ctype || '—'
                  const st = String(r.status ?? '')
                  const cls =
                    st === 'pending' ? 'bg-info' : st === 'applied' ? 'bg-success' : st === 'void' ? 'bg-danger' : 'bg-light'
                  return (
                    <tr key={String(r.id)}>
                      <td>#{String(r.id)}</td>
                      <td>
                        <span className={`badge ${badge}`}>{label}</span>
                      </td>
                      <td>
                        <div className="fw-semibold">{String(r.title ?? '')}</div>
                        {r.description ? (
                          <div className="small text-muted">{String(r.description)}</div>
                        ) : null}
                      </td>
                      <td className="text-end">${fmtMoney(r.amount)}</td>
                      <td>{String(r.parent_name ?? `ID: ${r.parent_id ?? ''}`)}</td>
                      <td>
                        <span className={`badge ${cls}`}>{st}</span>
                      </td>
                      <td>
                        {r.invoice_number
                          ? String(r.invoice_number)
                          : r.invoice_id
                            ? `#${r.invoice_id}`
                            : '—'}
                      </td>
                      <td>{r.due_date ? String(r.due_date) : '—'}</td>
                    </tr>
                  )
                })
              )}
            </tbody>
            <tfoot className="table-light">
              <tr>
                <td colSpan={3} className="text-end fw-semibold">
                  Total Amount
                </td>
                <td className="text-end fw-semibold">${pageTotal.toFixed(2)}</td>
                <td colSpan={4} />
              </tr>
            </tfoot>
          </table>
        </div>
      </div>

      {modalOpen ? (
        <div className="modal show d-block" tabIndex={-1} style={{ background: 'rgba(0,0,0,.45)' }}>
          <div className="modal-dialog modal-lg modal-dialog-scrollable">
            <form className="modal-content" onSubmit={onModalSubmit}>
              <div className="modal-header">
                <h5 className="modal-title">Adjust Charge</h5>
                <button type="button" className="btn-close" onClick={() => setModalOpen(false)} />
              </div>
              <div className="modal-body">
                <div className="row g-3">
                  <div className="col-md-6">
                    <label className="form-label">Parent *</label>
                    <select
                      name="parent_id"
                      className="form-select"
                      required
                      value={selectedParentId}
                      onChange={(e) => setSelectedParentId(e.target.value)}
                    >
                      <option value="">— Select Parent —</option>
                      {parents.map((p) => (
                        <option key={p.id} value={String(p.id)}>
                          {`${p.lastname ?? ''}, ${p.firstname ?? ''}`.trim() || `ID ${p.id}`}
                        </option>
                      ))}
                    </select>
                  </div>
                  <div className="col-md-6">
                    <label className="form-label">Invoice</label>
                    <select name="invoice_id" className="form-select">
                      <option value="">—</option>
                      {invoiceOptions.map((inv) => (
                        <option key={String(inv.id)} value={String(inv.id ?? '')}>
                          {inv.invoice_number ?? `#${inv.id}`}
                        </option>
                      ))}
                    </select>
                  </div>
                  <div className="col-md-6">
                    <label className="form-label">Title *</label>
                    <input name="title" type="text" className="form-control" required />
                  </div>
                  <div className="col-md-6">
                    <label className="form-label">Description *</label>
                    <input name="description" type="text" className="form-control" required />
                  </div>
                  <div className="col-md-3">
                    <label className="form-label">Amount *</label>
                    <input name="amount" type="number" step="0.01" className="form-control" required />
                  </div>
                  <div className="col-md-3">
                    <label className="form-label">Type *</label>
                    <select name="charge_type" className="form-select" required>
                      <option value="add">Add Charge</option>
                      <option value="deduct">Deduct Charge</option>
                    </select>
                  </div>
                  <div className="col-md-3">
                    <label className="form-label">Due Date</label>
                    <input name="due_date" type="date" className="form-control" />
                  </div>
                </div>
              </div>
              <div className="modal-footer">
                <button type="submit" className="btn btn-primary">
                  Save
                </button>
                <button type="button" className="btn btn-secondary" onClick={() => setModalOpen(false)}>
                  Cancel
                </button>
              </div>
            </form>
          </div>
        </div>
      ) : null}
    </div>
  )
}
