import { useEffect, useMemo, useRef, useState } from 'react'
import { useSearchParams } from 'react-router-dom'
import { ApiHttpError } from '../../api/http'
import {
  fetchCommunicationsCompose,
  fetchFamilyGuardians,
  fetchStudentFamilies,
  previewCommunicationsEmail,
  sendCommunicationsEmail,
} from '../../api/session'
import type { CommunicationsStudentOption } from '../../api/types'
import { useAuth } from '../../auth/AuthProvider'

export function CommunicationsIndexPage() {
  const { user } = useAuth()
  const [searchParams] = useSearchParams()
  const preStudent = searchParams.get('student_id')
  const preTemplate = searchParams.get('template_key') ?? ''

  const [students, setStudents] = useState<CommunicationsStudentOption[]>([])
  const [templates, setTemplates] = useState<{ template_key: string; name?: string | null }[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  const [studentId, setStudentId] = useState('')
  const [familyId, setFamilyId] = useState('')
  const [familyOptions, setFamilyOptions] = useState<{ id: number; label: string }[]>([])
  const [loadingFamilies, setLoadingFamilies] = useState(false)
  const [templateKey, setTemplateKey] = useState(preTemplate)

  const [recipients, setRecipients] = useState<string[]>([])
  const [subject, setSubject] = useState('')
  const [body, setBody] = useState('')
  const [busy, setBusy] = useState(false)
  const [sendMsg, setSendMsg] = useState<string | null>(null)
  const prefillDone = useRef<string | null>(null)

  useEffect(() => {
    let cancelled = false
    fetchCommunicationsCompose()
      .then((ctx) => {
        if (cancelled) return
        setStudents(ctx.students ?? [])
        setTemplates(ctx.templates ?? [])
      })
      .catch((e: unknown) => {
        if (!cancelled)
          setError(e instanceof ApiHttpError ? e.message : 'Failed to load compose options.')
      })
      .finally(() => {
        if (!cancelled) setLoading(false)
      })
    return () => {
      cancelled = true
    }
  }, [])

  useEffect(() => {
    prefillDone.current = null
  }, [preStudent])

  async function loadGuardians(fid: string) {
    setRecipients([])
    if (!fid) return
    try {
      const res = await fetchFamilyGuardians(Number(fid))
      const list = (res as { data?: unknown }).data
      const rows = Array.isArray(list) ? list : []
      const emails: string[] = []
      for (const g of rows as { email?: string | null; receive_emails?: boolean }[]) {
        if (g.receive_emails && g.email) emails.push(g.email.trim())
      }
      setRecipients([...new Set(emails)])
    } catch {
      setRecipients([])
    }
  }

  async function loadFamilies(sid: string) {
    setFamilyId('')
    setRecipients([])
    setFamilyOptions([])
    if (!sid) return
    setLoadingFamilies(true)
    try {
      const res = await fetchStudentFamilies(Number(sid))
      const list = (res as { data?: unknown }).data
      const rows = Array.isArray(list) ? list : []
      const mapped = rows.map((f: { id?: number; household_name?: string; is_primary_home?: boolean }) => ({
        id: Number(f.id),
        label:
          (f.household_name?.trim() || '') !== ''
            ? String(f.household_name)
            : `Family #${f.id}` + (f.is_primary_home ? ' (primary)' : ''),
      }))
      setFamilyOptions(mapped)
      if (mapped.length > 0) {
        const first = String(mapped[0]!.id)
        setFamilyId(first)
        void loadGuardians(first)
      }
    } catch {
      setFamilyOptions([])
    } finally {
      setLoadingFamilies(false)
    }
  }

  useEffect(() => {
    if (!preStudent || students.length === 0) return
    if (!students.some((s) => String(s.id) === preStudent)) return
    if (prefillDone.current === preStudent) return
    prefillDone.current = preStudent
    setStudentId(preStudent)
    void loadFamilies(preStudent)
  }, [preStudent, students])

  async function refreshPreview() {
    if (!studentId || !familyId || !templateKey) return
    setBusy(true)
    setSendMsg(null)
    try {
      const vars: Record<string, string> = {
        school_name: 'Al Rahma Sunday School',
        teacher_name: user?.name ?? 'Teacher',
        class_section: '',
        student_grade: '',
        attendance_message: '',
        assessment_name: '',
        score_obtained: '',
        score_total: '',
        teacher_comments: '',
        behavior_summary: '',
        actions_taken: '',
        next_steps: '',
      }
      const data = await previewCommunicationsEmail({
        student_id: Number(studentId),
        family_id: Number(familyId),
        template_key: templateKey,
        vars,
      })
      if (data.subject) setSubject(data.subject)
      if (data.html)
        setBody(data.html.replace(/<br\s*\/?>/gi, '\n'))
    } catch (e: unknown) {
      setSendMsg(e instanceof ApiHttpError ? e.message : 'Preview failed.')
    } finally {
      setBusy(false)
    }
  }

  async function onSend(e: React.FormEvent) {
    e.preventDefault()
    if (!studentId || !familyId || !templateKey || !subject.trim()) return
    setBusy(true)
    setSendMsg(null)
    try {
      await sendCommunicationsEmail({
        student_id: Number(studentId),
        family_id: Number(familyId),
        template_key: templateKey,
        subject: subject.trim(),
        body,
        recipients,
      })
      setSendMsg('Message sent.')
    } catch (err: unknown) {
      setSendMsg(err instanceof ApiHttpError ? err.message : 'Send failed.')
    } finally {
      setBusy(false)
    }
  }

  function removeRecipient(email: string) {
    setRecipients((r) => r.filter((x) => x !== email))
  }

  const previewSafe = useMemo(() => ({ __html: body.replace(/\n/g, '<br/>') }), [body])

  return (
    <div className="container my-4">
      <h2 className="mb-3">Family Communications</h2>

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

      <div className="card">
        <div className="card-header">Compose</div>
        <div className="card-body">
          <form id="comm-form" onSubmit={onSend}>
            <div className="row g-3">
              <div className="col-md-4">
                <label className="form-label" htmlFor="student_id">
                  Student
                </label>
                <select
                  className="form-select"
                  id="student_id"
                  name="student_id"
                  required
                  value={studentId}
                  onChange={(ev) => {
                    const v = ev.target.value
                    setStudentId(v)
                    void loadFamilies(v)
                  }}
                >
                  <option value="">Select…</option>
                  {students.map((st) => (
                    <option key={st.id} value={st.id}>
                      {[st.lastname, st.firstname].filter(Boolean).join(', ') || `Student ${st.id}`}
                    </option>
                  ))}
                </select>
              </div>
              <div className="col-md-4">
                <label className="form-label" htmlFor="family_id">
                  Family (if multiple)
                </label>
                <select
                  className="form-select"
                  id="family_id"
                  name="family_id"
                  required
                  disabled={!studentId || loadingFamilies}
                  value={familyId}
                  onChange={(ev) => {
                    const v = ev.target.value
                    setFamilyId(v)
                    void loadGuardians(v)
                  }}
                >
                  <option value="">{studentId ? 'Select…' : 'Select a student first…'}</option>
                  {familyOptions.map((f) => (
                    <option key={f.id} value={f.id}>
                      {f.label}
                    </option>
                  ))}
                </select>
              </div>
              <div className="col-md-4">
                <label className="form-label" htmlFor="template_key">
                  Subject Category
                </label>
                <select
                  className="form-select"
                  id="template_key"
                  name="template_key"
                  required
                  value={templateKey}
                  onChange={(ev) => setTemplateKey(ev.target.value)}
                >
                  <option value="">Select…</option>
                  {templates.map((t) => (
                    <option key={t.template_key} value={t.template_key}>
                      {(t.name?.trim() || t.template_key) as string}
                    </option>
                  ))}
                </select>
              </div>
            </div>

            <div className="mt-3">
              <label className="form-label">Recipients (Guardians)</label>
              <div className="d-flex flex-wrap gap-2">
                {recipients.map((em) => (
                  <span key={em} className="badge bg-light text-dark border">
                    {em}{' '}
                    <button
                      type="button"
                      className="btn btn-sm btn-link p-0 ms-1"
                      onClick={() => removeRecipient(em)}
                      aria-label={`Remove ${em}`}
                    >
                      ×
                    </button>
                  </span>
                ))}
              </div>
            </div>

            <hr />
            <div className="row g-3">
              <div className="col-md-8">
                <label className="form-label" htmlFor="subject">
                  Email Subject
                </label>
                <input
                  type="text"
                  className="form-control"
                  id="subject"
                  name="subject"
                  required
                  value={subject}
                  onChange={(ev) => setSubject(ev.target.value)}
                />
              </div>
              <div className="col-md-4 d-flex align-items-end">
                <button
                  type="button"
                  className="btn btn-outline-secondary ms-auto"
                  disabled={busy}
                  onClick={() => void refreshPreview()}
                >
                  Refresh Preview
                </button>
              </div>
              <div className="col-12">
                <label className="form-label" htmlFor="body">
                  Email Body (editable)
                </label>
                <textarea
                  className="form-control"
                  id="body"
                  name="body"
                  rows={10}
                  required
                  value={body}
                  onChange={(ev) => setBody(ev.target.value)}
                />
              </div>
            </div>

            {sendMsg ? (
              <div
                className={`alert mt-3 py-2 ${sendMsg.includes('fail') ? 'alert-danger' : 'alert-success'}`}
              >
                {sendMsg}
              </div>
            ) : null}

            <div className="mt-3 d-flex gap-2">
              <button type="submit" className="btn btn-primary" disabled={busy}>
                Send
              </button>
              <button
                type="button"
                className="btn btn-outline-primary"
                data-bs-toggle="modal"
                data-bs-target="#communicationsPreviewModal"
              >
                Preview
              </button>
            </div>
          </form>
        </div>
      </div>

      <div className="modal fade" id="communicationsPreviewModal" tabIndex={-1}>
        <div className="modal-dialog modal-lg modal-dialog-scrollable">
          <div className="modal-content">
            <div className="modal-header">
              <h5 className="modal-title">Email Preview</h5>
              <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close" />
            </div>
            <div className="modal-body">
              <h6 className="mb-3">{subject}</h6>
              <div dangerouslySetInnerHTML={previewSafe} />
            </div>
            <div className="modal-footer">
              <button type="button" className="btn btn-secondary" data-bs-dismiss="modal">
                Close
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}
