import { type FormEvent, useEffect, useMemo, useState } from 'react'
import { useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import { useSchoolYearOptions } from '../../hooks/useSchoolYearOptions'
import { fetchSlipPreviewList, type SlipPreviewRow } from '../../api/slips'
import { displaySemester, formatPreviewDateKey } from './slipFormatting'
import { SLIPS_PRINT_PATH } from './slipPaths'

function groupRowsByDate(rows: SlipPreviewRow[]) {
  const groupedRows: Record<string, SlipPreviewRow[]> = {}
  const dateOrder: string[] = []
  for (const r of rows) {
    let dateKey = String(r.date ?? '').trim()
    if (!dateKey) dateKey = 'Unknown Date'
    if (!(dateKey in groupedRows)) {
      groupedRows[dateKey] = []
      dateOrder.push(dateKey)
    }
    groupedRows[dateKey].push(r)
  }
  const chartData = dateOrder.map((d) => groupedRows[d].length)
  const chartLabels = dateOrder.map((d) => formatPreviewDateKey(d))
  return { groupedRows, dateOrder, chartData, chartLabels }
}

function slipPrintSearchParams(row: SlipPreviewRow): string {
  const fields = [
    'student_name',
    'date',
    'time_in',
    'grade',
    'reason',
    'school_year',
    'semester',
    'admin_name',
  ] as const
  const qs = new URLSearchParams()
  for (const f of fields) {
    qs.set(f, String(row[f] ?? ''))
  }
  return qs.toString()
}

export function SlipPreviewListPage() {
  type SlipSortKey =
    | 'student_name'
    | 'time_in'
    | 'grade'
    | 'reason'
    | 'school_year'
    | 'semester'
    | 'admin_name'
  const [searchParams, setSearchParams] = useSearchParams()
  const schoolYear = searchParams.get('school_year') ?? ''
  const semester = searchParams.get('semester') ?? ''

  const [rows, setRows] = useState<SlipPreviewRow[]>([])
  const [error, setError] = useState<string | null>(null)
  const [expandedDates, setExpandedDates] = useState<Set<string>>(new Set())
  const [sortConfig, setSortConfig] = useState<{ key: SlipSortKey; direction: 'asc' | 'desc' }>({
    key: 'student_name',
    direction: 'asc',
  })
  const { options, selectedYear } = useSchoolYearOptions({
    preferredYear: schoolYear,
  })

  useEffect(() => {
    setError(null)
    fetchSlipPreviewList({
      school_year: schoolYear || undefined,
      semester: semester || undefined,
    })
      .then((d) => {
        const nextRows = d.rows ?? []
        setRows(nextRows)
        const dateKeys = new Set(
          nextRows.map((row) => {
            const raw = String(row.date ?? '').trim()
            return raw || 'Unknown Date'
          }),
        )
        setExpandedDates(dateKeys)
      })
      .catch((e: unknown) =>
        setError(e instanceof ApiHttpError ? e.message : 'Failed to load slips.'),
      )
  }, [schoolYear, semester])

  const { groupedRows, dateOrder, chartData, chartLabels } = useMemo(
    () => groupRowsByDate(rows),
    [rows],
  )

  const maxCount = Math.max(1, ...chartData)

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

  function openPrint(row: SlipPreviewRow) {
    const q = slipPrintSearchParams(row)
    window.open(`${SLIPS_PRINT_PATH}?${q}`, '_blank', 'noopener')
  }

  function toggleDate(dateKey: string) {
    setExpandedDates((prev) => {
      const next = new Set(prev)
      next.has(dateKey) ? next.delete(dateKey) : next.add(dateKey)
      return next
    })
  }

  function requestSort(key: SlipSortKey) {
    setSortConfig((prev) =>
      prev.key === key
        ? { key, direction: prev.direction === 'asc' ? 'desc' : 'asc' }
        : { key, direction: 'asc' },
    )
  }

  function sortIndicator(key: SlipSortKey) {
    if (sortConfig.key !== key) return '↕'
    return sortConfig.direction === 'asc' ? '↑' : '↓'
  }

  function sortRows(groupRows: SlipPreviewRow[]) {
    return [...groupRows].sort((left, right) => {
      const direction = sortConfig.direction === 'asc' ? 1 : -1
      const leftValue =
        sortConfig.key === 'semester'
          ? displaySemester(left.semester)
          : String(left[sortConfig.key] ?? '')
      const rightValue =
        sortConfig.key === 'semester'
          ? displaySemester(right.semester)
          : String(right[sortConfig.key] ?? '')
      return (
        leftValue.localeCompare(rightValue, undefined, {
          numeric: true,
          sensitivity: 'base',
        }) * direction
      )
    })
  }

  return (
    <div className="container-fluid px-0 py-4">
      <div className="d-flex align-items-center justify-content-between flex-wrap gap-2 mb-3">
        <div>
          <h2 className="mb-0">Late Slip Preview</h2>
          <small className="text-muted">View and print student late slips</small>
        </div>
      </div>

      <form className="row gy-2 gx-3 align-items-end mb-4" onSubmit={applyFilter}>
        <div className="col-md-4">
          <label className="form-label">School Year</label>
          <select name="school_year" className="form-select" defaultValue={schoolYear || selectedYear}>
            {(options.length > 0 ? options : [{ value: selectedYear, label: selectedYear }]).map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        </div>
        <div className="col-md-3">
          <label className="form-label">Semester</label>
          <select name="semester" className="form-select" defaultValue={semester}>
            <option value="">All Semesters</option>
            <option value="fall">Fall</option>
            <option value="spring">Spring</option>
          </select>
        </div>
        <div className="col-md-2">
          <button type="submit" className="btn btn-primary w-100">
            Filter
          </button>
        </div>
      </form>

      {error ? <div className="alert alert-danger">{error}</div> : null}

      {rows.length === 0 ? (
        <div className="alert alert-light border">No slips found.</div>
      ) : (
        <>
          <div className="row mb-4">
            <div className="col-12">
              <div className="card shadow-sm border-0">
                <div className="card-header bg-white py-3">
                  <h5 className="card-title mb-0 fw-bold text-primary">Late Statistics by Date</h5>
                </div>
                <div className="card-body">
                  <div style={{ width: '100%' }}>
                    <div
                      className="d-flex align-items-end gap-1 px-2 border-bottom"
                      style={{ height: 240 }}
                    >
                      {chartLabels.map((label, i) => {
                        const barH = Math.round((chartData[i] / maxCount) * 220)
                        return (
                          <div
                            key={label + i}
                            className="d-flex flex-column align-items-center flex-fill"
                            style={{ maxWidth: 90 }}
                          >
                            <div
                              className="w-100 rounded-top bg-primary bg-opacity-75"
                              style={{
                                height: barH,
                                minHeight: chartData[i] > 0 ? 6 : 0,
                              }}
                              title={`${label}: ${chartData[i]}`}
                            />
                          </div>
                        )
                      })}
                    </div>
                    <div className="d-flex gap-1 px-2 mt-1 flex-wrap justify-content-between">
                      {chartLabels.map((label, i) => (
                        <div
                          key={`lbl-${label}-${i}`}
                          className="small text-muted text-center text-truncate flex-fill"
                          style={{ fontSize: 10, maxWidth: 90 }}
                        >
                          {label}
                          <span className="d-block fw-semibold text-dark">{chartData[i]}</span>
                        </div>
                      ))}
                    </div>
                    <div className="small text-muted text-center mt-2">
                      Recorded Dates · Total slips per day
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>

          {dateOrder.map((dateKey) => {
            const groupRows = groupedRows[dateKey] ?? []
            const expanded = expandedDates.has(dateKey)
            const displayedRows = sortRows(groupRows)
            return (
              <div key={dateKey} className="card mb-4">
                <div
                  className="card-header d-flex align-items-center justify-content-between flex-wrap gap-2"
                  role="button"
                  style={{ cursor: 'pointer', userSelect: 'none' }}
                  onClick={() => toggleDate(dateKey)}
                >
                  <div className="fw-semibold">
                    {expanded ? '▼' : '▶'} Date: {formatPreviewDateKey(dateKey)}
                  </div>
                  <span className="badge bg-secondary">{groupRows.length} slips</span>
                </div>
                {expanded ? (
                  <div className="table-responsive">
                    <table className="table table-striped table-bordered align-middle w-100">
                      <thead className="table-light">
                        <tr>
                          <th>
                            <button type="button" className="btn btn-link btn-sm p-0 text-decoration-none" onClick={() => requestSort('student_name')}>
                              Student Name {sortIndicator('student_name')}
                            </button>
                          </th>
                          <th>
                            <button type="button" className="btn btn-link btn-sm p-0 text-decoration-none" onClick={() => requestSort('time_in')}>
                              Time In {sortIndicator('time_in')}
                            </button>
                          </th>
                          <th>
                            <button type="button" className="btn btn-link btn-sm p-0 text-decoration-none" onClick={() => requestSort('grade')}>
                              Grade {sortIndicator('grade')}
                            </button>
                          </th>
                          <th>
                            <button type="button" className="btn btn-link btn-sm p-0 text-decoration-none" onClick={() => requestSort('reason')}>
                              Reason {sortIndicator('reason')}
                            </button>
                          </th>
                          <th>
                            <button type="button" className="btn btn-link btn-sm p-0 text-decoration-none" onClick={() => requestSort('school_year')}>
                              School Year {sortIndicator('school_year')}
                            </button>
                          </th>
                          <th>
                            <button type="button" className="btn btn-link btn-sm p-0 text-decoration-none" onClick={() => requestSort('semester')}>
                              Semester {sortIndicator('semester')}
                            </button>
                          </th>
                          <th>
                            <button type="button" className="btn btn-link btn-sm p-0 text-decoration-none" onClick={() => requestSort('admin_name')}>
                              Admin Name {sortIndicator('admin_name')}
                            </button>
                          </th>
                          <th>Action</th>
                        </tr>
                      </thead>
                      <tbody>
                        {displayedRows.map((r, idx) => (
                          <tr key={idx}>
                            <td>{String(r.student_name ?? '')}</td>
                            <td>{String(r.time_in ?? '')}</td>
                            <td>{String(r.grade ?? '')}</td>
                            <td>{String(r.reason ?? '')}</td>
                            <td>{String(r.school_year ?? '')}</td>
                            <td>{displaySemester(r.semester)}</td>
                            <td>{String(r.admin_name ?? '')}</td>
                            <td>
                              <button
                                type="button"
                                className="btn btn-sm btn-primary"
                                onClick={() => openPrint(r)}
                              >
                                Print
                              </button>
                            </td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  </div>
                ) : null}
              </div>
            )
          })}
        </>
      )}
    </div>
  )
}
