import { useCallback, useEffect, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { useSchoolYearOptions } from '../../hooks/useSchoolYearOptions'
import { fetchClassPrepIndex, saveClassPrepAdjustment } from '../../api/session'
import type { ClassPrepIndexResponse, ClassPrepSectionRow } from '../../api/types'

function adjustQty(input: HTMLInputElement, delta: number) {
  const curr = parseInt(input.value, 10) || 0
  input.value = String(curr + delta)
}

export function ClassPrepListPage() {
  const [searchParams, setSearchParams] = useSearchParams()
  const schoolYear = searchParams.get('school_year') ?? ''
  const semester = searchParams.get('semester') ?? ''

  const [data, setData] = useState<ClassPrepIndexResponse | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [savingId, setSavingId] = useState<string | null>(null)
  const [saveMsg, setSaveMsg] = useState<string | null>(null)
  const { options, selectedYear } = useSchoolYearOptions({
    preferredYear: schoolYear,
  })

  useEffect(() => {
    let cancelled = false
    setLoading(true)
    setError(null)
    fetchClassPrepIndex({
      school_year: schoolYear || selectedYear,
      semester: semester || undefined,
    })
      .then((d) => {
        if (!cancelled) setData(d)
      })
      .catch((e: unknown) => {
        if (!cancelled)
          setError(e instanceof ApiHttpError ? e.message : 'Failed to load class preparation data.')
      })
      .finally(() => {
        if (!cancelled) setLoading(false)
      })
    return () => {
      cancelled = true
    }
  }, [schoolYear, semester])

  const onFilterSubmit = useCallback(
    (e: React.FormEvent<HTMLFormElement>) => {
      e.preventDefault()
      const fd = new FormData(e.currentTarget)
      const sy = String(fd.get('school_year') ?? '')
      const sem = String(fd.get('semester') ?? '')
      const next = new URLSearchParams()
      if (sy) next.set('school_year', sy)
      if (sem) next.set('semester', sem)
      setSearchParams(next)
    },
    [setSearchParams],
  )

  async function onSaveAdjustment(prep: ClassPrepSectionRow, form: HTMLFormElement) {
    setSavingId(String(prep.class_section_id))
    setSaveMsg(null)
    const fd = new FormData(form)
    const adjustments: Record<string, number> = {}
    fd.forEach((v, k) => {
      if (k.startsWith('adj__')) {
        const name = k.slice(5)
        adjustments[name] = parseInt(String(v), 10) || 0
      }
    })
    try {
      await saveClassPrepAdjustment({
        class_section_id: prep.class_section_id,
        school_year: schoolYear,
        semester: semester || undefined,
        adjustments,
      })
      setSaveMsg('Saved.')
      const fresh = await fetchClassPrepIndex({
        school_year: schoolYear,
        semester: semester || undefined,
      })
      setData(fresh)
    } catch (e: unknown) {
      setSaveMsg(e instanceof ApiHttpError ? e.message : 'Save failed.')
    } finally {
      setSavingId(null)
    }
  }

  const printBase = `/app/administrator/class-prep/print`
  const semQuery = semester ? `?semester=${encodeURIComponent(semester)}` : ''

  return (
    <div className="container-fluid">
      <div className="wrapper">
        <h2 className="text-center mt-4 mb-3">Class Preparation</h2>

        <form onSubmit={onFilterSubmit} className="mb-4 d-flex align-items-center gap-2 flex-wrap">
          <label htmlFor="school_year" className="form-label mb-0">
            School Year:
          </label>
          <select
            name="school_year"
            id="school_year"
            className="form-select form-select-sm w-auto"
            defaultValue={schoolYear || selectedYear}
          >
            {(options.length > 0 ? options : [{ value: selectedYear, label: selectedYear }]).map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
          <label htmlFor="semester" className="form-label mb-0">
            Semester:
          </label>
          <select
            name="semester"
            id="semester"
            className="form-select form-select-sm w-auto"
            defaultValue={semester}
          >
            <option value="">—</option>
            <option value="Fall">Fall</option>
            <option value="Spring">Spring</option>
          </select>
          <button type="submit" className="btn btn-sm btn-primary">
            Calculate Items
          </button>
        </form>

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

        {saveMsg ? (
          <div className="alert alert-info py-2" role="status">
            {saveMsg}
          </div>
        ) : null}

        <div className="row g-3">
          {(data?.prep_results ?? []).map((prep) => {
            const adjMap = prep.adjustments ?? {}
            return (
              <div key={String(prep.class_section_id)} className="col-12 col-lg-6">
                <div className="card shadow-sm border-0 h-100 classprep-card">
                  <div className="card-header d-flex justify-content-between align-items-center bg-light border-0">
                    <div>
                      <div className="fw-semibold mb-1">{prep.class_section}</div>
                      {prep.needs_print ? (
                        <span className="badge bg-danger">Updated since last print</span>
                      ) : (
                        <span className="badge bg-success">Up-to-date</span>
                      )}
                      {prep.last_printed_at ? (
                        <small className="text-muted ms-2">Last printed: {prep.last_printed_at}</small>
                      ) : null}
                    </div>
                    <div className="small text-muted text-end">
                      Students:
                      <br />
                      <span className="badge bg-secondary">{prep.student_count}</span>
                    </div>
                  </div>

                  <div className="card-body">
                    <div className="row g-3">
                      <div className="col-12 col-md-7">
                        <div className="fw-semibold mb-2">Prep Items</div>
                        <ul className="list-group list-group-flush small border rounded overflow-hidden">
                          {Object.entries(prep.prep_items ?? {}).map(([item, qty]) => (
                            <li
                              key={item}
                              className={`list-group-item d-flex justify-content-between align-items-center ${
                                Number(qty) === 0 ? 'text-muted classprep-muted-soft' : ''
                              }`}
                            >
                              <span>{item}</span>
                              <span
                                className={`badge rounded-pill ${
                                  Number(qty) > 0 ? 'bg-primary' : 'bg-secondary'
                                }`}
                              >
                                {Number(qty)}
                              </span>
                            </li>
                          ))}
                        </ul>
                      </div>

                      <div className="col-12 col-md-5">
                        <div className="fw-semibold mb-2">Adjustments (Tables)</div>
                        <form
                          className="d-grid gap-2"
                          onSubmit={(e) => {
                            e.preventDefault()
                            void onSaveAdjustment(prep, e.currentTarget)
                          }}
                        >
                          {Object.entries(adjMap).map(([item, value]) => (
                            <div key={item}>
                              <label className="form-label mb-1 small text-muted d-block">{item}</label>
                              <div className="input-group input-group-sm">
                                <button
                                  type="button"
                                  className="btn btn-outline-secondary"
                                  onClick={(ev) => {
                                    const input = ev.currentTarget.parentElement?.querySelector(
                                      'input[type="number"]',
                                    ) as HTMLInputElement | null
                                    if (input) adjustQty(input, -1)
                                  }}
                                  aria-label={`Decrease ${item}`}
                                >
                                  −
                                </button>
                                <input
                                  type="number"
                                  className="form-control text-center"
                                  name={`adj__${item}`}
                                  defaultValue={Number(value)}
                                  readOnly
                                />
                                <button
                                  type="button"
                                  className="btn btn-outline-secondary"
                                  onClick={(ev) => {
                                    const input = ev.currentTarget.parentElement?.querySelector(
                                      'input[type="number"]',
                                    ) as HTMLInputElement | null
                                    if (input) adjustQty(input, 1)
                                  }}
                                  aria-label={`Increase ${item}`}
                                >
                                  +
                                </button>
                              </div>
                            </div>
                          ))}
                          <div className="d-flex justify-content-end">
                            <button
                              type="submit"
                              className="btn btn-sm btn-primary"
                              disabled={savingId === String(prep.class_section_id)}
                            >
                              {savingId === String(prep.class_section_id) ? 'Saving…' : 'Save'}
                            </button>
                          </div>
                        </form>
                      </div>
                    </div>
                  </div>

                  <div className="card-footer bg-transparent border-0 d-flex justify-content-end">
                    <Link
                      to={`${printBase}/${encodeURIComponent(String(prep.class_section_id))}/${encodeURIComponent(schoolYear)}${semQuery}`}
                      className={`btn btn-lg ${prep.needs_print ? 'btn-danger' : 'btn-success'}`}
                      target="_blank"
                      rel="noopener noreferrer"
                    >
                      Print
                    </Link>
                  </div>
                </div>
              </div>
            )
          })}
        </div>

        <div className="mt-5">
          <h5 className="mb-3">Totals for All Used Items</h5>
          <div className="table-responsive">
            <table className="table table-sm table-bordered align-middle">
              <thead className="table-light">
                <tr>
                  <th>Item</th>
                  <th className="text-end">Total Needed</th>
                  <th className="text-end">In Inventory</th>
                  <th className="text-end">Short By</th>
                </tr>
              </thead>
              <tbody>
                {Object.entries(data?.total_needed ?? {}).map(([item, needed]) => {
                  const have = Number((data?.available ?? {})[item] ?? 0)
                  const short = Math.max(0, Number(needed) - have)
                  return (
                    <tr key={item} className={short > 0 ? 'table-warning' : ''}>
                      <td>{item}</td>
                      <td className="text-end">{Number(needed)}</td>
                      <td className="text-end">{have}</td>
                      <td
                        className={`text-end ${short > 0 ? 'text-danger fw-bold' : 'text-success'}`}
                      >
                        {short}
                      </td>
                    </tr>
                  )
                })}
              </tbody>
            </table>
          </div>

          {data?.shortages && Object.keys(data.shortages).length > 0 ? (
            <div className="alert alert-danger mt-3">
              <strong>Shortages Detected</strong>
              <ul className="mb-0">
                {Object.entries(data.shortages).map(([item, short]) => (
                  <li key={item}>
                    {item}: short by {Number(short)} pcs
                  </li>
                ))}
              </ul>
            </div>
          ) : data && Object.keys(data.total_needed ?? {}).length > 0 ? (
            <div className="alert alert-success mt-3">All items are available in stock.</div>
          ) : null}
        </div>
      </div>

      <style>{`
        .classprep-muted-soft { opacity: 0.55; }
        .classprep-card { border-radius: 12px; }
        .classprep-card .card-header {
          border-top-left-radius: 12px;
          border-top-right-radius: 12px;
        }
        .classprep-card .card-footer {
          border-bottom-left-radius: 12px;
          border-bottom-right-radius: 12px;
        }
      `}</style>
    </div>
  )
}
