import { useEffect, useMemo, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { applyDiscountVoucher, fetchDiscountApplyContext } from '../../api/session'
import type { DiscountApplyParentRow, DiscountVoucherRow } from '../../api/types'
import { AcademicFilterBar } from './AcademicFilterBar'

export function DiscountApplyVoucherPage() {
  const [searchParams] = useSearchParams()
  const schoolYear = searchParams.get('school_year') ?? undefined
  const semester = searchParams.get('semester') ?? undefined

  const [vouchers, setVouchers] = useState<DiscountVoucherRow[]>([])
  const [voucherId, setVoucherId] = useState('')
  const [allowAdditional, setAllowAdditional] = useState(true)
  const [parents, setParents] = useState<DiscountApplyParentRow[]>([])
  const [selected, setSelected] = useState<Record<string, boolean>>({})
  const [checkAll, setCheckAll] = useState(false)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [msg, setMsg] = useState<string | null>(null)
  const [busy, setBusy] = useState(false)

  useEffect(() => {
    let cancelled = false
    setLoading(true)
    fetchDiscountApplyContext({ school_year: schoolYear, semester })
      .then((d) => {
        if (cancelled) return
        setParents(d.parents ?? [])
        setVouchers(d.vouchers ?? [])
      })
      .catch((e: unknown) => {
        if (!cancelled)
          setError(e instanceof ApiHttpError ? e.message : 'Could not load parents or vouchers.')
      })
      .finally(() => {
        if (!cancelled) setLoading(false)
      })
    return () => {
      cancelled = true
    }
  }, [schoolYear, semester])

  const selectableParents = useMemo(
    () =>
      parents.filter((p) => {
        if (!p.has_discount) return true
        return allowAdditional
      }),
    [parents, allowAdditional],
  )

  function toggleParent(id: string, enabled: boolean) {
    if (!enabled) return
    setSelected((s) => ({ ...s, [id]: !s[id] }))
  }

  function onCheckAll(checked: boolean) {
    setCheckAll(checked)
    const next: Record<string, boolean> = {}
    if (checked) {
      for (const p of selectableParents) {
        next[String(p.id)] = true
      }
    }
    setSelected(next)
  }

  useEffect(() => {
    setSelected({})
    setCheckAll(false)
  }, [allowAdditional, parents])

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault()
    if (!voucherId) return
    const ids = Object.entries(selected)
      .filter(([, on]) => on)
      .map(([id]) => id)
    if (ids.length === 0) {
      setMsg('Select at least one parent.')
      return
    }
    setBusy(true)
    setMsg(null)
    try {
      await applyDiscountVoucher({
        voucher_id: voucherId,
        parent_ids: ids,
        allow_additional: allowAdditional,
        school_year: schoolYear,
        semester,
      })
      setMsg('Voucher applied.')
    } catch (err: unknown) {
      setMsg(err instanceof ApiHttpError ? err.message : 'Apply failed.')
    } finally {
      setBusy(false)
    }
  }

  return (
    <div className="container mt-4">
      <h1>Apply Discount Voucher</h1>
      <AcademicFilterBar />

      {loading ? <p className="text-muted">Loading…</p> : null}
      {error ? <div className="alert alert-danger">{error}</div> : null}
      {msg ? (
        <div className={`alert ${msg.includes('fail') || msg.includes('Select') ? 'alert-warning' : 'alert-success'}`}>
          {msg}
        </div>
      ) : null}

      <form onSubmit={onSubmit}>
        <div className="d-flex gap-2 mb-3 justify-content-end">
          <button type="submit" className="btn btn-success" disabled={busy || loading}>
            Apply Voucher
          </button>
          <Link to="/app/administrator/discounts" className="btn btn-info">
            Cancel
          </Link>
        </div>

        <div className="mb-3">
          <label className="form-label" htmlFor="voucher_id">
            Select Voucher Code
          </label>
          <select
            name="voucher_id"
            id="voucher_id"
            className="form-select"
            required
            value={voucherId}
            onChange={(ev) => setVoucherId(ev.target.value)}
          >
            <option value="">-- Select Voucher --</option>
            {vouchers.map((v) => (
              <option key={String(v.id)} value={String(v.id)}>
                {v.code} ({String(v.discount_type)} —{' '}
                {v.discount_type === 'percent' ? `${v.discount_value}%` : `$${v.discount_value}`})
              </option>
            ))}
          </select>
        </div>

        <div className="form-check mb-3">
          <input
            className="form-check-input"
            type="checkbox"
            id="allowAdditional"
            checked={allowAdditional}
            onChange={(ev) => setAllowAdditional(ev.target.checked)}
          />
          <label className="form-check-label" htmlFor="allowAdditional">
            Allow additional discounts for parents who already have discounts
          </label>
        </div>

        <div className="mb-3">
          <label className="form-label">Select Parents</label>
          <div className="table-responsive">
            <table className="table table-bordered">
              <thead>
                <tr>
                  <th>
                    <input
                      type="checkbox"
                      checked={checkAll}
                      onChange={(ev) => onCheckAll(ev.target.checked)}
                      aria-label="Select all"
                    />
                  </th>
                  <th>Parent ID</th>
                  <th>Parent Name</th>
                  <th>Email</th>
                  <th>Has Discount?</th>
                  <th>Total Discount Amount</th>
                </tr>
              </thead>
              <tbody>
                {parents.map((parent) => {
                  const id = String(parent.id)
                  const hasDisc = Boolean(parent.has_discount)
                  const enabled = !hasDisc || allowAdditional
                  return (
                    <tr key={id}>
                      <td>
                        <input
                          type="checkbox"
                          name={`parent_${id}`}
                          className="form-check-input"
                          checked={Boolean(selected[id])}
                          disabled={!enabled}
                          onChange={() => toggleParent(id, enabled)}
                        />
                      </td>
                      <td>{parent.school_id ?? 'N/A'}</td>
                      <td>
                        {[parent.firstname, parent.lastname].filter(Boolean).join(' ') || '—'}
                      </td>
                      <td>{parent.email ?? '—'}</td>
                      <td>{hasDisc ? 'Yes' : 'No'}</td>
                      <td>${Number(parent.total_discount ?? 0).toFixed(2)}</td>
                    </tr>
                  )
                })}
              </tbody>
            </table>
          </div>
        </div>
      </form>
    </div>
  )
}
