import { useEffect, useMemo, useState } from 'react'
import { ApiHttpError } from '../../api/http'
import { fetchParentStatement, type ParentStatement } from '../../api/schoolYears'
import { SchoolYearSelector } from '../../components/schoolYear'
import { useSchoolYear } from '../../context/SchoolYearContext'

function normalizeApiError(error: unknown, fallback: string): string {
  if (error instanceof ApiHttpError) return error.message || fallback
  if (error instanceof Error) return error.message
  return fallback
}

function formatMoney(value: number | null | undefined): string {
  return Number(value ?? 0).toLocaleString(undefined, {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  })
}

export function ParentStatementPage() {
  const { selectedSchoolYearName } = useSchoolYear()
  const [statement, setStatement] = useState<ParentStatement | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    if (!selectedSchoolYearName) return

    let cancelled = false
    setLoading(true)
    setError(null)

    ;(async () => {
      try {
        const nextStatement = await fetchParentStatement({ schoolYear: selectedSchoolYearName })
        if (!cancelled) setStatement(nextStatement)
      } catch (loadError) {
        if (!cancelled) setError(normalizeApiError(loadError, 'Unable to load parent statement.'))
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()

    return () => {
      cancelled = true
    }
  }, [selectedSchoolYearName])

  const lines = useMemo(() => statement?.lines ?? [], [statement])

  return (
    <div className="container py-4">
      <div className="d-flex flex-wrap justify-content-between align-items-start gap-3 mb-4">
        <div>
          <h1 className="h3 mb-1">Parent Statement</h1>
          <p className="text-muted mb-0">
            Opening balances from closed years are shown separately from new-year charges so they are not double-counted.
          </p>
        </div>
        <SchoolYearSelector />
      </div>

      {error ? <div className="alert alert-danger">{error}</div> : null}
      {loading ? <p className="text-muted">Loading statement…</p> : null}

      <div className="card shadow-sm">
        <div className="card-body">
          <div className="d-flex flex-wrap justify-content-between gap-3 mb-3">
            <div>
              <h2 className="h5 mb-1">{statement?.parent_name ?? 'Parent account'}</h2>
              <div className="text-muted small">School year: {selectedSchoolYearName ?? '—'}</div>
            </div>
            <div className="text-end">
              <div className="small text-muted">Current balance</div>
              <div className="h4 mb-0">${formatMoney(statement?.current_balance)}</div>
            </div>
          </div>

          <div className="alert alert-info small">
            Opening balance from prior year: <strong>${formatMoney(statement?.opening_balance)}</strong>. The old-balance invoice is the collectible item; this opening-balance label is audit context, not a second charge.
          </div>

          <div className="table-responsive">
            <table className="table align-middle">
              <thead>
                <tr>
                  <th>Description</th>
                  <th>Source year</th>
                  <th>Invoice</th>
                  <th className="text-end">Amount</th>
                </tr>
              </thead>
              <tbody>
                {lines.length === 0 ? (
                  <tr><td colSpan={4} className="text-muted">No statement lines found.</td></tr>
                ) : lines.map((line, index) => (
                  <tr key={`${line.label}-${index}`}>
                    <td>{line.label}</td>
                    <td>{line.source_school_year ?? '—'}</td>
                    <td>{line.invoice_id ?? '—'}</td>
                    <td className="text-end">${formatMoney(line.amount)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  )
}
