'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { useRouter } from 'next/navigation';
import {
  X, FileText, MessageSquare, Send, Trash2, Edit3, Save, ChevronRight,
  Clock, Truck, CheckCircle2, XCircle, AlertTriangle, Download, Mail, FileIcon, DollarSign, Eye
} from 'lucide-react';
import { motion } from 'framer-motion';
import {
  ESTADO_LABELS,
  ESTADO_COLORS,
  TRANSICIONES_VALIDAS,
} from '@/lib/presupuestos/constants';

interface Nota {
  id: string;
  contenido: string;
  createdAt: string;
  autor: { id: string; name: string } | null;
}

interface Presupuesto {
  id: string;
  numero: number;
  estado: string;
  descripcion: string;
  clienteNombre: string | null;
  importeEstimado: number | null;
  facturado: boolean;
  facturaId: string | null;
  createdAt: string;
  updatedAt: string;
  parte: { id: string; numero: number; tipo: string; descripcion: string; estado: string } | null;
  clienteRef: { id: string; nombre: string } | null;
  creadoPor: { id: string; name: string } | null;
  notas: Nota[];
}

const ESTADO_ICONS: Record<string, React.ElementType> = {
  PENDIENTE: Clock,
  SOLICITADO_PROVEEDOR: Truck,
  ENVIADO_CLIENTE: Send,
  ACEPTADO: CheckCircle2,
  RECHAZADO: XCircle,
};

interface Props {
  id: string;
  canEdit: boolean;
  onClose: () => void;
  onUpdated: () => void;
}

export default function PresupuestoDetailModal({ id, canEdit, onClose, onUpdated }: Props) {
  const router = useRouter();
  const [data, setData] = useState<Presupuesto | null>(null);
  const [loading, setLoading] = useState(true);
  const [nuevaNota, setNuevaNota] = useState('');
  const [enviandoNota, setEnviandoNota] = useState(false);
  const [editando, setEditando] = useState(false);
  const [editDesc, setEditDesc] = useState('');
  const [editImporte, setEditImporte] = useState('');
  const [msg, setMsg] = useState<{ tipo: 'ok' | 'err'; texto: string } | null>(null);
  const [confirmDelete, setConfirmDelete] = useState(false);
  const [enviandoEmail, setEnviandoEmail] = useState(false);
  const notasEndRef = useRef<HTMLDivElement>(null);

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetch(`/api/presupuestos/${id}`);
      if (res.ok) {
        const d = await res.json();
        setData(d);
        setEditDesc(d.descripcion);
        setEditImporte(d.importeEstimado?.toString() || '');
      }
    } catch { /* ignore */ }
    setLoading(false);
  }, [id]);

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

  const showMsg = (tipo: 'ok' | 'err', texto: string) => {
    setMsg({ tipo, texto });
    setTimeout(() => setMsg(null), 3000);
  };

  const cambiarEstado = async (nuevoEstado: string) => {
    try {
      const res = await fetch(`/api/presupuestos/${id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ estado: nuevoEstado }),
      });
      if (res.ok) {
        const d = await res.json();
        setData(d);
        showMsg('ok', `Estado cambiado a: ${ESTADO_LABELS[nuevoEstado]}`);
        onUpdated();
      } else {
        const err = await res.json();
        showMsg('err', err.error || 'Error al cambiar estado');
      }
    } catch { showMsg('err', 'Error de conexión'); }
  };

  const guardarEdicion = async () => {
    try {
      const res = await fetch(`/api/presupuestos/${id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ descripcion: editDesc, importeEstimado: editImporte || null }),
      });
      if (res.ok) {
        const d = await res.json();
        setData(d);
        setEditando(false);
        showMsg('ok', 'Guardado');
        onUpdated();
      } else {
        const err = await res.json();
        showMsg('err', err.error || 'Error al guardar');
      }
    } catch { showMsg('err', 'Error de conexión'); }
  };

  const enviarNota = async () => {
    if (!nuevaNota.trim()) return;
    setEnviandoNota(true);
    try {
      const res = await fetch(`/api/presupuestos/${id}/notas`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ contenido: nuevaNota }),
      });
      if (res.ok) {
        setNuevaNota('');
        fetchData();
        setTimeout(() => notasEndRef.current?.scrollIntoView({ behavior: 'smooth' }), 200);
      }
    } catch { showMsg('err', 'Error al añadir nota'); }
    setEnviandoNota(false);
  };

  const handleViewPdf = () => {
    window.open(`/api/presupuestos/${id}/pdf`, '_blank');
  };

  const handleDownloadPdf = () => {
    window.open(`/api/presupuestos/${id}/pdf?download=true`, '_blank');
  };

  const handleDownloadWord = () => {
    window.open(`/api/presupuestos/${id}/word`, '_blank');
  };

  const handleSendEmail = async () => {
    setEnviandoEmail(true);
    try {
      const res = await fetch(`/api/presupuestos/${id}/enviar`, { method: 'POST' });
      const data = await res.json();

      if (res.ok) {
        showMsg('ok', data.message || 'Presupuesto enviado por correo');
      } else if (data.requiresEmail) {
        const customEmail = window.prompt("El cliente asociado no tiene un email registrado (o es un cliente nuevo).\n\nIntroduce el correo electrónico de destino:");
        if (customEmail && customEmail.includes('@')) {
          setEnviandoEmail(true);
          const retryRes = await fetch(`/api/presupuestos/${id}/enviar`, {
            method: 'POST',
            body: JSON.stringify({ emailDestino: customEmail.trim() })
          });
          const retryData = await retryRes.json();
          if (retryRes.ok) {
            showMsg('ok', retryData.message || 'Presupuesto enviado por correo');
          } else {
            showMsg('err', retryData.error || 'Error enviando el correo');
          }
        } else if (customEmail) {
          showMsg('err', 'El correo introducido no es válido');
        }
      } else {
        showMsg('err', data.error || 'Error enviando el correo');
      }
    } catch {
      showMsg('err', 'Error de conexión enviando email');
    }
    setEnviandoEmail(false);
  };

  const handleFacturar = async () => {
    if (!confirm('¿Generar factura para este presupuesto?')) return;
    try {
      const res = await fetch(`/api/presupuestos/${id}/facturar`, { method: 'POST' });
      if (res.ok) {
        const d = await res.json();
        showMsg('ok', 'Presupuesto convertido a Factura');
        if (d.facturaId) {
          router.push(`/dashboard/facturas/${d.facturaId}`);
        } else {
          fetchData();
        }
      } else {
        const error = await res.json();
        showMsg('err', error.error || 'Error al facturar');
      }
    } catch { showMsg('err', 'Error de conexión'); }
  };

  const eliminar = async () => {
    try {
      const res = await fetch(`/api/presupuestos/${id}`, { method: 'DELETE' });
      if (res.ok) {
        onUpdated();
        onClose();
      } else {
        showMsg('err', 'Error al eliminar');
      }
    } catch { showMsg('err', 'Error de conexión'); }
  };

  if (loading || !data) {
    return (
      <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}
        className="fixed inset-0 z-50 bg-black/40 flex items-center justify-center" onClick={onClose}>
        <div className="bg-white rounded-2xl p-8"><Clock className="w-6 h-6 animate-spin text-gray-400" /></div>
      </motion.div>
    );
  }

  const transicionesPermitidas = TRANSICIONES_VALIDAS[data.estado] || [];
  const Icon = ESTADO_ICONS[data.estado] || FileText;

  return (
    <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}
      className="fixed inset-0 z-50 bg-black/40 flex items-center justify-center p-4" onClick={onClose}>
      <motion.div initial={{ scale: 0.95 }} animate={{ scale: 1 }} exit={{ scale: 0.95 }}
        className="bg-white rounded-2xl shadow-xl w-full max-w-2xl max-h-[90vh] overflow-y-auto"
        onClick={e => e.stopPropagation()}>

        {/* Cabecera */}
        <div className="sticky top-0 bg-white border-b border-gray-200 px-6 py-4 flex items-center justify-between z-10">
          <div className="flex items-center gap-3">
            <div className={`p-2 rounded-lg ${ESTADO_COLORS[data.estado]}`}>
              <Icon className="w-5 h-5" />
            </div>
            <div>
              <h2 className="text-lg font-bold text-gray-900">Presupuesto #{data.numero}</h2>
              <span className={`text-xs px-2 py-0.5 rounded-full font-medium ${ESTADO_COLORS[data.estado]}`}>
                {ESTADO_LABELS[data.estado]}
              </span>
            </div>
          </div>
          <button onClick={onClose} className="p-1 hover:bg-gray-100 rounded-lg">
            <X className="w-5 h-5 text-gray-500" />
          </button>
        </div>

        {/* Mensaje */}
        {msg && (
          <div className={`mx-6 mt-3 px-3 py-2 rounded-lg text-sm ${msg.tipo === 'ok' ? 'bg-green-50 text-green-700' : 'bg-red-50 text-red-700'
            }`}>{msg.texto}</div>
        )}

        <div className="px-6 py-4 space-y-5">
          {/* Info principal */}
          <div className="space-y-3">
            {editando ? (
              <div className="space-y-3">
                <div>
                  <label className="block text-xs font-medium text-gray-500 mb-1">Descripción</label>
                  <textarea
                    value={editDesc}
                    onChange={e => setEditDesc(e.target.value)}
                    rows={3}
                    className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500"
                  />
                </div>
                <div>
                  <label className="block text-xs font-medium text-gray-500 mb-1">Importe estimado (€)</label>
                  <input
                    type="number"
                    step="0.01"
                    value={editImporte}
                    onChange={e => setEditImporte(e.target.value)}
                    className="w-40 border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500"
                    placeholder="0.00"
                  />
                </div>
                <div className="flex gap-2">
                  <button onClick={guardarEdicion}
                    className="flex items-center gap-1 bg-blue-600 text-white px-3 py-1.5 rounded-lg text-sm hover:bg-blue-700">
                    <Save className="w-3 h-3" /> Guardar
                  </button>
                  <button onClick={() => setEditando(false)}
                    className="px-3 py-1.5 border rounded-lg text-sm text-gray-600 hover:bg-gray-50">
                    Cancelar
                  </button>
                </div>
              </div>
            ) : (
              <>
                <div>
                  <h4 className="text-xs font-medium text-gray-500 mb-1">Descripción</h4>
                  <p className="text-sm text-gray-900 whitespace-pre-wrap">{data.descripcion}</p>
                </div>
                <div className="grid grid-cols-2 gap-4">
                  <div>
                    <h4 className="text-xs font-medium text-gray-500 mb-1">Cliente</h4>
                    <p className="text-sm text-gray-900">{data.clienteRef?.nombre || data.clienteNombre || '-'}</p>
                  </div>
                  <div>
                    <h4 className="text-xs font-medium text-gray-500 mb-1">Importe estimado</h4>
                    <p className="text-sm text-gray-900">
                      {data.importeEstimado != null ? `${data.importeEstimado.toFixed(2)} \u20AC` : 'Sin definir'}
                    </p>
                  </div>
                  {data.parte && (
                    <div>
                      <h4 className="text-xs font-medium text-gray-500 mb-1">Parte vinculada</h4>
                      <p className="text-sm text-blue-600">#{data.parte.numero} · {data.parte.descripcion}</p>
                    </div>
                  )}
                  <div>
                    <h4 className="text-xs font-medium text-gray-500 mb-1">Creado por</h4>
                    <p className="text-sm text-gray-700">{data.creadoPor?.name || '-'}</p>
                    <p className="text-xs text-gray-400">{new Date(data.createdAt).toLocaleString('es-ES')}</p>
                  </div>
                </div>
                {canEdit && (
                  <button onClick={() => setEditando(true)}
                    className="flex items-center gap-1 text-xs text-blue-600 hover:text-blue-800">
                    <Edit3 className="w-3 h-3" /> Editar datos
                  </button>
                )}
              </>
            )}
          </div>

          {/* Cambiar estado */}
          {canEdit && transicionesPermitidas.length > 0 && (
            <div className="border-t border-gray-100 pt-4">
              <h4 className="text-xs font-medium text-gray-500 mb-2">Cambiar estado</h4>
              <div className="flex flex-wrap gap-2">
                {transicionesPermitidas.map(est => {
                  const BtnIcon = ESTADO_ICONS[est] || ChevronRight;
                  return (
                    <button
                      key={est}
                      onClick={() => cambiarEstado(est)}
                      className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium border transition hover:shadow-sm ${ESTADO_COLORS[est] || 'bg-gray-100 text-gray-600'
                        } border-transparent`}
                    >
                      <BtnIcon className="w-3.5 h-3.5" />
                      {ESTADO_LABELS[est]}
                    </button>
                  );
                })}
              </div>
            </div>
          )}

          {/* Exportación y Envío */}
          <div className="border-t border-gray-100 pt-4">
            <h4 className="text-xs font-medium text-gray-500 mb-2">Documento y Exportación</h4>
            <div className="flex flex-wrap gap-2">
              <button
                onClick={handleViewPdf}
                className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium border border-gray-300 text-gray-700 hover:bg-gray-50 transition"
                title="Visualizar documento PDF en el navegador"
              >
                <Eye className="w-3.5 h-3.5" /> Ver PDF
              </button>

              <button
                onClick={handleDownloadPdf}
                className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium border border-[#e53e3e] text-[#e53e3e] hover:bg-red-50 transition"
                title="Generar y descargar documento PDF formal"
              >
                <FileText className="w-3.5 h-3.5" /> Descargar PDF
              </button>
              <button
                onClick={handleDownloadWord}
                className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium border border-[#3182ce] text-[#3182ce] hover:bg-blue-50 transition"
                title="Descargar documento Word editable"
              >
                <FileIcon className="w-3.5 h-3.5" /> Descargar Word
              </button>

              {canEdit && data.estado === 'ACEPTADO' && !data.facturado && (
                <button
                  onClick={handleFacturar}
                  className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium border border-green-600 text-green-700 hover:bg-green-50 transition ml-2"
                  title="Generar Factura"
                >
                  <DollarSign className="w-3.5 h-3.5" /> Convertir a Factura
                </button>
              )}

              <div className="flex-1" />

              <button
                onClick={handleSendEmail}
                disabled={enviandoEmail}
                className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium bg-[#2b6cb0] text-white hover:bg-[#2c5282] transition disabled:opacity-50"
                title="Enviar por correo automáticamente al cliente"
              >
                {enviandoEmail ? <Clock className="w-3.5 h-3.5 animate-spin" /> : <Mail className="w-3.5 h-3.5" />}
                {enviandoEmail ? 'Enviando...' : 'Enviar por Email'}
              </button>
            </div>
          </div>

          {/* Notas / historial */}
          <div className="border-t border-gray-100 pt-4">
            <h4 className="text-xs font-medium text-gray-500 mb-2 flex items-center gap-1">
              <MessageSquare className="w-3.5 h-3.5" />
              Notas ({data.notas.length})
            </h4>
            <div className="space-y-2 max-h-60 overflow-y-auto border border-gray-100 rounded-lg p-3 bg-gray-50">
              {data.notas.length === 0 && (
                <p className="text-xs text-gray-400 text-center py-3">Sin notas aún. Añade la primera nota abajo.</p>
              )}
              {data.notas.map(n => (
                <div key={n.id} className="bg-white rounded-lg p-2.5 border border-gray-100">
                  <p className="text-sm text-gray-800 whitespace-pre-wrap">{n.contenido}</p>
                  <p className="text-xs text-gray-400 mt-1">
                    {n.autor?.name || 'Sistema'} · {new Date(n.createdAt).toLocaleString('es-ES')}
                  </p>
                </div>
              ))}
              <div ref={notasEndRef} />
            </div>

            {/* Añadir nota */}
            <div className="flex gap-2 mt-2">
              <input
                type="text"
                value={nuevaNota}
                onChange={e => setNuevaNota(e.target.value)}
                onKeyDown={e => e.key === 'Enter' && enviarNota()}
                placeholder="Añadir nota..."
                className="flex-1 border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500"
              />
              <button
                onClick={enviarNota}
                disabled={enviandoNota || !nuevaNota.trim()}
                className="bg-blue-600 text-white px-3 py-2 rounded-lg hover:bg-blue-700 disabled:opacity-50 transition"
              >
                <Send className="w-4 h-4" />
              </button>
            </div>
          </div>

          {/* Eliminar (solo admin) */}
          {canEdit && (
            <div className="pt-3 border-t border-gray-100">
              {confirmDelete ? (
                <div className="flex items-center gap-3">
                  <AlertTriangle className="w-4 h-4 text-red-500" />
                  <span className="text-sm text-red-700">{'\u00BF'}Eliminar definitivamente?</span>
                  <button onClick={eliminar}
                    className="bg-red-600 text-white px-3 py-1 rounded-lg text-xs hover:bg-red-700">Sí, eliminar</button>
                  <button onClick={() => setConfirmDelete(false)}
                    className="text-xs text-gray-500 hover:text-gray-700">Cancelar</button>
                </div>
              ) : (
                <button onClick={() => setConfirmDelete(true)}
                  className="flex items-center gap-1 text-xs text-red-500 hover:text-red-700">
                  <Trash2 className="w-3 h-3" /> Eliminar presupuesto
                </button>
              )}
            </div>
          )}
        </div>
      </motion.div>
    </motion.div>
  );
}
