'use client';

import { useParams } from 'next/navigation';
import { useCallback, useEffect, useRef, useState } from 'react';
import Swal from 'sweetalert2';
import { RequireRole, useAuth } from '@/lib/auth-context';
import {
  ATTACHMENT_KIND_LABELS,
  cancelExam,
  Exam,
  EXAM_STATUS_BADGES,
  EXAM_STATUS_LABELS,
  EXAM_TYPE_LABELS,
  ExamAttachmentKind,
  examAttachmentPath,
  getExam,
  removeExamAttachment,
  saveExamResult,
  scheduleExam,
  uploadExamAttachment,
} from '@/lib/services/exams';
import { openProtectedFile } from '@/lib/download';
import {
  BackLink,
  ErrorAlert,
  Loading,
  PageHeader,
  formatBytes,
  formatDateTime,
} from '@/components/app/ui';
import { extractApiError } from '@/lib/api-client';

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

/** datetime-local ↔ ISO no fuso do navegador */
function toLocalInput(iso: string | null): string {
  if (!iso) return '';
  const d = new Date(iso);
  const offset = d.getTimezoneOffset() * 60000;
  return new Date(d.getTime() - offset).toISOString().slice(0, 16);
}

function ExamDetail() {
  const { id } = useParams<{ id: string }>();
  const examId = Number(id);
  const { user } = useAuth();
  const clinical = user?.role === 'admin' || user?.role === 'dentist';

  const [exam, setExam] = useState<Exam | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);
  const [scheduledAt, setScheduledAt] = useState('');
  const [location, setLocation] = useState('');
  const [result, setResult] = useState('');
  const [kind, setKind] = useState<ExamAttachmentKind>(clinical ? 'result' : 'request');
  const fileRef = useRef<HTMLInputElement>(null);

  const load = useCallback(async () => {
    try {
      const loaded = await getExam(examId);
      setExam(loaded);
      setScheduledAt(toLocalInput(loaded.scheduledAt));
      setLocation(loaded.location ?? '');
      setResult(loaded.resultSummary ?? '');
    } catch (err) {
      setError(extractApiError(err));
    }
  }, [examId]);

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

  async function run(fn: () => Promise<Exam | void>, success?: string) {
    setBusy(true);
    try {
      const updated = await fn();
      if (updated) {
        setExam(updated);
        setResult(updated.resultSummary ?? '');
      } else {
        await load();
      }
      if (success) Swal.fire({ icon: 'success', title: success, timer: 1200, showConfirmButton: false });
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    } finally {
      setBusy(false);
    }
  }

  async function handleUpload(e: React.FormEvent) {
    e.preventDefault();
    const file = fileRef.current?.files?.[0];
    if (!file) return;
    await run(() => uploadExamAttachment(examId, kind, file), 'Arquivo anexado');
    if (fileRef.current) fileRef.current.value = '';
  }

  async function handleRelease(e: React.FormEvent) {
    e.preventDefault();
    if (result.trim().length < 3) return;
    const first = exam?.status !== 'completed';
    if (first) {
      const confirmation = await Swal.fire({
        icon: 'question',
        title: 'Liberar resultado ao paciente?',
        text: 'O paciente recebe um aviso por e-mail e passa a ver o laudo e os arquivos de resultado no portal.',
        showCancelButton: true,
        confirmButtonText: 'Liberar',
        cancelButtonText: 'Voltar',
      });
      if (!confirmation.isConfirmed) return;
    }
    await run(() => saveExamResult(examId, result), first ? 'Resultado liberado' : 'Laudo atualizado');
  }

  async function handleCancel() {
    const confirmation = await Swal.fire({
      icon: 'warning',
      title: 'Cancelar exame?',
      showCancelButton: true,
      confirmButtonText: 'Cancelar exame',
      cancelButtonText: 'Voltar',
      confirmButtonColor: '#dc3545',
    });
    if (confirmation.isConfirmed) await run(() => cancelExam(examId), 'Exame cancelado');
  }

  async function openFile(attachmentId: number) {
    try {
      await openProtectedFile(examAttachmentPath(examId, attachmentId));
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    }
  }

  if (error) return <ErrorAlert message={error} />;
  if (!exam) return <Loading />;

  const isOpen = exam.status === 'requested' || exam.status === 'scheduled';
  const cancelled = exam.status === 'cancelled';

  return (
    <>
      <BackLink href="/painel/exames" label="Exames" />
      <PageHeader
        title={exam.name}
        subtitle={`${exam.patient?.fullName ?? ''} · pedido por ${exam.requestedByDentist?.fullName ?? ''}`}
        action={
          isOpen && (
            <button className="btn btn-outline-danger" onClick={handleCancel} disabled={busy}>
              Cancelar exame
            </button>
          )
        }
      />

      <div className="d-flex flex-wrap gap-2 align-items-center mb-4">
        <span className={`badge fs-6 ${EXAM_STATUS_BADGES[exam.status]}`}>{EXAM_STATUS_LABELS[exam.status]}</span>
        <span className="badge text-bg-light border">{EXAM_TYPE_LABELS[exam.type]}</span>
        <small className="text-muted">Pedido em {formatDateTime(exam.createdAt)}</small>
      </div>

      <div className="row g-4">
        <div className="col-lg-6">
          {exam.instructions && (
            <div className="card border-0 shadow-sm mb-4">
              <div className="card-header bg-white fw-semibold">Justificativa / orientações</div>
              <div className="card-body" style={{ whiteSpace: 'pre-wrap' }}>
                {exam.instructions}
              </div>
            </div>
          )}

          <form
            className="card border-0 shadow-sm mb-4"
            onSubmit={(e) => {
              e.preventDefault();
              if (!scheduledAt) return;
              run(
                () => scheduleExam(examId, { scheduledAt: new Date(scheduledAt).toISOString(), location: location || undefined }),
                'Exame marcado',
              );
            }}
          >
            <div className="card-header bg-white fw-semibold">Marcação</div>
            <div className="card-body">
              <div className="row g-2">
                <div className="col-sm-6">
                  <label htmlFor="exam-when" className="form-label small">Data e hora</label>
                  <input
                    id="exam-when"
                    type="datetime-local"
                    className="form-control"
                    value={scheduledAt}
                    disabled={!isOpen}
                    onChange={(e) => setScheduledAt(e.target.value)}
                  />
                </div>
                <div className="col-sm-6">
                  <label htmlFor="exam-where" className="form-label small">Local</label>
                  <input
                    id="exam-where"
                    className="form-control"
                    value={location}
                    disabled={!isOpen}
                    placeholder="Clínica de imagem / laboratório"
                    onChange={(e) => setLocation(e.target.value)}
                  />
                </div>
              </div>
              {isOpen && (
                <button type="submit" className="btn btn-outline-primary mt-3" disabled={busy || !scheduledAt}>
                  Salvar marcação
                </button>
              )}
            </div>
          </form>

          <div className="card border-0 shadow-sm">
            <div className="card-header bg-white fw-semibold">Resultado</div>
            <div className="card-body">
              {clinical ? (
                <form onSubmit={handleRelease}>
                  <label htmlFor="exam-result" className="form-label small">Laudo / resumo</label>
                  <textarea
                    id="exam-result"
                    className="form-control mb-3"
                    rows={5}
                    value={result}
                    disabled={cancelled}
                    onChange={(e) => setResult(e.target.value)}
                  />
                  {!cancelled && (
                    <button type="submit" className="btn btn-success" disabled={busy || result.trim().length < 3}>
                      {exam.status === 'completed' ? 'Atualizar laudo' : 'Liberar resultado ao paciente'}
                    </button>
                  )}
                  {exam.resultAvailableAt && (
                    <small className="d-block text-muted mt-2">
                      Liberado em {formatDateTime(exam.resultAvailableAt)}
                    </small>
                  )}
                </form>
              ) : (
                <p className="text-muted mb-0">
                  <i className="bi bi-shield-lock me-1" aria-hidden="true" />
                  {exam.hasResult
                    ? 'Resultado registrado — acesso restrito a dentistas e administração.'
                    : 'Ainda sem resultado.'}
                </p>
              )}
            </div>
          </div>
        </div>

        <div className="col-lg-6">
          <div className="card border-0 shadow-sm">
            <div className="card-header bg-white fw-semibold">Arquivos</div>
            <ul className="list-group list-group-flush">
              {exam.attachments.length === 0 && (
                <li className="list-group-item text-muted">Nenhum arquivo visível para você.</li>
              )}
              {exam.attachments.map((a) => (
                <li key={a.id} className="list-group-item d-flex justify-content-between align-items-center gap-2">
                  <div className="text-truncate">
                    <span className="badge text-bg-light border me-2">{ATTACHMENT_KIND_LABELS[a.kind]}</span>
                    {a.originalName}
                    <small className="d-block text-muted">
                      {formatBytes(a.sizeBytes)} · {formatDateTime(a.createdAt)}
                    </small>
                  </div>
                  <div className="text-nowrap">
                    <button className="btn btn-sm btn-outline-primary me-1" onClick={() => openFile(a.id)}>
                      Abrir
                    </button>
                    {clinical && (
                      <button
                        className="btn btn-sm btn-outline-danger"
                        aria-label={`Remover ${a.originalName}`}
                        disabled={busy}
                        onClick={() => run(() => removeExamAttachment(examId, a.id))}
                      >
                        <i className="bi bi-trash" />
                      </button>
                    )}
                  </div>
                </li>
              ))}
            </ul>
            {!cancelled && (
              <form className="card-body border-top" onSubmit={handleUpload}>
                <div className="row g-2 align-items-end">
                  <div className="col-sm-4">
                    <label htmlFor="att-kind" className="form-label small">Tipo</label>
                    <select
                      id="att-kind"
                      className="form-select"
                      value={kind}
                      onChange={(e) => setKind(e.target.value as ExamAttachmentKind)}
                    >
                      {(Object.keys(ATTACHMENT_KIND_LABELS) as ExamAttachmentKind[])
                        .filter((k) => clinical || k !== 'result')
                        .map((k) => (
                          <option key={k} value={k}>
                            {ATTACHMENT_KIND_LABELS[k]}
                          </option>
                        ))}
                    </select>
                  </div>
                  <div className="col-sm-8">
                    <label htmlFor="att-file" className="form-label small">Arquivo (PDF ou imagem, até 20 MB)</label>
                    <input
                      id="att-file"
                      ref={fileRef}
                      type="file"
                      accept="application/pdf,image/jpeg,image/png,image/webp"
                      className="form-control"
                    />
                  </div>
                </div>
                <button type="submit" className="btn btn-outline-primary mt-3" disabled={busy}>
                  <i className="bi bi-upload me-1" />
                  Anexar
                </button>
              </form>
            )}
          </div>
        </div>
      </div>
    </>
  );
}
