import React, { useState, useEffect, useCallback } from 'react';
import {
  ScanLine, Upload, RefreshCw, X, Image as ImageIcon, Loader2,
  Users, FileText, CheckCircle2, Clock, AlertCircle, ZoomIn, ChevronRight, Calendar, Camera as CameraIcon
} from 'lucide-react';
import { PageHeader } from '../../components/PageHeader.tsx';
import { useToast } from '../../contexts/ToastContext.tsx';
import { HybridBackend } from '../../services/backend.ts';
import { CameraCapture } from '../../components/CameraCapture.tsx';

const FALLBACK_URL = 'https://rx.scoreodonto.com';

// Runtime RX config — loaded once from backend, then cached
let _rxBase: string = FALLBACK_URL;
let _rxToken: string = '';
let _rxConfigLoaded = false;

async function loadRxConfig(): Promise<void> {
  if (_rxConfigLoaded) return;
  const workspace = HybridBackend.getActiveWorkspace();
  if (workspace?.id) {
    const cfg = await HybridBackend.getRxConfig(workspace.id);
    if (cfg) {
      _rxBase = cfg.rx_url?.replace(/\/$/, '') || FALLBACK_URL;
      _rxToken = cfg.rx_token || '';
    }
  }
  _rxConfigLoaded = true;
}

function thumbUrl(relPath: string): string {
  return `${_rxBase}${relPath}`;
}

const rxFetch = (path: string, opts: RequestInit = {}) =>
  fetch(`${_rxBase}/api${path}`, {
    ...opts,
    headers: {
      'Authorization': `Bearer ${_rxToken}`,
      ...(opts.headers || {}),
    },
  });

// ─── Types ───────────────────────────────────────────────────────────────────
interface RxPatient {
  patient_name: string;
  doctor: string;
  remark: string;
  client_name: string;
  image_count: string; // the API returns this as a string
  last_date: string;
  latest_image_id: number;
  thumb_url: string;   // relative path, e.g. /api/images/5386/thumbnail
  pending_count: string;
}

interface RxImage {
  id: number;
  filename: string;
  thumb_filename: string;
  thumb_url: string;   // relative path — use thumbUrl() to build absolute
  file_url: string;    // relative path to the signed-URL endpoint
  doctor: string;
  remark: string;
  image_remark: string | null;
  created_at: string;
}

interface RxGTO {
  id: number;
  gto_number: string;
  patient_name: string;
  description: string;
  sent: boolean;
  sent_at: string | null;
  created_at: string;
  image_count: number;
  thumb_url: string | null;
}

// ─── Sub-components ───────────────────────────────────────────────────────────
const StatCard: React.FC<{ label: string; value: number | string; icon: React.ReactNode; color: string }> = ({ label, value, icon, color }) => (
  <div className="bg-white rounded-xl sm:rounded-2xl p-3 sm:p-5 border border-gray-100 flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4 shadow-sm">
    <div className="w-8 h-8 sm:w-11 sm:h-11 rounded-lg sm:rounded-xl flex items-center justify-center flex-shrink-0 [&>svg]:w-4 [&>svg]:h-4 sm:[&>svg]:w-5 sm:[&>svg]:h-5" style={{ backgroundColor: `${color}15`, color }}>
      {icon}
    </div>
    <div>
      <p className="text-[8px] sm:text-[9px] font-black text-gray-400 uppercase tracking-widest leading-tight">{label}</p>
      <p className="text-lg sm:text-2xl font-black text-gray-900">{value}</p>
    </div>
  </div>
);

// ─── Image tile: uses thumb_url directly (no extra API call needed) ───────────
const RxImageTile: React.FC<{ image: RxImage; onClick: (image: RxImage) => void }> = ({ image, onClick }) => (
  <button
    onClick={() => onClick(image)}
    className="aspect-square rounded-xl overflow-hidden border border-gray-100 hover:border-purple-300 group relative transition-all shadow-sm"
  >
    <img
      src={thumbUrl(image.thumb_url)}
      alt={image.filename}
      className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
      loading="lazy"
      onError={e => { (e.target as HTMLImageElement).style.display = 'none'; }}
    />
    <div className="absolute inset-0 bg-black/0 group-hover:bg-black/30 transition-colors flex items-center justify-center">
      <ZoomIn size={20} className="text-white opacity-0 group-hover:opacity-100 transition-opacity" />
    </div>
    {(image.image_remark || image.doctor) && (
      <div className="absolute bottom-0 left-0 right-0 bg-black/60 text-white text-[8px] font-bold px-2 py-1 truncate opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity">
        {image.image_remark || image.doctor}
      </div>
    )}
  </button>
);

// ─── Fullscreen viewer: loads signed URL on demand ────────────────────────────
const FullscreenViewer: React.FC<{ image: RxImage; onClose: () => void }> = ({ image, onClose }) => {
  const [url, setUrl] = useState<string | null>(null);
  const [err, setErr] = useState(false);

  useEffect(() => {
    rxFetch(`/images/${image.id}/file-url`)
      .then(r => r.json())
      .then(d => { if (d.url) setUrl(d.url); else setErr(true); })
      .catch(() => setErr(true));
  }, [image.id]);

  return (
    <div className="fixed inset-0 z-[80] bg-black/95 flex items-center justify-center p-4" onClick={onClose}>
      <button className="absolute top-4 right-4 text-white/70 hover:text-white p-2 rounded-full hover:bg-white/10 transition-colors" onClick={onClose}>
        <X size={24} />
      </button>
      {image.image_remark && (
        <div className="absolute top-4 left-1/2 -translate-x-1/2 bg-black/60 text-white text-xs font-bold px-4 py-2 rounded-full uppercase">
          {image.image_remark}
        </div>
      )}
      {err ? (
        <div className="flex flex-col items-center gap-3 text-white/60">
          <AlertCircle size={40} /><p className="text-sm font-bold uppercase">ERRO AO CARREGAR IMAGEM</p>
        </div>
      ) : !url ? (
        <div className="flex flex-col items-center gap-3 text-white/60">
          <Loader2 size={40} className="animate-spin" /><p className="text-sm font-bold uppercase">CARREGANDO...</p>
        </div>
      ) : (
        <img src={url} alt={image.filename} className="max-w-full max-h-full object-contain rounded-xl shadow-2xl" onClick={e => e.stopPropagation()} />
      )}
    </div>
  );
};

// ─── Image Gallery Modal ──────────────────────────────────────────────────────
const ImageGalleryModal: React.FC<{
  patient: RxPatient;
  onClose: () => void;
  onUploadClick: (name: string) => void;
}> = ({ patient, onClose, onUploadClick }) => {
  const [images, setImages] = useState<RxImage[]>([]);
  const [loading, setLoading] = useState(true);
  const [fullscreen, setFullscreen] = useState<RxImage | null>(null);

  useEffect(() => {
    // real param is `name`, not `patient`
    rxFetch(`/images/by-patient?name=${encodeURIComponent(patient.patient_name)}`)
      .then(r => r.json())
      .then(d => setImages(Array.isArray(d) ? d : []))
      .catch(() => setImages([]))
      .finally(() => setLoading(false));
  }, [patient.patient_name]);

  return (
    <div className="fixed inset-0 bg-black/70 z-[70] flex items-end sm:items-center justify-center backdrop-blur-sm p-0 sm:p-4">
      <div className="bg-white rounded-t-2xl sm:rounded-2xl w-full sm:max-w-3xl max-h-[92vh] flex flex-col overflow-hidden shadow-2xl">
        <div className="px-4 sm:px-6 py-3 sm:py-4 border-b border-gray-100 flex-shrink-0" style={{ background: 'linear-gradient(to right, #7c3aed10, transparent)' }}>
          {/* Mobile drag handle */}
          <div className="w-10 h-1 bg-gray-200 rounded-full mx-auto mb-3 sm:hidden" />
          <div className="flex items-start justify-between gap-3">
            <div className="min-w-0">
              <h3 className="text-sm sm:text-base font-black text-gray-900 uppercase tracking-tight truncate">{patient.patient_name}</h3>
              <div className="flex flex-wrap items-center gap-x-3 gap-y-0.5 mt-0.5">
                <p className="text-[10px] text-purple-600 font-bold uppercase">{images.length} RADIOGRAFIA{images.length !== 1 ? 'S' : ''}</p>
                {patient.doctor && <p className="text-[10px] text-gray-400 font-bold uppercase">· {patient.doctor}</p>}
                {patient.remark && <p className="text-[10px] text-gray-400 font-medium truncate">· {patient.remark}</p>}
              </div>
            </div>
            <div className="flex items-center gap-1.5 flex-shrink-0">
              <button
                onClick={() => onUploadClick(patient.patient_name)}
                className="flex items-center gap-1.5 px-3 sm:px-4 py-2 bg-purple-600 text-white rounded-xl text-[10px] font-black uppercase hover:bg-purple-700 active:bg-purple-800 transition-colors"
              >
                <Upload size={13} /> <span className="hidden sm:inline">UPLOAD RX</span><span className="sm:hidden">UPLOAD</span>
              </button>
              <button onClick={onClose} className="p-2 hover:bg-gray-100 active:bg-gray-200 rounded-xl transition-colors"><X size={18} /></button>
            </div>
          </div>
        </div>

        <div className="flex-1 overflow-y-auto p-3 sm:p-6">
          {loading ? (
            <div className="flex items-center justify-center py-16 gap-3 text-gray-400">
              <Loader2 size={22} className="animate-spin" /><span className="text-sm font-bold uppercase">CARREGANDO IMAGENS...</span>
            </div>
          ) : images.length === 0 ? (
            <div className="flex flex-col items-center justify-center py-16 gap-3 text-gray-400">
              <ImageIcon size={40} /><p className="text-sm font-bold uppercase">NENHUMA IMAGEM ENCONTRADA</p>
            </div>
          ) : (
            <div className="grid grid-cols-3 sm:grid-cols-4 gap-2 sm:gap-3">
              {images.map(img => <RxImageTile key={img.id} image={img} onClick={setFullscreen} />)}
            </div>
          )}
        </div>
      </div>

      {fullscreen && <FullscreenViewer image={fullscreen} onClose={() => setFullscreen(null)} />}
    </div>
  );
};

// ─── Upload Modal ─────────────────────────────────────────────────────────────
const UploadModal: React.FC<{ initialPatient?: string; onClose: () => void; onSuccess: () => void }> = ({ initialPatient, onClose, onSuccess }) => {
  const toast = useToast();
  const [patientName, setPatientName] = useState(initialPatient || '');
  const [doctor, setDoctor] = useState('');
  const [remark, setRemark] = useState('');
  const [file, setFile] = useState<File | null>(null);
  const [uploading, setUploading] = useState(false);
  const [showCam, setShowCam] = useState(false);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!file || !patientName.trim()) { toast.error('SELECIONE UM ARQUIVO E INFORME O NOME DO PACIENTE.'); return; }
    setUploading(true);
    try {
      const fd = new FormData();
      fd.append('image', file);
      fd.append('patientName', patientName.trim().toUpperCase());
      fd.append('doctor', doctor.trim().toUpperCase());
      fd.append('remark', remark.trim().toUpperCase());
      const res = await rxFetch('/images/upload-file', { method: 'POST', body: fd });
      const data = await res.json();
      if (data.success || data.filename) {
        toast.success('RADIOGRAFIA ENVIADA COM SUCESSO!');
        onSuccess();
        onClose();
      } else {
        toast.error('ERRO AO ENVIAR IMAGEM.');
      }
    } catch {
      toast.error('ERRO DE CONEXÃO COM O SERVIDOR RX.');
    } finally {
      setUploading(false);
    }
  };

  const inputCls = "w-full border border-gray-200 rounded-xl px-4 py-2.5 text-sm font-bold uppercase focus:outline-none focus:border-purple-400 focus:ring-2 focus:ring-purple-100 bg-white";

  return (
    <div className="fixed inset-0 bg-black/60 z-[70] flex items-center justify-center backdrop-blur-sm p-4">
      <form onSubmit={handleSubmit} className="bg-white rounded-2xl w-full max-w-md shadow-2xl overflow-hidden">
        <div className="px-6 py-4 border-b border-gray-100 flex items-center justify-between" style={{ background: 'linear-gradient(to right, #7c3aed10, transparent)' }}>
          <div>
            <h3 className="text-base font-black text-gray-900 uppercase">UPLOAD DE RADIOGRAFIA</h3>
            <p className="text-[10px] font-bold uppercase tracking-widest" style={{ color: '#7c3aed' }}>RX SCOREODONTO</p>
          </div>
          <button type="button" onClick={onClose} className="p-2 hover:bg-gray-100 rounded-xl"><X size={18} /></button>
        </div>
        <div className="p-6 space-y-4">
          <div>
            <label className="text-[9px] font-black text-gray-400 uppercase tracking-widest block mb-1.5">PACIENTE *</label>
            <input value={patientName} onChange={e => setPatientName(e.target.value)} className={inputCls} placeholder="NOME COMPLETO DO PACIENTE" required />
          </div>
          <div>
            <label className="text-[9px] font-black text-gray-400 uppercase tracking-widest block mb-1.5">MÉDICO / DENTISTA</label>
            <input value={doctor} onChange={e => setDoctor(e.target.value)} className={inputCls} placeholder="DR. NOME" />
          </div>
          <div>
            <label className="text-[9px] font-black text-gray-400 uppercase tracking-widest block mb-1.5">OBSERVAÇÃO / TIPO</label>
            <input value={remark} onChange={e => setRemark(e.target.value)} className={inputCls} placeholder="EX: RAIO-X PERIAPICAL" />
          </div>
          <div>
            <label className="text-[9px] font-black text-gray-400 uppercase tracking-widest block mb-1.5">ARQUIVO *</label>
            <div
              className="border-2 border-dashed border-gray-200 rounded-xl p-6 text-center hover:border-purple-300 transition-colors cursor-pointer"
              onClick={() => document.getElementById('rx-file-input')?.click()}
            >
              {file ? (
                <div className="flex items-center justify-center gap-2 text-purple-600">
                  <CheckCircle2 size={20} /><span className="text-sm font-bold uppercase truncate max-w-xs">{file.name}</span>
                </div>
              ) : (
                <div className="text-gray-400">
                  <ImageIcon size={32} className="mx-auto mb-2" />
                  <p className="text-xs font-bold uppercase">CLIQUE PARA SELECIONAR</p>
                  <p className="text-[9px] font-medium text-gray-300 mt-1">PNG, JPG, DICOM</p>
                </div>
              )}
              <input id="rx-file-input" type="file" accept="image/*,.dcm" className="hidden" onChange={e => setFile(e.target.files?.[0] || null)} />
            </div>
            <button type="button" onClick={() => setShowCam(true)} className="mt-2 w-full py-2.5 border border-gray-200 rounded-xl text-xs font-black uppercase text-gray-600 hover:bg-gray-50 transition-colors flex items-center justify-center gap-2">
              <CameraIcon size={14} /> ABRIR CÂMERA
            </button>
          </div>
        </div>
        <div className="px-6 pb-6 flex gap-3">
          <button type="button" onClick={onClose} className="flex-1 py-3 border border-gray-200 rounded-xl text-xs font-black uppercase text-gray-500 hover:bg-gray-50 transition-colors">
            CANCELAR
          </button>
          <button type="submit" disabled={uploading} className="flex-1 py-3 text-white rounded-xl text-xs font-black uppercase disabled:opacity-50 transition-colors flex items-center justify-center gap-2" style={{ backgroundColor: '#7c3aed' }}>
            {uploading ? <><Loader2 size={16} className="animate-spin" /> ENVIANDO...</> : <><Upload size={16} /> ENVIAR</>}
          </button>
        </div>
      </form>
      {showCam && (
        <CameraCapture
          title="RAIO-X"
          onCapture={(f) => { setFile(f); setShowCam(false); }}
          onClose={() => setShowCam(false)}
        />
      )}
    </div>
  );
};

// ─── GTO Tab ──────────────────────────────────────────────────────────────────
const GTOTab: React.FC = () => {
  const toast = useToast();
  const [gtos, setGtos] = useState<RxGTO[]>([]);
  const [loading, setLoading] = useState(true);
  const [sending, setSending] = useState<number | null>(null);

  const load = useCallback(() => {
    setLoading(true);
    rxFetch('/gtos')
      .then(r => r.json())
      // real response: { rows: [...], total, page, limit, pages }
      .then(d => setGtos(Array.isArray(d.rows) ? d.rows : []))
      .catch(() => setGtos([]))
      .finally(() => setLoading(false));
  }, []);

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

  const markSent = async (gto: RxGTO) => {
    setSending(gto.id);
    try {
      const res = await rxFetch(`/gtos/${gto.id}/sent`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ sent: true })
      });
      if (res.ok) { toast.success(`GTO ${gto.gto_number} MARCADA COMO ENVIADA!`); load(); }
      else toast.error('ERRO AO ATUALIZAR GTO.');
    } catch { toast.error('ERRO DE CONEXÃO.'); }
    finally { setSending(null); }
  };

  if (loading) return (
    <div className="flex items-center justify-center py-20 gap-3 text-gray-400">
      <Loader2 size={22} className="animate-spin" /><span className="text-sm font-bold uppercase">CARREGANDO GTOs...</span>
    </div>
  );

  if (gtos.length === 0) return (
    <div className="flex flex-col items-center justify-center py-20 gap-3 text-gray-400">
      <FileText size={40} /><p className="text-sm font-bold uppercase">NENHUMA GTO ENCONTRADA</p>
    </div>
  );

  const pendentes = gtos.filter(g => !g.sent).length;

  return (
    <div className="space-y-3">
      {pendentes > 0 && (
        <div className="flex items-center gap-2 px-4 py-2 bg-amber-50 border border-amber-200 rounded-2xl text-amber-700">
          <Clock size={14} />
          <p className="text-[10px] font-black uppercase">{pendentes} GTO{pendentes !== 1 ? 'S' : ''} PENDENTE{pendentes !== 1 ? 'S' : ''} DE ENVIO</p>
        </div>
      )}
      {gtos.map(gto => (
        <div key={gto.id} className="bg-white rounded-2xl p-3 sm:p-4 border border-gray-100 flex items-center gap-3 sm:gap-4 hover:border-purple-100 transition-colors shadow-sm">
          {/* Thumbnail */}
          {gto.thumb_url ? (
            <img src={thumbUrl(gto.thumb_url)} alt="thumb" className="w-10 h-10 sm:w-12 sm:h-12 rounded-xl object-cover flex-shrink-0 border border-gray-100" />
          ) : (
            <div className="w-10 h-10 sm:w-12 sm:h-12 rounded-xl flex-shrink-0 flex items-center justify-center bg-gray-50 border border-gray-100">
              <FileText size={18} className="text-gray-300" />
            </div>
          )}

          <div className="flex-1 min-w-0">
            <div className="flex items-center gap-2">
              <p className="text-sm font-black text-gray-900 uppercase">#{gto.gto_number}</p>
              <span className={`text-[8px] font-black px-2 py-0.5 rounded-full uppercase flex-shrink-0 ${gto.sent ? 'bg-emerald-100 text-emerald-700' : 'bg-amber-100 text-amber-700'}`}>
                {gto.sent ? 'ENVIADA' : 'PENDENTE'}
              </span>
            </div>
            <p className="text-[11px] font-bold text-gray-700 uppercase truncate">{gto.patient_name}</p>
            {gto.description && <p className="text-[9px] text-gray-400 uppercase truncate mt-0.5">{gto.description}</p>}
            <div className="flex items-center gap-3 mt-1">
              <span className="text-[9px] text-gray-400 flex items-center gap-1">
                <ImageIcon size={9} /> {gto.image_count} img
              </span>
              <span className="text-[9px] text-gray-400 flex items-center gap-1">
                <Calendar size={9} /> {new Date(gto.created_at).toLocaleDateString('pt-BR')}
              </span>
            </div>
          </div>

          {!gto.sent && (
            <button
              onClick={() => markSent(gto)}
              disabled={sending === gto.id}
              className="p-2 sm:px-4 sm:py-2 text-white rounded-xl text-[10px] font-black uppercase disabled:opacity-50 transition-colors flex items-center gap-1.5 flex-shrink-0"
              style={{ backgroundColor: '#7c3aed' }}
            >
              {sending === gto.id ? <Loader2 size={14} className="animate-spin" /> : <CheckCircle2 size={14} />}
              <span className="hidden sm:inline">ENVIADA</span>
            </button>
          )}
        </div>
      ))}
    </div>
  );
};

// ─── Patient card with proper image error state ───────────────────────────────
const PatientCard: React.FC<{ patient: RxPatient; onClick: (p: RxPatient) => void }> = ({ patient, onClick }) => {
  const [imgError, setImgError] = useState(false);
  return (
    <button
      onClick={() => onClick(patient)}
      className="bg-white rounded-2xl border border-gray-100 hover:border-purple-200 active:border-purple-300 hover:shadow-md text-left transition-all group flex items-center gap-4 overflow-hidden"
    >
      <div className="w-16 h-16 flex-shrink-0 overflow-hidden bg-gray-100 flex items-center justify-center">
        {imgError ? (
          <ScanLine size={22} className="text-purple-300" />
        ) : (
          <img
            src={thumbUrl(patient.thumb_url)}
            alt={patient.patient_name}
            className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
            loading="lazy"
            onError={() => setImgError(true)}
          />
        )}
      </div>
      <div className="min-w-0 flex-1 py-3 pr-3">
        <p className="text-sm font-black text-gray-900 uppercase truncate leading-tight">{patient.patient_name}</p>
        <p className="text-[10px] font-bold text-gray-400 uppercase mt-0.5">
          {parseInt(patient.image_count, 10)} IMAGEM{parseInt(patient.image_count, 10) !== 1 ? 'NS' : ''}
          {patient.doctor ? ` · ${patient.doctor}` : ''}
        </p>
        {patient.remark && <p className="text-[9px] text-gray-400 truncate mt-0.5">{patient.remark}</p>}
      </div>
      <ChevronRight size={16} className="text-gray-300 group-hover:text-purple-500 mr-3 flex-shrink-0 transition-colors" />
    </button>
  );
};

// ─── Main RXPlugin View ───────────────────────────────────────────────────────
export const RXPlugin: React.FC = () => {
  const toast = useToast();
  const [tab, setTab] = useState<'pacientes' | 'gtos'>('pacientes');
  const [patients, setPatients] = useState<RxPatient[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState('');
  const [selectedPatient, setSelectedPatient] = useState<RxPatient | null>(null);
  const [uploadOpen, setUploadOpen] = useState(false);
  const [uploadPatient, setUploadPatient] = useState('');
  const [syncing, setSyncing] = useState(false);
  const [configReady, setConfigReady] = useState(_rxConfigLoaded);

  const loadPatients = useCallback(() => {
    setLoading(true);
    rxFetch('/images/patients')
      .then(r => r.json())
      .then(d => setPatients(Array.isArray(d) ? d : []))
      .catch(() => setPatients([]))
      .finally(() => setLoading(false));
  }, []);

  useEffect(() => {
    if (!_rxConfigLoaded) {
      loadRxConfig().then(() => {
        setConfigReady(true);
        loadPatients();
      });
    } else {
      loadPatients();
    }
  }, [loadPatients]);

  const handleSync = async () => {
    setSyncing(true);
    try {
      const res = await rxFetch('/system/trigger-sync', { method: 'POST' });
      const d = await res.json();
      if (d.success) toast.success(d.message || 'SINCRONIZAÇÃO ENVIADA!');
      else toast.error('ERRO AO SINCRONIZAR.');
    } catch { toast.error('ERRO DE CONEXÃO.'); }
    finally { setSyncing(false); }
  };

  const handleUploadClick = (name = '') => { setUploadPatient(name); setUploadOpen(true); };

  // image_count comes as string from the API
  const totalImages = patients.reduce((acc, p) => acc + parseInt(p.image_count || '0', 10), 0);
  const filtered = patients.filter(p => !search.trim() || p.patient_name.toLowerCase().includes(search.toLowerCase()));

  const TABS = [
    { id: 'pacientes' as const, label: 'PACIENTES', icon: <Users size={14} /> },
    { id: 'gtos' as const, label: 'GTOs', icon: <FileText size={14} /> },
  ];

  return (
    <div className="space-y-6 animate-in fade-in duration-500">
      <PageHeader title="RX / RADIOGRAFIAS" description="Gerenciamento de imagens radiográficas integrado ao RX ScoreOdonto.">
        <div className="flex items-center gap-2">
          <button
            onClick={handleSync}
            disabled={syncing}
            className="flex items-center gap-2 px-4 py-2.5 border border-purple-200 text-purple-600 rounded-xl text-[10px] font-black uppercase hover:bg-purple-50 disabled:opacity-50 transition-colors"
          >
            <RefreshCw size={14} className={syncing ? 'animate-spin' : ''} /> SINCRONIZAR
          </button>
          <button
            onClick={() => handleUploadClick()}
            className="flex items-center gap-2 px-4 py-2.5 text-white rounded-xl text-[10px] font-black uppercase hover:opacity-90 transition-all shadow-sm"
            style={{ backgroundColor: '#7c3aed' }}
          >
            <Upload size={14} /> UPLOAD RX
          </button>
        </div>
      </PageHeader>

      {/* Stats */}
      <div className="grid grid-cols-3 gap-2 sm:gap-4">
        <StatCard label="TOTAL PACIENTES" value={patients.length} icon={<Users size={20} />} color="#7c3aed" />
        <StatCard label="TOTAL DE IMAGENS" value={totalImages} icon={<ScanLine size={20} />} color="#059669" />
        <StatCard label="IMAGENS PENDENTES" value={patients.reduce((a, p) => a + parseInt(p.pending_count || '0', 10), 0)} icon={<Clock size={20} />} color="#d97706" />
      </div>

      {/* Tabs */}
      <div className="flex gap-1 p-1 bg-gray-100 rounded-2xl w-fit">
        {TABS.map(t => (
          <button
            key={t.id}
            onClick={() => setTab(t.id)}
            className={`flex items-center gap-2 px-5 py-2 rounded-xl text-[10px] font-black uppercase transition-all ${tab === t.id ? 'bg-white shadow-sm' : 'text-gray-500 hover:text-gray-700'}`}
            style={tab === t.id ? { color: '#7c3aed' } : {}}
          >
            {t.icon}{t.label}
          </button>
        ))}
      </div>

      {/* PACIENTES */}
      {tab === 'pacientes' && (
        <div className="space-y-4">
          <input
            value={search}
            onChange={e => setSearch(e.target.value)}
            placeholder="BUSCAR PACIENTE..."
            className="w-full border border-gray-200 rounded-2xl px-5 py-3 text-sm font-bold uppercase focus:outline-none focus:border-purple-400 focus:ring-2 focus:ring-purple-100 bg-white"
          />

          {loading ? (
            <div className="flex items-center justify-center py-20 gap-3 text-gray-400">
              <Loader2 size={22} className="animate-spin" /><span className="text-sm font-bold uppercase">CARREGANDO PACIENTES...</span>
            </div>
          ) : filtered.length === 0 ? (
            <div className="flex flex-col items-center justify-center py-20 gap-3 text-gray-400">
              <Users size={40} />
              <p className="text-sm font-bold uppercase">{search ? 'NENHUM PACIENTE ENCONTRADO' : 'SEM PACIENTES COM IMAGENS'}</p>
            </div>
          ) : (
            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
              {filtered.map(p => (
                <PatientCard key={p.patient_name} patient={p} onClick={setSelectedPatient} />
              ))}
            </div>
          )}
        </div>
      )}

      {/* GTOs */}
      {tab === 'gtos' && <GTOTab />}

      {/* Modals */}
      {selectedPatient && (
        <ImageGalleryModal
          patient={selectedPatient}
          onClose={() => setSelectedPatient(null)}
          onUploadClick={name => { setSelectedPatient(null); handleUploadClick(name); }}
        />
      )}
      {uploadOpen && (
        <UploadModal
          initialPatient={uploadPatient}
          onClose={() => setUploadOpen(false)}
          onSuccess={loadPatients}
        />
      )}
    </div>
  );
};
