'use client';

import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useCallback, useEffect, useState } from 'react';
import { RequireRole, useAuth } from '@/lib/auth-context';
import {
  createExam,
  Exam,
  EXAM_STATUS_BADGES,
  EXAM_STATUS_LABELS,
  EXAM_TYPE_LABELS,
  ExamStatus,
  ExamType,
  listExams,
} from '@/lib/services/exams';
import { listDentists } from '@/lib/services/dentists';
import type { Dentist } from '@/lib/types';
import PatientSelect from '@/components/app/PatientSelect';
import {
  EmptyState,
  ErrorAlert,
  Loading,
  Modal,
  PageHeader,
  Pagination,
  formatDate,
  formatDateTime,
} from '@/components/app/ui';
import { extractApiError } from '@/lib/api-client';

export default function ExamesPage() {
  return (
    <RequireRole roles={['admin', 'receptionist', 'dentist']}>
      <ExamsView />
    </RequireRole>
  );
}

const PAGE_SIZE = 15;

function ExamsView() {
  const { user } = useAuth();
  const router = useRouter();
  const isAdmin = user?.role === 'admin';
  const canRequest = isAdmin || user?.role === 'dentist';

  const [items, setItems] = useState<Exam[]>([]);
  const [total, setTotal] = useState(0);
  const [totalPages, setTotalPages] = useState(1);
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState('');
  const [term, setTerm] = useState('');
  const [status, setStatus] = useState<ExamStatus | ''>('');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [open, setOpen] = useState(false);
  const [dentists, setDentists] = useState<Dentist[]>([]);
  const [patientId, setPatientId] = useState<number | ''>('');
  const [dentistId, setDentistId] = useState<number | ''>('');
  const [name, setName] = useState('');
  const [type, setType] = useState<ExamType>('imaging');
  const [instructions, setInstructions] = useState('');
  const [saving, setSaving] = useState(false);
  const [formError, setFormError] = useState<string | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await listExams({
        page,
        limit: PAGE_SIZE,
        search: term || undefined,
        status: status || undefined,
      });
      setItems(result.data);
      setTotal(result.total);
      setTotalPages(Math.max(result.totalPages, 1));
    } catch (err) {
      setError(extractApiError(err));
    } finally {
      setLoading(false);
    }
  }, [page, term, status]);

  useEffect(() => {
    load();
  }, [load]);

  useEffect(() => {
    if (!isAdmin) return;
    listDentists({ limit: 100 })
      .then((r) => setDentists(r.data.filter((d) => d.isActive)))
      .catch(() => setDentists([]));
  }, [isAdmin]);

  async function handleCreate(e: React.FormEvent) {
    e.preventDefault();
    if (!patientId) return setFormError('Selecione o paciente.');
    if (isAdmin && !dentistId) return setFormError('Selecione o dentista solicitante.');
    if (name.trim().length < 3) return setFormError('Informe o exame.');
    setSaving(true);
    setFormError(null);
    try {
      const exam = await createExam({
        patientId,
        requestedByDentistId: isAdmin ? Number(dentistId) : undefined,
        name: name.trim(),
        type,
        instructions: instructions.trim() || undefined,
      });
      router.push(`/painel/exames/${exam.id}`);
    } catch (err) {
      setFormError(extractApiError(err));
      setSaving(false);
    }
  }

  return (
    <>
      <PageHeader
        title="Exames"
        subtitle="Pedidos, marcações e resultados"
        action={
          canRequest && (
            <button type="button" className="btn btn-primary" onClick={() => setOpen(true)}>
              <i className="bi bi-plus-lg me-1" />
              Pedir exame
            </button>
          )
        }
      />

      {user?.role === 'receptionist' && (
        <div className="alert alert-light border small">
          <i className="bi bi-shield-lock me-1" aria-hidden="true" />
          Por serem dados de saúde, laudos e arquivos de resultado ficam visíveis só para dentistas,
          administração e o próprio paciente.
        </div>
      )}

      <form
        className="row g-2 mb-3"
        onSubmit={(e) => {
          e.preventDefault();
          setPage(1);
          setTerm(search.trim());
        }}
      >
        <div className="col-12 col-md-5">
          <div className="input-group">
            <span className="input-group-text">
              <i className="bi bi-search" />
            </span>
            <input
              className="form-control"
              placeholder="Paciente ou exame"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              aria-label="Buscar exame"
            />
          </div>
        </div>
        <div className="col-8 col-md-3">
          <select
            className="form-select"
            aria-label="Filtrar por status"
            value={status}
            onChange={(e) => {
              setPage(1);
              setStatus(e.target.value as ExamStatus | '');
            }}
          >
            <option value="">Todos os status</option>
            {(Object.keys(EXAM_STATUS_LABELS) as ExamStatus[]).map((s) => (
              <option key={s} value={s}>
                {EXAM_STATUS_LABELS[s]}
              </option>
            ))}
          </select>
        </div>
        <div className="col-auto">
          <button className="btn btn-outline-primary" type="submit">
            Buscar
          </button>
        </div>
      </form>

      {error && <ErrorAlert message={error} onRetry={load} />}

      {loading ? (
        <Loading />
      ) : items.length === 0 ? (
        <EmptyState icon="bi-file-earmark-medical" title="Nenhum exame encontrado" />
      ) : (
        <div className="card border-0 shadow-sm">
          <div className="table-responsive">
            <table className="table table-hover align-middle mb-0">
              <thead className="table-light">
                <tr>
                  <th scope="col">Paciente</th>
                  <th scope="col">Exame</th>
                  <th scope="col">Solicitante</th>
                  <th scope="col">Marcação</th>
                  <th scope="col">Status</th>
                  <th scope="col" className="text-end">Ações</th>
                </tr>
              </thead>
              <tbody>
                {items.map((exam) => (
                  <tr key={exam.id}>
                    <td className="fw-semibold">{exam.patient?.fullName}</td>
                    <td>
                      {exam.name}
                      <small className="d-block text-muted">
                        {EXAM_TYPE_LABELS[exam.type]} · pedido em {formatDate(exam.createdAt)}
                      </small>
                    </td>
                    <td>{exam.requestedByDentist?.fullName}</td>
                    <td className="small">
                      {exam.scheduledAt ? formatDateTime(exam.scheduledAt) : '—'}
                      {exam.location && <div className="text-muted">{exam.location}</div>}
                    </td>
                    <td>
                      <span className={`badge ${EXAM_STATUS_BADGES[exam.status]}`}>
                        {EXAM_STATUS_LABELS[exam.status]}
                      </span>
                    </td>
                    <td className="text-end">
                      <Link href={`/painel/exames/${exam.id}`} className="btn btn-sm btn-outline-primary">
                        Abrir
                      </Link>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div className="card-body pt-0">
            <Pagination page={page} totalPages={totalPages} total={total} onChange={setPage} />
          </div>
        </div>
      )}

      <Modal
        open={open}
        title="Pedir exame"
        onClose={() => setOpen(false)}
        busy={saving}
        footer={
          <>
            <button className="btn btn-outline-secondary" onClick={() => setOpen(false)} disabled={saving}>
              Cancelar
            </button>
            <button type="submit" form="exam-form" className="btn btn-primary" disabled={saving}>
              Pedir exame
            </button>
          </>
        }
      >
        <form id="exam-form" onSubmit={handleCreate} noValidate>
          {formError && <div className="alert alert-danger py-2">{formError}</div>}
          <div className="mb-3">
            <label htmlFor="exam-patient" className="form-label">Paciente *</label>
            <PatientSelect id="exam-patient" value={patientId} onChange={setPatientId} />
          </div>
          {isAdmin && (
            <div className="mb-3">
              <label htmlFor="exam-dentist" className="form-label">Dentista solicitante *</label>
              <select
                id="exam-dentist"
                className="form-select"
                value={dentistId}
                onChange={(e) => setDentistId(e.target.value ? Number(e.target.value) : '')}
              >
                <option value="">Selecione</option>
                {dentists.map((d) => (
                  <option key={d.id} value={d.id}>
                    {d.fullName}
                  </option>
                ))}
              </select>
            </div>
          )}
          <div className="row g-3 mb-3">
            <div className="col-8">
              <label htmlFor="exam-name" className="form-label">Exame *</label>
              <input
                id="exam-name"
                className="form-control"
                placeholder="Ex.: Radiografia panorâmica"
                value={name}
                onChange={(e) => setName(e.target.value)}
              />
            </div>
            <div className="col-4">
              <label htmlFor="exam-type" className="form-label">Tipo</label>
              <select
                id="exam-type"
                className="form-select"
                value={type}
                onChange={(e) => setType(e.target.value as ExamType)}
              >
                {(Object.keys(EXAM_TYPE_LABELS) as ExamType[]).map((t) => (
                  <option key={t} value={t}>
                    {EXAM_TYPE_LABELS[t]}
                  </option>
                ))}
              </select>
            </div>
          </div>
          <label htmlFor="exam-instructions" className="form-label">Justificativa / orientações</label>
          <textarea
            id="exam-instructions"
            className="form-control"
            rows={3}
            value={instructions}
            onChange={(e) => setInstructions(e.target.value)}
          />
        </form>
      </Modal>
    </>
  );
}
