'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { useRouter } from 'next/navigation';
import { motion } from 'framer-motion';
import {
  X, Clock, User, Loader2, CheckCircle, AlertTriangle,
  Flag, Edit2, Trash2, FileText, Wrench, DollarSign,
  Package, Save, Upload, Paperclip, Download, Image as ImageIcon, Eye,
  CalendarPlus
} from 'lucide-react';
import {
  TIPO_PARTE_LABELS, TIPO_PARTE_COLORS,
  ESTADO_PARTE_LABELS, ESTADO_PARTE_COLORS,
  UNIDADES,
} from '@/lib/partes/constants';
import { calcularHoras } from '@/lib/partes/calculo-horas';
import NuevoPresupuestoModal from '../../presupuestos/_components/nuevo-presupuesto-modal';
import AdjuntosViewer from './adjuntos-viewer';

interface Adjunto {
  id: string;
  nombre: string;
  cloud_storage_path: string;
  contentType: string | null;
  size: number | null;
  subidoPor: { id: string; name: string } | null;
  createdAt: string;
  url: string;
}

interface ParteDetail {
  id: string;
  numero: number;
  tipo: string;
  estado: string;
  descripcion: string;
  clienteNombre: string | null;
  clienteRef: { id: string; nombre: string; telefono?: string; email?: string } | null;
  aviso: {
    id: string; numero: number; cliente: string; estado: string;
    urgencia: string; descripcion: string; contacto?: string; telefono?: string;
  } | null;
  tecnico: { id: string; name: string; email: string } | null;
  tecnicos: { id: string; tecnico: { id: string; name: string; email: string }; rol: string }[];
  fechaInicio: string | null;
  horaInicio: string | null;
  horaFin: string | null;
  horasCalculadas: number | null;
  descontarComida: boolean;
  facturable: boolean;
  facturado: boolean;
  numFactura: string | null;
  importeEstimado: number | null;
  firmado: boolean;
  requierePresupuesto: boolean;
  notasPresupuesto: string | null;
  observaciones: string | null;
  materiales: { id: string; descripcion: string; cantidad: number; unidad: string; precioUnit: number | null }[];
  createdAt: string;
}

interface Props {
  parteId: string;
  userRole: string;
  onClose: () => void;
}

export default function ParteDetailModal({ parteId, userRole, onClose }: Props) {
  const router = useRouter();
  const [parte, setParte] = useState<ParteDetail | null>(null);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState(false);
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);

  // Edit fields
  const [editDescripcion, setEditDescripcion] = useState('');
  const [editHoraInicio, setEditHoraInicio] = useState('');
  const [editHoraFin, setEditHoraFin] = useState('');
  const [editDescontarComida, setEditDescontarComida] = useState(true);
  const [editObservaciones, setEditObservaciones] = useState('');
  const [editFacturable, setEditFacturable] = useState(true);
  const [editImporte, setEditImporte] = useState('');
  const [editFirmado, setEditFirmado] = useState(false);
  const [editReqPresupuesto, setEditReqPresupuesto] = useState(false);
  const [editNotasPresupuesto, setEditNotasPresupuesto] = useState('');

  // Presupuesto modal
  const [showPresupuestoModal, setShowPresupuestoModal] = useState(false);
  // Facturación modal
  const [showFacturarModal, setShowFacturarModal] = useState(false);
  const [numFacturaInput, setNumFacturaInput] = useState('');
  // Nueva visita modal
  const [showNuevaVisitaModal, setShowNuevaVisitaModal] = useState(false);
  const [nuevaVisitaFecha, setNuevaVisitaFecha] = useState('');
  const [nuevaVisitaNotas, setNuevaVisitaNotas] = useState('');
  const [creandoVisita, setCreandoVisita] = useState(false);

  // Adjuntos
  const [adjuntos, setAdjuntos] = useState<Adjunto[]>([]);
  const [uploading, setUploading] = useState(false);
  const [uploadProgress, setUploadProgress] = useState('');
  const [viewerData, setViewerData] = useState<{ adjuntos: Adjunto[], initialIndex: number } | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const canEdit = userRole === 'admin' || userRole === 'oficina';

  const fetchParte = useCallback(async () => {
    try {
      const res = await fetch(`/api/partes/${parteId}`);
      const data = await res.json();
      if (data.parte) setParte(data.parte);
    } catch (err) {
      console.error(err);
    } finally {
      setLoading(false);
    }
  }, [parteId]);

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

  const showMsg = (type: 'success' | 'error', text: string) => {
    setMessage({ type, text });
    setTimeout(() => setMessage(null), 3000);
  };

  const startEditing = () => {
    if (!parte) return;
    setEditDescripcion(parte.descripcion);
    setEditHoraInicio(parte.horaInicio || '');
    setEditHoraFin(parte.horaFin || '');
    setEditDescontarComida(parte.descontarComida);
    setEditObservaciones(parte.observaciones || '');
    setEditFacturable(parte.facturable);
    setEditImporte(parte.importeEstimado?.toString() || '');
    setEditFirmado(parte.firmado);
    setEditReqPresupuesto(parte.requierePresupuesto);
    setEditNotasPresupuesto(parte.notasPresupuesto || '');
    setEditing(true);
  };

  const handleSaveEdit = async () => {
    setSaving(true);
    try {
      const res = await fetch(`/api/partes/${parteId}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          descripcion: editDescripcion,
          horaInicio: editHoraInicio || null,
          horaFin: editHoraFin || null,
          descontarComida: editDescontarComida,
          observaciones: editObservaciones || null,
          facturable: editFacturable,
          importeEstimado: editImporte || null,
          firmado: editFirmado,
          requierePresupuesto: editReqPresupuesto,
          notasPresupuesto: editNotasPresupuesto || null,
        }),
      });
      if (res.ok) {
        showMsg('success', 'Parte actualizada');
        setEditing(false);
        fetchParte();
      } else {
        const data = await res.json();
        showMsg('error', data.error || 'Error al guardar');
      }
    } catch { showMsg('error', 'Error de conexión'); }
    finally { setSaving(false); }
  };

  const handleChangeEstado = async (nuevoEstado: string) => {
    setSaving(true);
    try {
      const res = await fetch(`/api/partes/${parteId}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ estado: nuevoEstado }),
      });
      if (res.ok) {
        showMsg('success', `Estado cambiado a ${ESTADO_PARTE_LABELS[nuevoEstado]}`);
        fetchParte();
      }
    } catch { showMsg('error', 'Error'); }
    finally { setSaving(false); }
  };

  const handleFacturar = async () => {
    if (!confirm('¿Generar factura automáticamente (incluyendo todos los materiales y horas) para este parte?')) return;
    setSaving(true);
    try {
      const res = await fetch(`/api/partes/${parteId}/facturar`, {
        method: 'POST',
      });
      if (res.ok) {
        const data = await res.json();
        showMsg('success', 'Factura generada con éxito');
        if (data.facturaId) {
          router.push(`/dashboard/facturas/${data.facturaId}`);
        } else {
          fetchParte();
        }
      } else {
        const err = await res.json();
        showMsg('error', err.error || 'Error al facturar');
      }
    } catch { showMsg('error', 'Error'); }
    finally { setSaving(false); }
  };

  const handleDesmarcarFacturado = async () => {
    setSaving(true);
    try {
      const res = await fetch(`/api/partes/${parteId}/facturar`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ facturado: false }),
      });
      if (res.ok) {
        showMsg('success', 'Facturación desmarcada');
        fetchParte();
      }
    } catch { showMsg('error', 'Error'); }
    finally { setSaving(false); }
  };

  const handleDelete = async () => {
    if (!confirm('¿Eliminar esta parte de trabajo? Esta acción no se puede deshacer.')) return;
    setSaving(true);
    try {
      const res = await fetch(`/api/partes/${parteId}`, { method: 'DELETE' });
      if (res.ok) {
        onClose();
      } else {
        const data = await res.json();
        showMsg('error', data.error || 'Error');
      }
    } catch { showMsg('error', 'Error'); }
    finally { setSaving(false); }
  };

  // Handler: programar nueva visita
  const handleNuevaVisita = async () => {
    if (!nuevaVisitaFecha) {
      showMsg('error', 'Seleccione una fecha para la nueva visita');
      return;
    }
    setCreandoVisita(true);
    try {
      const res = await fetch(`/api/partes/${parteId}/nueva-visita`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          fecha: nuevaVisitaFecha,
          notas: nuevaVisitaNotas || undefined,
        }),
      });
      const data = await res.json();
      if (res.ok && data.success) {
        showMsg('success', `Nueva visita programada: Parte #${data.nuevoParte.numero}`);
        setShowNuevaVisitaModal(false);
        setNuevaVisitaFecha('');
        setNuevaVisitaNotas('');
        fetchParte();
      } else {
        showMsg('error', data.error || 'Error al programar nueva visita');
      }
    } catch {
      showMsg('error', 'Error de conexión');
    } finally {
      setCreandoVisita(false);
    }
  };

  // Fetch adjuntos
  const fetchAdjuntos = useCallback(async () => {
    try {
      const res = await fetch(`/api/partes/${parteId}/adjuntos`);
      const data = await res.json();
      if (data.adjuntos) setAdjuntos(data.adjuntos);
    } catch (err) {
      console.error('Error fetching adjuntos:', err);
    }
  }, [parteId]);

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

  const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (!files || files.length === 0) return;

    setUploading(true);
    setUploadProgress('');

    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      const sanitizeFileName = (name: string) => name.replace(/[^a-zA-Z0-9.\-_]/g, '_');
      const safeFileName = sanitizeFileName(file.name);

      setUploadProgress(`Subiendo ${file.name}... (${i + 1}/${files.length})`);
      try {
        const formData = new FormData();
        formData.append('file', file);

        const uploadRes = await fetch(`/api/partes/${parteId}/adjuntos`, {
          method: 'POST',
          body: formData,
        });

        if (!uploadRes.ok) {
          const eRes = await uploadRes.json();
          throw new Error(`Upload failed: ${eRes.error || uploadRes.statusText}`);
        }

        const data = await uploadRes.json();
        setAdjuntos(prev => [data.adjunto, ...prev]);
        showMsg('success', `${file.name} subido correctamente`);
      } catch (err: any) {
        console.error('Upload error:', err);
        showMsg('error', `Error subiendo ${file.name}: ${err.message}`);
      }
    }

    setUploading(false);
    setUploadProgress('');
    fetchAdjuntos();
    if (fileInputRef.current) fileInputRef.current.value = '';
  };

  const handleDeleteAdjunto = async (adjuntoId: string) => {
    if (!confirm('¿Eliminar este archivo?')) return;
    try {
      await fetch(`/api/partes/${parteId}/adjuntos?adjuntoId=${adjuntoId}`, { method: 'DELETE' });
      fetchAdjuntos();
    } catch {
      showMsg('error', 'Error eliminando archivo');
    }
  };

  const formatFileSize = (bytes: number | null) => {
    if (!bytes) return '';
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  };

  const isImageFile = (contentType: string | null) => {
    return contentType?.startsWith('image/') || false;
  };

  const formatDate = (d: string) =>
    new Date(d).toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit', year: 'numeric' });

  // Horas preview para edición
  let horasPreview = '';
  if (editing && editHoraInicio && editHoraFin) {
    const r = calcularHoras({ horaInicio: editHoraInicio, horaFin: editHoraFin, descontarComida: editDescontarComida });
    horasPreview = r.detalle;
  }

  const totalMateriales = parte?.materiales.reduce((sum, m) => sum + (m.cantidad * (m.precioUnit || 0)), 0) || 0;

  if (loading) {
    return (
      <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center">
        <div className="bg-white rounded-xl p-8"><Loader2 className="w-8 h-8 animate-spin text-[#1a365d]" /></div>
      </motion.div>
    );
  }

  if (!parte) return null;

  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      className="fixed inset-0 bg-black/50 z-50 flex items-end md:items-center justify-center"
      onClick={onClose}
    >
      <motion.div
        initial={{ y: 50, opacity: 0 }}
        animate={{ y: 0, opacity: 1 }}
        exit={{ y: 50, opacity: 0 }}
        className="bg-white rounded-t-xl md:rounded-xl shadow-xl w-full max-w-3xl max-h-[92vh] overflow-y-auto"
        onClick={(e) => e.stopPropagation()}
      >
        {/* Header */}
        <div className="sticky top-0 bg-white border-b px-6 py-4 z-10 rounded-t-xl">
          <div className="flex items-start justify-between">
            <div>
              <div className="flex items-center gap-3 flex-wrap">
                <span className="text-sm font-mono text-gray-500">Parte #{parte.numero}</span>
                <span className={`text-xs px-2 py-1 rounded font-medium ${TIPO_PARTE_COLORS[parte.tipo]}`}>
                  {TIPO_PARTE_LABELS[parte.tipo]}
                </span>
                <span className={`text-xs px-2 py-1 rounded-full font-medium ${ESTADO_PARTE_COLORS[parte.estado]}`}>
                  {ESTADO_PARTE_LABELS[parte.estado]}
                </span>
                {parte.firmado && <span className="text-xs bg-green-100 text-green-700 px-2 py-1 rounded">✔ Firmado</span>}
                {parte.requierePresupuesto && <span className="text-xs bg-amber-100 text-amber-700 px-2 py-1 rounded"><Flag className="w-3 h-3 inline" /> Presupuesto</span>}
              </div>
              <h2 className="text-lg font-bold text-gray-900 mt-1">
                {parte.clienteNombre || parte.clienteRef?.nombre || parte.aviso?.cliente || 'Sin cliente'}
              </h2>
            </div>
            <button onClick={onClose} className="text-gray-400 hover:text-gray-600"><X className="w-5 h-5" /></button>
          </div>

          {message && (
            <div className={`mt-3 p-2 rounded-lg text-sm flex items-center gap-2 ${message.type === 'success' ? 'bg-green-50 text-green-700' : 'bg-red-50 text-red-700'
              }`}>
              {message.type === 'success' ? <CheckCircle className="w-4 h-4" /> : <AlertTriangle className="w-4 h-4" />}
              {message.text}
            </div>
          )}
        </div>

        <div className="p-6 space-y-6">
          {/* Info grid */}
          {!editing ? (
            <>
              <div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
                {parte.aviso && (
                  <div>
                    <span className="text-gray-500 block text-xs mb-0.5">Aviso vinculado</span>
                    <span className="font-medium text-blue-700">#{parte.aviso.numero} - {parte.aviso.estado}</span>
                  </div>
                )}
                <div>
                  <span className="text-gray-500 block text-xs mb-0.5">Fecha</span>
                  <span className="font-medium text-gray-900">{parte.fechaInicio ? formatDate(parte.fechaInicio) : '-'}</span>
                </div>
                <div>
                  <span className="text-gray-500 block text-xs mb-0.5">Horario</span>
                  <span className="font-medium text-gray-900">
                    {parte.horaInicio ? `${parte.horaInicio} - ${parte.horaFin || '?'}` : '-'}
                  </span>
                </div>
                <div>
                  <span className="text-gray-500 block text-xs mb-0.5">Horas</span>
                  <span className="font-medium text-gray-900">
                    {parte.horasCalculadas != null ? `${parte.horasCalculadas}h` : '-'}
                    {parte.descontarComida && parte.horasCalculadas != null && (
                      <span className="text-gray-400 text-xs ml-1">(comida descontada)</span>
                    )}
                  </span>
                </div>
              </div>

              <div className="bg-gray-50 rounded-lg p-4">
                <h4 className="text-xs font-medium text-gray-500 mb-1">Descripción</h4>
                <p className="text-sm text-gray-900 whitespace-pre-wrap">{parte.descripcion}</p>
              </div>

              {/* Técnicos */}
              {parte.tecnicos.length > 0 && (
                <div>
                  <h4 className="text-xs font-medium text-gray-500 mb-2">Técnicos asignados</h4>
                  <div className="flex flex-wrap gap-2">
                    {parte.tecnicos.map(t => (
                      <span key={t.id} className={`text-xs px-2 py-1 rounded-full ${t.rol === 'PRINCIPAL' ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 text-gray-700'
                        }`}>
                        <User className="w-3 h-3 inline mr-1" />
                        {t.tecnico.name} ({t.rol === 'PRINCIPAL' ? 'Principal' : 'Apoyo'})
                      </span>
                    ))}
                  </div>
                </div>
              )}

              {/* Presupuesto */}
              {parte.requierePresupuesto && (
                <div className="bg-amber-50 border border-amber-200 rounded-lg p-4">
                  <div className="flex items-center justify-between mb-1">
                    <h4 className="text-xs font-medium text-amber-700 flex items-center gap-1">
                      <Flag className="w-3 h-3" /> Requiere presupuesto
                    </h4>
                    {canEdit && (
                      <button
                        onClick={() => setShowPresupuestoModal(true)}
                        className="text-xs bg-amber-600 text-white px-2 py-1 rounded hover:bg-amber-700 transition"
                      >
                        Crear pendiente
                      </button>
                    )}
                  </div>
                  {parte.notasPresupuesto && (
                    <p className="text-sm text-amber-800 whitespace-pre-wrap">{parte.notasPresupuesto}</p>
                  )}
                </div>
              )}

              {/* Materiales */}
              {parte.materiales.length > 0 && (
                <div>
                  <h4 className="text-xs font-medium text-gray-500 mb-2 flex items-center gap-1">
                    <Package className="w-3 h-3" /> Materiales ({parte.materiales.length})
                  </h4>
                  <div className="bg-gray-50 rounded-lg overflow-hidden">
                    <table className="w-full text-sm">
                      <thead>
                        <tr className="text-xs text-gray-500 border-b">
                          <th className="text-left px-3 py-2">Material</th>
                          <th className="text-center px-3 py-2">Cant.</th>
                          <th className="text-center px-3 py-2">Ud.</th>
                          <th className="text-right px-3 py-2">€/ud</th>
                          <th className="text-right px-3 py-2">Total</th>
                        </tr>
                      </thead>
                      <tbody>
                        {parte.materiales.map(m => (
                          <tr key={m.id} className="border-b border-gray-100">
                            <td className="px-3 py-2 text-gray-900">{m.descripcion}</td>
                            <td className="px-3 py-2 text-center text-gray-600">{m.cantidad}</td>
                            <td className="px-3 py-2 text-center text-gray-600">{m.unidad}</td>
                            <td className="px-3 py-2 text-right text-gray-600">{m.precioUnit != null ? `${m.precioUnit.toFixed(2)}€` : '-'}</td>
                            <td className="px-3 py-2 text-right font-medium text-gray-900">
                              {m.precioUnit != null ? `${(m.cantidad * m.precioUnit).toFixed(2)}€` : '-'}
                            </td>
                          </tr>
                        ))}
                        {totalMateriales > 0 && (
                          <tr className="bg-gray-100">
                            <td colSpan={4} className="px-3 py-2 text-right font-medium text-gray-700">Total materiales:</td>
                            <td className="px-3 py-2 text-right font-bold text-gray-900">{totalMateriales.toFixed(2)}€</td>
                          </tr>
                        )}
                      </tbody>
                    </table>
                  </div>
                </div>
              )}

              {/* Facturación */}
              <div className="flex items-center gap-4 text-sm">
                <div>
                  <span className="text-gray-500 text-xs block">Facturable</span>
                  <span className="font-medium text-gray-900">{parte.facturable ? 'Sí' : 'No'}</span>
                </div>
                {parte.facturable && (
                  <>
                    <div>
                      <span className="text-gray-500 text-xs block">Facturado</span>
                      <span className={`font-medium ${parte.facturado ? 'text-green-700' : 'text-amber-700'}`}>
                        {parte.facturado ? 'Sí' : 'No'}
                      </span>
                    </div>
                    {parte.numFactura && (
                      <div>
                        <span className="text-gray-500 text-xs block">Nº Factura</span>
                        <span className="font-medium text-gray-900">{parte.numFactura}</span>
                      </div>
                    )}
                    {parte.importeEstimado != null && (
                      <div>
                        <span className="text-gray-500 text-xs block">Importe estimado</span>
                        <span className="font-medium text-gray-900">{parte.importeEstimado.toFixed(2)}€</span>
                      </div>
                    )}
                  </>
                )}
              </div>

              {parte.observaciones && (
                <div className="bg-gray-50 rounded-lg p-4">
                  <h4 className="text-xs font-medium text-gray-500 mb-1">Observaciones</h4>
                  <p className="text-sm text-gray-900 whitespace-pre-wrap">{parte.observaciones}</p>
                </div>
              )}

              {/* Adjuntos (Documentos y fotos) */}
              <div>
                <div className="flex items-center justify-between mb-2">
                  <h4 className="text-xs font-medium text-gray-500 flex items-center gap-1">
                    <Paperclip className="w-3 h-3" /> Adjuntos ({adjuntos.length})
                  </h4>
                  <div>
                    <input
                      ref={fileInputRef}
                      type="file"
                      multiple
                      accept="image/*,.pdf,.doc,.docx,.xls,.xlsx"
                      onChange={handleFileUpload}
                      className="hidden"
                      id="parte-file-upload"
                    />
                    <label
                      htmlFor="parte-file-upload"
                      className={`text-xs px-3 py-1.5 rounded-lg font-medium border border-blue-300 text-blue-700 hover:bg-blue-50 cursor-pointer flex items-center gap-1 ${uploading ? 'opacity-50 pointer-events-none' : ''}`}
                    >
                      {uploading ? <Loader2 className="w-3 h-3 animate-spin" /> : <Upload className="w-3 h-3" />}
                      Subir archivo
                    </label>
                  </div>
                </div>
                {uploadProgress && (
                  <div className="text-xs text-blue-600 mb-2 flex items-center gap-1">
                    <Loader2 className="w-3 h-3 animate-spin" /> {uploadProgress}
                  </div>
                )}
                {adjuntos.length === 0 ? (
                  <p className="text-xs text-gray-400 py-2">Sin archivos adjuntos. Sube hojas escaneadas, fotografías o documentos.</p>
                ) : (
                  <div className="space-y-2">
                    {adjuntos.map((adj, index) => (
                      <div key={adj.id} className="flex items-center gap-3 bg-gray-50 rounded-lg p-3 group">
                        <div className="flex-shrink-0">
                          {isImageFile(adj.contentType) ? (
                            <ImageIcon className="w-5 h-5 text-green-600" />
                          ) : (
                            <FileText className="w-5 h-5 text-blue-600" />
                          )}
                        </div>
                        <div className="flex-1 min-w-0">
                          <p className="text-sm text-gray-900 font-medium truncate">{adj.nombre}</p>
                          <p className="text-xs text-gray-400">
                            {formatFileSize(adj.size)}
                            {adj.subidoPor && ` · ${adj.subidoPor.name}`}
                            {' · '}{formatDate(adj.createdAt)}
                          </p>
                        </div>
                        <div className="flex items-center gap-1 flex-shrink-0">
                          <button
                            onClick={() => setViewerData({ adjuntos, initialIndex: index })}
                            className="text-gray-600 hover:text-gray-800 p-1"
                            title="Visualizar en carrusel"
                          >
                            <Eye className="w-4 h-4" />
                          </button>
                          <a
                            href={adj.url}
                            download={adj.nombre}
                            className="text-blue-600 hover:text-blue-800 p-1"
                            title="Descargar"
                          >
                            <Download className="w-4 h-4" />
                          </a>
                          {canEdit && (
                            <button
                              onClick={() => handleDeleteAdjunto(adj.id)}
                              className="text-red-400 hover:text-red-600 p-1 opacity-0 group-hover:opacity-100 transition-opacity"
                              title="Eliminar"
                            >
                              <Trash2 className="w-4 h-4" />
                            </button>
                          )}
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            </>
          ) : (
            /* EDIT MODE */
            <div className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-1">Descripción</label>
                <textarea
                  value={editDescripcion}
                  onChange={(e) => setEditDescripcion(e.target.value)}
                  rows={3}
                  className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm text-gray-900 resize-none"
                />
              </div>
              <div className="grid grid-cols-2 gap-3">
                <div>
                  <label className="block text-xs text-gray-500 mb-1">Hora inicio</label>
                  <input type="time" value={editHoraInicio} onChange={(e) => setEditHoraInicio(e.target.value)}
                    className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm text-gray-900" />
                </div>
                <div>
                  <label className="block text-xs text-gray-500 mb-1">Hora fin</label>
                  <input type="time" value={editHoraFin} onChange={(e) => setEditHoraFin(e.target.value)}
                    className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm text-gray-900" />
                </div>
              </div>
              {horasPreview && (
                <div className="bg-blue-50 border border-blue-200 rounded-lg p-2 text-sm text-blue-800">
                  <Clock className="w-4 h-4 inline mr-1" /> {horasPreview}
                </div>
              )}
              <label className="flex items-center gap-2 text-sm text-gray-700">
                <input type="checkbox" checked={editDescontarComida} onChange={(e) => setEditDescontarComida(e.target.checked)} className="rounded border-gray-300" />
                Descontar hora de comida
              </label>
              <div className="flex items-center gap-4">
                <label className="flex items-center gap-2 text-sm text-gray-700">
                  <input type="checkbox" checked={editFacturable} onChange={(e) => setEditFacturable(e.target.checked)} className="rounded border-gray-300" />
                  Facturable
                </label>
                {editFacturable && (
                  <div className="flex items-center gap-2">
                    <input type="number" step="0.01" value={editImporte} onChange={(e) => setEditImporte(e.target.value)}
                      placeholder="Importe est." className="w-28 px-3 py-1.5 border border-gray-300 rounded-lg text-sm text-gray-900" />
                    <span className="text-xs text-gray-500">€</span>
                  </div>
                )}
              </div>
              <label className="flex items-center gap-2 text-sm text-gray-700">
                <input type="checkbox" checked={editFirmado} onChange={(e) => setEditFirmado(e.target.checked)} className="rounded border-gray-300" />
                Firmado
              </label>
              <div>
                <label className="flex items-center gap-2 text-sm text-gray-700 mb-1">
                  <input type="checkbox" checked={editReqPresupuesto} onChange={(e) => setEditReqPresupuesto(e.target.checked)} className="rounded border-gray-300" />
                  Requiere presupuesto
                </label>
                {editReqPresupuesto && (
                  <textarea value={editNotasPresupuesto} onChange={(e) => setEditNotasPresupuesto(e.target.value)}
                    rows={2} placeholder="Notas para presupuesto..."
                    className="w-full px-3 py-2 border border-amber-300 bg-amber-50 rounded-lg text-sm resize-none text-gray-900" />
                )}
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-1">Observaciones</label>
                <textarea value={editObservaciones} onChange={(e) => setEditObservaciones(e.target.value)}
                  rows={2} className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm resize-none text-gray-900" />
              </div>
              <div className="flex gap-2">
                <button onClick={handleSaveEdit} disabled={saving}
                  className="flex items-center gap-2 px-4 py-2 bg-[#1a365d] text-white rounded-lg text-sm hover:bg-[#2c5282] disabled:opacity-50">
                  {saving ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4" />} Guardar
                </button>
                <button onClick={() => setEditing(false)} className="px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 rounded-lg">
                  Cancelar
                </button>
              </div>
            </div>
          )}

          {/* Actions */}
          {!editing && (
            <div className="flex flex-wrap gap-2 border-t pt-4">
              {/* Estado transitions */}
              {parte.estado === 'PENDIENTE' && (
                <button onClick={() => handleChangeEstado('EN_PROCESO')} disabled={saving}
                  className="text-xs px-3 py-1.5 rounded-lg font-medium border border-purple-300 text-purple-700 hover:bg-purple-50 disabled:opacity-50">
                  {'→'} En proceso
                </button>
              )}
              {parte.estado === 'EN_PROCESO' && (
                <button onClick={() => handleChangeEstado('FINALIZADO')} disabled={saving}
                  className="text-xs px-3 py-1.5 rounded-lg font-medium border border-green-300 text-green-700 hover:bg-green-50 disabled:opacity-50">
                  {'→'} Finalizar
                </button>
              )}
              {/* Botón: Nueva visita (solo si parte tiene aviso y no está finalizado/cancelado) */}
              {parte.aviso && (parte.estado === 'PENDIENTE' || parte.estado === 'EN_PROCESO') && (
                <button onClick={() => { setNuevaVisitaFecha(''); setNuevaVisitaNotas(''); setShowNuevaVisitaModal(true); }} disabled={saving}
                  className="text-xs px-3 py-1.5 rounded-lg font-medium border border-blue-300 text-blue-700 hover:bg-blue-50 disabled:opacity-50 flex items-center gap-1">
                  <CalendarPlus className="w-3 h-3" /> Nueva visita
                </button>
              )}
              {(parte.estado === 'PENDIENTE' || parte.estado === 'EN_PROCESO') && (
                <button onClick={() => handleChangeEstado('CANCELADO')} disabled={saving}
                  className="text-xs px-3 py-1.5 rounded-lg font-medium border border-red-300 text-red-700 hover:bg-red-50 disabled:opacity-50">
                  Cancelar
                </button>
              )}

              {/* Facturar */}
              {canEdit && parte.facturable && !parte.facturado && parte.estado === 'FINALIZADO' && (
                <button onClick={handleFacturar} disabled={saving}
                  className="text-xs px-3 py-1.5 rounded-lg font-medium border border-green-300 text-green-700 hover:bg-green-50 disabled:opacity-50 flex items-center gap-1">
                  <DollarSign className="w-3 h-3" /> Convertir a Factura
                </button>
              )}
              {canEdit && parte.facturado && (
                <button onClick={handleDesmarcarFacturado} disabled={saving}
                  className="text-xs px-3 py-1.5 rounded-lg font-medium border border-gray-300 text-gray-600 hover:bg-gray-50 disabled:opacity-50">
                  Desmarcar facturado
                </button>
              )}

              {/* Editar */}
              {canEdit && (
                <button onClick={startEditing}
                  className="text-xs px-3 py-1.5 rounded-lg font-medium border border-gray-300 text-gray-700 hover:bg-gray-50 flex items-center gap-1">
                  <Edit2 className="w-3 h-3" /> Editar
                </button>
              )}

              {/* Eliminar */}
              {userRole === 'admin' && (
                <button onClick={handleDelete} disabled={saving}
                  className="text-xs px-3 py-1.5 rounded-lg font-medium border border-red-300 text-red-700 hover:bg-red-50 disabled:opacity-50 flex items-center gap-1">
                  <Trash2 className="w-3 h-3" /> Eliminar
                </button>
              )}
            </div>
          )}
        </div>
      </motion.div>

      {/* Modal: Nueva visita */}
      {
        showNuevaVisitaModal && parte && (
          <div className="fixed inset-0 bg-black/40 z-[60] flex items-center justify-center" onClick={() => setShowNuevaVisitaModal(false)}>
            <div className="bg-white rounded-xl shadow-2xl w-full max-w-sm mx-4 p-6" onClick={(e) => e.stopPropagation()}>
              <h3 className="text-lg font-bold text-gray-900 mb-1 flex items-center gap-2">
                <CalendarPlus className="w-5 h-5 text-blue-600" /> Programar nueva visita
              </h3>
              <p className="text-xs text-gray-500 mb-4">
                Se creará una nueva cita y un nuevo parte vinculados al mismo aviso #{parte.aviso?.numero}.
                No se crea un aviso nuevo.
              </p>
              <div className="space-y-3 mb-4">
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1">Fecha de la visita *</label>
                  <input
                    type="date"
                    value={nuevaVisitaFecha}
                    onChange={(e) => setNuevaVisitaFecha(e.target.value)}
                    className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm text-gray-900"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1">Notas <span className="text-gray-400">(opcional)</span></label>
                  <textarea
                    value={nuevaVisitaNotas}
                    onChange={(e) => setNuevaVisitaNotas(e.target.value)}
                    rows={2}
                    placeholder="Motivo, material a llevar, indicaciones..."
                    className="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm text-gray-900 resize-none"
                  />
                </div>
              </div>
              <div className="flex gap-3 justify-end">
                <button onClick={() => setShowNuevaVisitaModal(false)} className="px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 rounded-lg">
                  Cancelar
                </button>
                <button
                  onClick={handleNuevaVisita}
                  disabled={creandoVisita || !nuevaVisitaFecha}
                  className="px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 font-medium flex items-center gap-2"
                >
                  {creandoVisita && <Loader2 className="w-4 h-4 animate-spin" />}
                  Programar
                </button>
              </div>
            </div>
          </div>
        )
      }

      {/* Modal crear presupuesto pendiente */}
      {
        showPresupuestoModal && parte && (
          <NuevoPresupuestoModal
            onClose={() => setShowPresupuestoModal(false)}
            onCreated={() => {
              setShowPresupuestoModal(false);
              showMsg('success', 'Presupuesto pendiente creado');
            }}
            partePreseleccionado={{
              id: parte.id,
              numero: parte.numero,
              descripcion: parte.descripcion,
              clienteId: parte.clienteRef?.id || undefined,
              clienteNombre: parte.clienteNombre || parte.clienteRef?.nombre || undefined,
            }}
          />
        )
      }
      {/* Visor de Carrusel */}
      {viewerData && (
        <AdjuntosViewer
          adjuntos={viewerData.adjuntos}
          initialIndex={viewerData.initialIndex}
          onClose={() => setViewerData(null)}
        />
      )}
    </motion.div>
  );
}