'use client';

import { useCallback, useEffect, useState } from 'react';
import Swal from 'sweetalert2';
import {
  documentDownloadPath,
  listDocuments,
  removeDocument,
  uploadDocument,
} from '@/lib/services/patients';
import { openProtectedFile } from '@/lib/download';
import {
  DOCUMENT_TYPE_LABELS,
  DocumentType,
  PatientDocument,
} from '@/lib/types';
import {
  EmptyState,
  Loading,
  formatBytes,
  formatDateTime,
} from '@/components/app/ui';
import { extractApiError } from '@/lib/api-client';

export default function DocumentsTab({
  patientId,
  canManage,
}: {
  patientId: number;
  canManage: boolean;
}) {
  const [items, setItems] = useState<PatientDocument[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [uploading, setUploading] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      setItems(await listDocuments(patientId));
    } catch (err) {
      setError(extractApiError(err));
    } finally {
      setLoading(false);
    }
  }, [patientId]);

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

  async function handleUpload() {
    const typeOptions = (Object.keys(DOCUMENT_TYPE_LABELS) as DocumentType[])
      .map((t) => `<option value="${t}">${DOCUMENT_TYPE_LABELS[t]}</option>`)
      .join('');

    const { value } = await Swal.fire({
      title: 'Enviar documento',
      html: `
        <div class="text-start">
          <label class="form-label">Tipo</label>
          <select id="sw-dtype" class="form-select mb-2">${typeOptions}</select>
          <label class="form-label">Título</label>
          <input id="sw-dtitle" class="form-control mb-2">
          <label class="form-label">Arquivo (PDF, JPG, PNG, WEBP · máx 10 MB)</label>
          <input id="sw-dfile" type="file" class="form-control" accept=".pdf,.jpg,.jpeg,.png,.webp">
        </div>`,
      focusConfirm: false,
      showCancelButton: true,
      confirmButtonText: 'Enviar',
      cancelButtonText: 'Cancelar',
      preConfirm: () => {
        const type = (
          document.getElementById('sw-dtype') as HTMLSelectElement
        ).value as DocumentType;
        const title = (
          document.getElementById('sw-dtitle') as HTMLInputElement
        ).value.trim();
        const file = (
          document.getElementById('sw-dfile') as HTMLInputElement
        ).files?.[0];
        if (!title) {
          Swal.showValidationMessage('Informe o título');
          return false;
        }
        if (!file) {
          Swal.showValidationMessage('Selecione um arquivo');
          return false;
        }
        return { type, title, file };
      },
    });

    if (!value) return;
    setUploading(true);
    try {
      await uploadDocument(patientId, value);
      Swal.fire({
        icon: 'success',
        title: 'Documento enviado',
        timer: 1200,
        showConfirmButton: false,
      });
      load();
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    } finally {
      setUploading(false);
    }
  }

  async function handleRemove(doc: PatientDocument) {
    const confirm = await Swal.fire({
      icon: 'warning',
      title: 'Remover documento?',
      text: doc.title,
      showCancelButton: true,
      confirmButtonText: 'Remover',
      cancelButtonText: 'Cancelar',
      confirmButtonColor: '#dc3545',
    });
    if (!confirm.isConfirmed) return;
    try {
      await removeDocument(patientId, doc.id);
      load();
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    }
  }

  async function handleOpen(doc: PatientDocument) {
    try {
      await openProtectedFile(documentDownloadPath(patientId, doc.id));
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    }
  }

  if (loading) return <Loading label="Carregando documentos…" />;
  if (error) return <div className="alert alert-danger">{error}</div>;

  return (
    <div className="card border-0 shadow-sm">
      <div className="card-header bg-white d-flex justify-content-between align-items-center">
        <span className="fw-semibold">
          <i className="bi bi-folder2-open me-2 text-primary" />
          Documentos
        </span>
        {canManage && (
          <button
            className="btn btn-sm btn-primary"
            onClick={handleUpload}
            disabled={uploading}
          >
            {uploading ? (
              <span
                className="spinner-border spinner-border-sm me-1"
                role="status"
                aria-hidden="true"
              />
            ) : (
              <i className="bi bi-upload me-1" />
            )}
            Enviar
          </button>
        )}
      </div>
      {items.length === 0 ? (
        <EmptyState
          icon="bi-folder2-open"
          title="Nenhum documento"
          description="Anexe exames, radiografias e termos."
        />
      ) : (
        <div className="table-responsive">
          <table className="table align-middle mb-0">
            <thead className="table-light">
              <tr>
                <th>Título</th>
                <th>Tipo</th>
                <th>Tamanho</th>
                <th>Enviado</th>
                <th className="text-end">Ações</th>
              </tr>
            </thead>
            <tbody>
              {items.map((doc) => (
                <tr key={doc.id}>
                  <td className="fw-semibold">{doc.title}</td>
                  <td>{DOCUMENT_TYPE_LABELS[doc.type]}</td>
                  <td className="text-muted">{formatBytes(doc.sizeBytes)}</td>
                  <td className="text-muted">{formatDateTime(doc.createdAt)}</td>
                  <td className="text-end table-nowrap">
                    <button
                      className="btn btn-sm btn-outline-primary"
                      onClick={() => handleOpen(doc)}
                      aria-label={`Abrir ${doc.title}`}
                    >
                      Abrir
                    </button>
                    {canManage && (
                      <button
                        className="btn btn-sm btn-outline-danger ms-1"
                        onClick={() => handleRemove(doc)}
                        aria-label={`Remover ${doc.title}`}
                      >
                        <i className="bi bi-trash" />
                      </button>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}
