import { Fragment, useCallback, useEffect, useMemo, useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import { ApiHttpError, apiFetch } from '../../api/http'
import { TeacherShell } from './TeacherShell'
import { useTeacherResource } from './useTeacherResource'

const CUSTOM_UNIT = 'Custom'

export type CurriculumRow = {
  unit_number?: number | null
  unit_title?: string | null
  chapter_name?: string | null
}

export type ClassProgressSubmitFormData = {
  subject_sections?: Record<string, { label?: string; db_subject?: string }>
  status_options?: Record<string, string>
  sunday_options?: string[]
  curriculum?: Record<string, CurriculumRow[]>
  classes?: Array<{
    class_section_id?: number
    class_section_name?: string
    class_id?: number | null
    class_name?: string | null
  }>
  defaults?: {
    class_id?: number | null
    class_section_id?: number | null
    school_year?: string | null
    semester?: string | null
    week_start?: string | null
  }
}

type UnitRow = {
  unitNumber: number | 'custom' | null
  chapter: string
}

function unwrapSubmitForm(raw: unknown): ClassProgressSubmitFormData | null {
  if (raw == null || typeof raw !== 'object') return null
  const o = raw as Record<string, unknown>
  const inner = o.data
  if (inner != null && typeof inner === 'object' && !Array.isArray(inner)) {
    return inner as ClassProgressSubmitFormData
  }
  return raw as ClassProgressSubmitFormData
}

function formatWeekLabel(iso: string): string {
  const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(iso)
  if (!m) return iso
  return `${m[2]}/${m[3]}/${m[1]}`
}

function unitChoices(curriculum: CurriculumRow[]): Array<{ value: number; label: string }> {
  const seen = new Map<number, string>()
  for (const r of curriculum) {
    const n = Number(r.unit_number ?? 0)
    if (!Number.isFinite(n) || n <= 0) continue
    if (!seen.has(n)) {
      const t = String(r.unit_title ?? '').trim()
      seen.set(n, t || `Unit ${n}`)
    }
  }
  return [...seen.entries()]
    .sort((a, b) => a[0] - b[0])
    .map(([value, label]) => ({ value, label }))
}

function chaptersForUnit(curriculum: CurriculumRow[], unitNumber: number): string[] {
  const out: string[] = []
  const seen = new Set<string>()
  for (const r of curriculum) {
    if (Number(r.unit_number ?? 0) !== unitNumber) continue
    const ch = String(r.chapter_name ?? '').trim()
    if (ch && !seen.has(ch)) {
      seen.add(ch)
      out.push(ch)
    }
  }
  return out
}

function unitLabelForPayload(curriculum: CurriculumRow[], unitNumber: number): string {
  for (const r of curriculum) {
    if (Number(r.unit_number ?? 0) === unitNumber) {
      const t = String(r.unit_title ?? '').trim()
      if (t) return t
    }
  }
  return `Unit ${unitNumber}`
}

function islamicSelectionValid(rows: UnitRow[]): boolean {
  for (const r of rows) {
    const ch = r.chapter.trim()
    if (r.unitNumber === 'custom' && ch !== '') return true
    if (typeof r.unitNumber === 'number' && r.unitNumber > 0 && ch !== '') return true
    if (typeof r.unitNumber === 'number' && r.unitNumber > 0 && ch === '') continue
  }
  return false
}

function appendArray(fd: FormData, key: string, values: string[]) {
  values.forEach((v, i) => {
    fd.append(`${key}[${i}]`, v)
  })
}

/** `teacher/class_progress_submit.php` — weekly progress form; POST `/api/v1/teacher/class-progress-submit`. */
export function TeacherClassProgressSubmitPage() {
  const [search] = useSearchParams()
  const classIdQ = search.get('class_id')
  const path = useMemo(() => {
    const params = new URLSearchParams()
    if (classIdQ) params.set('class_id', classIdQ)
    const q = params.toString()
    return `/class-progress-submit${q ? `?${q}` : ''}`
  }, [classIdQ])

  const { data: raw, loading, error, reload } = useTeacherResource<unknown>(path)
  const data = useMemo(() => unwrapSubmitForm(raw), [raw])

  const subjectSections = data?.subject_sections ?? {}
  const slugs = useMemo(() => Object.keys(subjectSections), [subjectSections])
  const sundayOptions = data?.sunday_options ?? []
  const classes = data?.classes ?? []
  const defaults = data?.defaults ?? {}
  const curriculumIslamic = data?.curriculum?.islamic ?? []
  const curriculumQuran = data?.curriculum?.quran ?? []

  const unitPickList = useMemo(() => unitChoices(curriculumIslamic), [curriculumIslamic])

  const classIds = useMemo(() => {
    const s = new Set<number>()
    for (const c of classes) {
      const id = Number(c.class_id ?? 0)
      if (id > 0) s.add(id)
    }
    return [...s].sort((a, b) => a - b)
  }, [classes])

  const [weekStart, setWeekStart] = useState('')
  const [classSectionId, setClassSectionId] = useState<number | ''>('')
  const [covered, setCovered] = useState<Record<string, string>>({})
  const [homework, setHomework] = useState<Record<string, string>>({})
  const [islamicRows, setIslamicRows] = useState<UnitRow[]>([{ unitNumber: null, chapter: '' }])
  const [quranRows, setQuranRows] = useState<UnitRow[]>([{ unitNumber: null, chapter: '' }])
  const [attachmentIslamic, setAttachmentIslamic] = useState<File[]>([])
  const [attachmentQuran, setAttachmentQuran] = useState<File[]>([])
  const [confirmOverwrite, setConfirmOverwrite] = useState(false)

  const [submitting, setSubmitting] = useState(false)
  const [submitError, setSubmitError] = useState<string | null>(null)
  const [submitOk, setSubmitOk] = useState<string | null>(null)

  useEffect(() => {
    if (!data) return
    const ws = defaults.week_start ?? sundayOptions[0] ?? ''
    setWeekStart(ws)
    const sid = Number(defaults.class_section_id ?? 0)
    setClassSectionId(sid > 0 ? sid : '')
    setCovered({})
    setHomework({})
    setIslamicRows([{ unitNumber: null, chapter: '' }])
    setQuranRows([{ unitNumber: null, chapter: '' }])
    setAttachmentIslamic([])
    setAttachmentQuran([])
    setConfirmOverwrite(false)
    setSubmitError(null)
    setSubmitOk(null)
  }, [data, defaults.class_section_id, defaults.week_start, sundayOptions])

  const resolvedClassId = useMemo(() => {
    const fromQ = classIdQ ? Number(classIdQ) : 0
    if (fromQ > 0) return fromQ
    return Number(defaults.class_id ?? 0)
  }, [classIdQ, defaults.class_id])

  const sectionsForClass = useMemo(() => {
    if (!resolvedClassId) return classes
    return classes.filter((c) => Number(c.class_id ?? 0) === resolvedClassId)
  }, [classes, resolvedClassId])

  useEffect(() => {
    if (classSectionId === '' && sectionsForClass.length === 1) {
      const only = Number(sectionsForClass[0].class_section_id ?? 0)
      if (only > 0) setClassSectionId(only)
    }
  }, [sectionsForClass, classSectionId])

  const canSubmit = useMemo(() => {
    if (!weekStart || !classSectionId) return false
    if (!islamicSelectionValid(islamicRows)) return false
    const covIslamic = (covered.islamic ?? '').trim()
    if (covIslamic === '') return false
    return true
  }, [weekStart, classSectionId, islamicRows, covered])

  const updateIslamicRow = useCallback((idx: number, patch: Partial<UnitRow>) => {
    setIslamicRows((prev) => prev.map((r, i) => (i === idx ? { ...r, ...patch } : r)))
  }, [])

  const updateQuranRow = useCallback((idx: number, patch: Partial<UnitRow>) => {
    setQuranRows((prev) => prev.map((r, i) => (i === idx ? { ...r, ...patch } : r)))
  }, [])

  const handleSubmit = useCallback(async () => {
    setSubmitError(null)
    setSubmitOk(null)
    if (!canSubmit || classSectionId === '') return

    const unitIslamic: string[] = []
    const chapterIslamic: string[] = []
    for (const r of islamicRows) {
      const ch = r.chapter.trim()
      if (r.unitNumber === 'custom') {
        if (ch === '') continue
        unitIslamic.push(CUSTOM_UNIT)
        chapterIslamic.push(ch)
      } else if (typeof r.unitNumber === 'number' && r.unitNumber > 0) {
        if (ch === '') continue
        unitIslamic.push(unitLabelForPayload(curriculumIslamic, r.unitNumber))
        chapterIslamic.push(ch)
      }
    }

    const unitQuran: string[] = []
    const chapterQuran: string[] = []
    for (const r of quranRows) {
      const ch = r.chapter.trim()
      if (r.unitNumber === 'custom' && ch !== '') {
        unitQuran.push(CUSTOM_UNIT)
        chapterQuran.push(ch)
      } else if (typeof r.unitNumber === 'number' && r.unitNumber > 0 && ch !== '') {
        unitQuran.push(unitLabelForPayload(curriculumQuran, r.unitNumber))
        chapterQuran.push(ch)
      }
    }

    const fd = new FormData()
    fd.append('class_section_id', String(classSectionId))
    fd.append('week_start', weekStart)
    if (confirmOverwrite) fd.append('confirm_overwrite', '1')

    for (const slug of slugs) {
      const cov = (covered[slug] ?? '').trim()
      const hw = (homework[slug] ?? '').trim()
      fd.append(`covered_${slug}`, cov)
      if (hw) fd.append(`homework_${slug}`, hw)
    }

    appendArray(fd, 'unit_islamic', unitIslamic)
    appendArray(fd, 'chapter_islamic', chapterIslamic)
    appendArray(fd, 'unit_quran', unitQuran)
    appendArray(fd, 'chapter_quran', chapterQuran)

    attachmentIslamic.forEach((f) => fd.append('attachment_islamic[]', f))
    attachmentQuran.forEach((f) => fd.append('attachment_quran[]', f))

    setSubmitting(true)
    try {
      const res = await apiFetch<{ status?: boolean; message?: string }>('/api/v1/teacher/class-progress-submit', {
        method: 'POST',
        body: fd,
      })
      setSubmitOk(typeof res?.message === 'string' ? res.message : 'Progress saved.')
      setConfirmOverwrite(false)
      reload()
    } catch (e: unknown) {
      if (e instanceof ApiHttpError && e.status === 409) {
        setSubmitError(
          'A report already exists for this week. Check “Replace existing week” and submit again to overwrite.',
        )
        return
      }
      const msg = e instanceof ApiHttpError ? e.message : 'Unable to save progress.'
      setSubmitError(msg)
    } finally {
      setSubmitting(false)
    }
  }, [
    canSubmit,
    classSectionId,
    weekStart,
    confirmOverwrite,
    slugs,
    covered,
    homework,
    islamicRows,
    quranRows,
    curriculumIslamic,
    curriculumQuran,
    attachmentIslamic,
    attachmentQuran,
    reload,
  ])

  const subtitleParts = [defaults.school_year, defaults.semester].filter(Boolean).join(' · ')

  return (
    <TeacherShell
      title="Submit class progress"
      subtitle={subtitleParts || undefined}
      loading={loading}
      error={error}
    >
      {!loading && raw != null && data == null ? (
        <div className="alert alert-warning">
          Unexpected response shape.
          <pre className="small mb-0 mt-2 bg-light p-2 rounded overflow-auto" style={{ maxHeight: 200 }}>
            {JSON.stringify(raw, null, 2)}
          </pre>
        </div>
      ) : null}

      {data ? (
        <div className="d-flex flex-column gap-4">
          <div className="d-flex flex-wrap justify-content-end gap-2">
            <Link to="/app/teacher/class-progress-history" className="btn btn-outline-primary btn-sm">
              Past submissions
            </Link>
          </div>
          {classes.length === 0 ? (
            <div className="alert alert-info mb-0">
              You have no class assignments for the current term, so progress cannot be submitted.
            </div>
          ) : null}

          {classes.length > 0 && classIds.length > 1 ? (
            <div className="d-flex flex-wrap align-items-center gap-2">
              <span className="small text-muted me-1">Class:</span>
              {classIds.map((id) => {
                const label =
                  classes.find((c) => Number(c.class_id) === id)?.class_name?.trim() || `Class ${id}`
                const active = resolvedClassId === id
                return (
                  <Link
                    key={id}
                    to={`/app/teacher/class-progress-submit?class_id=${encodeURIComponent(String(id))}`}
                    className={`btn btn-sm ${active ? 'btn-primary' : 'btn-outline-primary'}`}
                  >
                    {label}
                  </Link>
                )
              })}
            </div>
          ) : null}

          {submitOk ? (
            <div className="alert alert-success py-2 mb-0" role="status">
              {submitOk}
            </div>
          ) : null}
          {submitError ? (
            <div className="alert alert-danger py-2 mb-0" role="alert">
              {submitError}
            </div>
          ) : null}

          {classes.length > 0 ? (
            <>
          <section className="border rounded p-3 bg-white">
            <h2 className="h6 mb-3">Week &amp; section</h2>
            <div className="row g-3">
              <div className="col-md-6">
                <label className="form-label" htmlFor="cp-week-start">
                  Week (Sunday start)
                </label>
                <select
                  id="cp-week-start"
                  className="form-select form-select-sm"
                  value={weekStart}
                  onChange={(e) => setWeekStart(e.target.value)}
                >
                  {sundayOptions.length === 0 ? <option value="">No dates configured</option> : null}
                  {sundayOptions.map((d) => (
                    <option key={d} value={d}>
                      {formatWeekLabel(d)}
                    </option>
                  ))}
                </select>
              </div>
              <div className="col-md-6">
                <label className="form-label" htmlFor="cp-section">
                  Class section
                </label>
                <select
                  id="cp-section"
                  className="form-select form-select-sm"
                  value={classSectionId === '' ? '' : String(classSectionId)}
                  onChange={(e) => setClassSectionId(e.target.value ? Number(e.target.value) : '')}
                >
                  <option value="">Select section…</option>
                  {sectionsForClass.map((c) => {
                    const id = Number(c.class_section_id ?? 0)
                    if (!id) return null
                    const name = String(c.class_section_name ?? '').trim() || `Section ${id}`
                    return (
                      <option key={id} value={id}>
                        {name}
                      </option>
                    )
                  })}
                </select>
              </div>
            </div>
          </section>

          <section className="border rounded p-3 bg-white">
            <h2 className="h6 mb-1">Islamic Studies — units / chapters</h2>
            <p className="small text-muted mb-3">
              Select at least one unit/chapter pair (or Custom + description). Required before submit.
            </p>
            <div className="d-flex flex-column gap-2">
              {islamicRows.map((row, idx) => (
                <div key={`is-${idx}`} className="row g-2 align-items-end">
                  <div className="col-md-5">
                    <label className="form-label small mb-0">Unit</label>
                    <select
                      className="form-select form-select-sm"
                      value={
                        row.unitNumber === 'custom'
                          ? 'custom'
                          : row.unitNumber != null
                            ? String(row.unitNumber)
                            : ''
                      }
                      onChange={(e) => {
                        const v = e.target.value
                        if (v === '') updateIslamicRow(idx, { unitNumber: null, chapter: '' })
                        else if (v === 'custom') updateIslamicRow(idx, { unitNumber: 'custom', chapter: '' })
                        else updateIslamicRow(idx, { unitNumber: Number(v), chapter: '' })
                      }}
                    >
                      <option value="">—</option>
                      {unitPickList.map((u) => (
                        <option key={u.value} value={u.value}>
                          {u.label}
                        </option>
                      ))}
                      <option value="custom">{CUSTOM_UNIT}</option>
                    </select>
                  </div>
                  <div className="col-md-5">
                    <label className="form-label small mb-0">Chapter / detail</label>
                    {row.unitNumber != null &&
                    row.unitNumber !== 'custom' &&
                    typeof row.unitNumber === 'number' &&
                    chaptersForUnit(curriculumIslamic, row.unitNumber).length > 0 ? (
                      <select
                        className="form-select form-select-sm"
                        value={row.chapter}
                        onChange={(e) => updateIslamicRow(idx, { chapter: e.target.value })}
                      >
                        <option value="">—</option>
                        {chaptersForUnit(curriculumIslamic, row.unitNumber).map((ch) => (
                          <option key={ch} value={ch}>
                            {ch}
                          </option>
                        ))}
                      </select>
                    ) : (
                      <input
                        type="text"
                        className="form-control form-control-sm"
                        value={row.chapter}
                        onChange={(e) => updateIslamicRow(idx, { chapter: e.target.value })}
                        placeholder={row.unitNumber === 'custom' ? 'Describe custom topic…' : 'Chapter or detail'}
                      />
                    )}
                  </div>
                  <div className="col-md-2 d-flex gap-1">
                    <button
                      type="button"
                      className="btn btn-outline-secondary btn-sm"
                      onClick={() =>
                        setIslamicRows((prev) => [...prev.slice(0, idx + 1), { unitNumber: null, chapter: '' }, ...prev.slice(idx + 1)])
                      }
                    >
                      + Row
                    </button>
                    {islamicRows.length > 1 ? (
                      <button
                        type="button"
                        className="btn btn-outline-danger btn-sm"
                        onClick={() => setIslamicRows((prev) => prev.filter((_, i) => i !== idx))}
                      >
                        ×
                      </button>
                    ) : null}
                  </div>
                </div>
              ))}
            </div>
          </section>

          {slugs.map((slug) => {
            const label = subjectSections[slug]?.label ?? slug
            const attKey = slug === 'islamic' ? attachmentIslamic : attachmentQuran
            const setAtt = slug === 'islamic' ? setAttachmentIslamic : setAttachmentQuran
            return (
              <Fragment key={slug}>
                {slug === 'quran' && curriculumQuran.length > 0 ? (
                  <section className="border rounded p-3 bg-white mb-3">
                    <h2 className="h6 mb-1">Quran / Arabic — units / chapters (optional)</h2>
                    <p className="small text-muted mb-3">Optional rows when curriculum is available.</p>
                    <div className="d-flex flex-column gap-2">
                      {quranRows.map((row, idx) => {
                        const qUnits = unitChoices(curriculumQuran)
                        return (
                          <div key={`qr-${idx}`} className="row g-2 align-items-end">
                            <div className="col-md-5">
                              <label className="form-label small mb-0">Unit</label>
                              <select
                                className="form-select form-select-sm"
                                value={
                                  row.unitNumber === 'custom'
                                    ? 'custom'
                                    : row.unitNumber != null
                                      ? String(row.unitNumber)
                                      : ''
                                }
                                onChange={(e) => {
                                  const v = e.target.value
                                  if (v === '') updateQuranRow(idx, { unitNumber: null, chapter: '' })
                                  else if (v === 'custom') updateQuranRow(idx, { unitNumber: 'custom', chapter: '' })
                                  else updateQuranRow(idx, { unitNumber: Number(v), chapter: '' })
                                }}
                              >
                                <option value="">—</option>
                                {qUnits.map((u) => (
                                  <option key={u.value} value={u.value}>
                                    {u.label}
                                  </option>
                                ))}
                                <option value="custom">{CUSTOM_UNIT}</option>
                              </select>
                            </div>
                            <div className="col-md-5">
                              <label className="form-label small mb-0">Chapter / detail</label>
                              {row.unitNumber != null &&
                              row.unitNumber !== 'custom' &&
                              typeof row.unitNumber === 'number' &&
                              chaptersForUnit(curriculumQuran, row.unitNumber).length > 0 ? (
                                <select
                                  className="form-select form-select-sm"
                                  value={row.chapter}
                                  onChange={(e) => updateQuranRow(idx, { chapter: e.target.value })}
                                >
                                  <option value="">—</option>
                                  {chaptersForUnit(curriculumQuran, row.unitNumber).map((ch) => (
                                    <option key={ch} value={ch}>
                                      {ch}
                                    </option>
                                  ))}
                                </select>
                              ) : (
                                <input
                                  type="text"
                                  className="form-control form-control-sm"
                                  value={row.chapter}
                                  onChange={(e) => updateQuranRow(idx, { chapter: e.target.value })}
                                  placeholder="Chapter or custom text…"
                                />
                              )}
                            </div>
                            <div className="col-md-2 d-flex gap-1">
                              <button
                                type="button"
                                className="btn btn-outline-secondary btn-sm"
                                onClick={() =>
                                  setQuranRows((prev) => [
                                    ...prev.slice(0, idx + 1),
                                    { unitNumber: null, chapter: '' },
                                    ...prev.slice(idx + 1),
                                  ])
                                }
                              >
                                + Row
                              </button>
                              {quranRows.length > 1 ? (
                                <button
                                  type="button"
                                  className="btn btn-outline-danger btn-sm"
                                  onClick={() => setQuranRows((prev) => prev.filter((_, i) => i !== idx))}
                                >
                                  ×
                                </button>
                              ) : null}
                            </div>
                          </div>
                        )
                      })}
                    </div>
                  </section>
                ) : null}
              <section className="border rounded p-3 bg-white">
                <h2 className="h6 mb-3">{label}</h2>
                <div className="mb-2">
                  <label className="form-label small" htmlFor={`covered-${slug}`}>
                    Material covered <span className="text-danger">{slug === 'islamic' ? '*' : ''}</span>
                  </label>
                  <textarea
                    id={`covered-${slug}`}
                    className="form-control form-control-sm"
                    rows={3}
                    value={covered[slug] ?? ''}
                    onChange={(e) => setCovered((p) => ({ ...p, [slug]: e.target.value }))}
                    placeholder="Topics taught this week…"
                  />
                </div>
                <div className="mb-2">
                  <label className="form-label small" htmlFor={`hw-${slug}`}>
                    Homework
                  </label>
                  <textarea
                    id={`hw-${slug}`}
                    className="form-control form-control-sm"
                    rows={2}
                    value={homework[slug] ?? ''}
                    onChange={(e) => setHomework((p) => ({ ...p, [slug]: e.target.value }))}
                  />
                </div>
                <div>
                  <label className="form-label small" htmlFor={`att-${slug}`}>
                    Attachment (PDF or image)
                  </label>
                  <input
                    id={`att-${slug}`}
                    type="file"
                    className="form-control form-control-sm"
                    accept=".pdf,.png,.jpg,.jpeg,image/*,application/pdf"
                    multiple
                    onChange={(e) => setAtt(Array.from(e.target.files ?? []))}
                  />
                  {attKey.length > 0 ? (
                    <div className="small text-muted mt-1">{attKey.map((f) => f.name).join(', ')}</div>
                  ) : null}
                </div>
              </section>
              </Fragment>
            )
          })}

          <div className="form-check mb-2">
            <input
              id="cp-overwrite"
              type="checkbox"
              className="form-check-input"
              checked={confirmOverwrite}
              onChange={(e) => setConfirmOverwrite(e.target.checked)}
            />
            <label className="form-check-label" htmlFor="cp-overwrite">
              Replace existing progress for this week (overwrite)
            </label>
          </div>

          <div className="d-flex flex-wrap gap-2 align-items-center">
            <button
              type="button"
              className="btn btn-primary"
              disabled={!canSubmit || submitting}
              onClick={() => void handleSubmit()}
            >
              {submitting ? 'Saving…' : 'Submit progress'}
            </button>
            <button type="button" className="btn btn-outline-secondary btn-sm" onClick={() => reload()}>
              Reload form
            </button>
            {!canSubmit ? (
              <span className="small text-muted">
                Choose section, week, Islamic unit/chapter, and material covered for Islamic Studies.
              </span>
            ) : null}
          </div>
            </>
          ) : null}
        </div>
      ) : null}
    </TeacherShell>
  )
}
