'use client';

import { useRef, useState, useCallback } from 'react';
import { Clock, AlertTriangle, Wrench, ClipboardList, Briefcase, Car } from 'lucide-react';
import { TIPO_EVENTO_BG, ESTADO_EVENTO_LABELS } from '@/lib/agenda/constants';
import type { EventoAgenda, Tecnico, TravelTime } from './agenda-content';

interface Props {
  weekStart: Date;
  eventos: EventoAgenda[];
  tecnicos: Tecnico[];
  loading: boolean;
  userRole: string;
  userId: string;
  travelTimes: TravelTime[];
  onCellClick: (fecha: string, tecnicoId?: string) => void;
  onEventoClick: (eventoId: string) => void;
  onEventoMoved: (eventoId: string, newFecha: string, newTecnicoId?: string) => void;
  onAvisoDrop: (avisoId: string, fecha: string, tecnicoId?: string) => void;
}

const DIAS = ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'];

function formatDateISO(date: Date): string {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, '0');
  const d = String(date.getDate()).padStart(2, '0');
  return `${y}-${m}-${d}`;
}

function addDays(date: Date, days: number): Date {
  const d = new Date(date);
  d.setDate(d.getDate() + days);
  return d;
}

function isToday(date: Date): boolean {
  const today = new Date();
  return date.toDateString() === today.toDateString();
}

const tipoIcon = (tipo: string) => {
  switch (tipo) {
    case 'VISITA_AVISO': return <ClipboardList className="w-3 h-3" />;
    case 'MANTENIMIENTO': return <Wrench className="w-3 h-3" />;
    case 'TAREA_INTERNA': return <Briefcase className="w-3 h-3" />;
    default: return null;
  }
};

export default function AgendaSemanal({
  weekStart, eventos, tecnicos, loading, userRole, userId, travelTimes,
  onCellClick, onEventoClick, onEventoMoved, onAvisoDrop,
}: Props) {
  const [draggedEvento, setDraggedEvento] = useState<string | null>(null);
  const [dragOverCell, setDragOverCell] = useState<string | null>(null);
  const justDroppedRef = useRef(false);

  const days = Array.from({ length: 7 }, (_, i) => addDays(weekStart, i));

  const getEventosForCell = (fecha: string, tecnicoId: string): EventoAgenda[] => {
    return eventos.filter(e => {
      const eventoFecha = e.fecha.split('T')[0];
      const asignado = e.asignaciones.some(a => a.tecnicoId === tecnicoId);
      return eventoFecha === fecha && asignado;
    }).sort((a, b) => (a.horaInicio || '').localeCompare(b.horaInicio || ''));
  };

  const getTravelTimeBetween = (fromId: string, toId: string): TravelTime | undefined => {
    return travelTimes.find(t => t.fromEventoId === fromId && t.toEventoId === toId);
  };

  const eventosSinAsignar = eventos.filter(e => e.asignaciones.length === 0);

  const handleDragStart = (e: React.DragEvent, eventoId: string) => {
    setDraggedEvento(eventoId);
    e.dataTransfer.setData('text/plain', `evento:${eventoId}`);
    e.dataTransfer.setData('application/evento-id', eventoId);
    e.dataTransfer.effectAllowed = 'move';
  };

  const handleDragOver = (e: React.DragEvent, fecha: string, tecnicoId: string) => {
    e.preventDefault();
    e.stopPropagation();
    const types = Array.from(e.dataTransfer.types);
    if (types.includes('application/aviso-id') || types.includes('application/evento-id') || types.includes('text/plain')) {
      e.dataTransfer.dropEffect = types.includes('application/aviso-id') ? 'copy' : 'move';
      setDragOverCell(`${fecha}-${tecnicoId}`);
    }
  };

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault();
    setDragOverCell(null);
  };

  const handleDrop = (e: React.DragEvent, fecha: string, tecnicoId: string) => {
    e.preventDefault();
    e.stopPropagation();
    justDroppedRef.current = true;
    setTimeout(() => { justDroppedRef.current = false; }, 300);
    // Check if it's an aviso being dropped
    const avisoId = e.dataTransfer.getData('application/aviso-id');
    if (avisoId) {
      onAvisoDrop(avisoId, fecha, tecnicoId);
    } else {
      // Check text/plain for evento
      const plainText = e.dataTransfer.getData('text/plain') || '';
      const eventoId = plainText.startsWith('evento:') ? plainText.replace('evento:', '') : e.dataTransfer.getData('application/evento-id');
      if (eventoId) {
        onEventoMoved(eventoId, fecha, tecnicoId);
      }
    }
    setDraggedEvento(null);
    setDragOverCell(null);
  };

  const handleDragEnd = () => {
    setDraggedEvento(null);
    setDragOverCell(null);
  };

  if (loading && eventos.length === 0) {
    return (
      <div className="bg-white rounded-xl border p-12 text-center">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#1a365d] mx-auto" />
        <p className="text-sm text-gray-500 mt-3">Cargando agenda...</p>
      </div>
    );
  }

  if (tecnicos.length === 0) {
    return (
      <div className="bg-white rounded-xl border p-12 text-center">
        <p className="text-gray-500">No hay técnicos disponibles</p>
      </div>
    );
  }

  return (
    <div className="bg-white rounded-xl border overflow-hidden">
      <div className="overflow-x-auto">
        <table className="w-full border-collapse min-w-[800px]">
          <thead>
            <tr className="bg-gray-50">
              <th className="text-left text-xs font-semibold text-gray-500 uppercase p-3 border-b border-r w-36 sticky left-0 bg-gray-50 z-10">
                Técnico
              </th>
              {days.map((day, i) => {
                const today = isToday(day);
                return (
                  <th
                    key={i}
                    className={`text-center text-xs font-semibold p-3 border-b border-r last:border-r-0 min-w-[130px] ${today ? 'bg-blue-50 text-blue-700' : 'text-gray-500'
                      }`}
                  >
                    <div className="uppercase">{DIAS[i]}</div>
                    <div className={`text-lg font-bold ${today ? 'text-blue-600' : 'text-gray-800'}`}>
                      {day.getDate()}
                    </div>
                    <div className="text-[10px] font-normal text-gray-400">
                      {day.toLocaleDateString('es-ES', { month: 'short' })}
                    </div>
                  </th>
                );
              })}
            </tr>
          </thead>
          <tbody>
            {tecnicos.map((tecnico) => (
              <tr key={tecnico.id} className="border-b last:border-b-0 hover:bg-gray-50/50">
                <td className="p-3 border-r text-sm font-medium text-gray-800 sticky left-0 bg-white z-10 align-top">
                  <div className="flex items-center gap-2">
                    <div className="w-7 h-7 rounded-full bg-[#1a365d] text-white flex items-center justify-center text-xs font-bold">
                      {tecnico.name?.charAt(0).toUpperCase() || '?'}
                    </div>
                    <div>
                      <span className="truncate max-w-[90px] block">{tecnico.name || tecnico.id}</span>
                      {tecnico.id === userId && (
                        <span className="text-[10px] text-blue-500">Tú</span>
                      )}
                    </div>
                  </div>
                </td>
                {days.map((day, i) => {
                  const fecha = formatDateISO(day);
                  const cellEventos = getEventosForCell(fecha, tecnico.id);
                  const cellKey = `${fecha}-${tecnico.id}`;
                  const isDragOver = dragOverCell === cellKey;
                  const today = isToday(day);

                  return (
                    <td
                      key={i}
                      className={`border-r last:border-r-0 p-1 align-top min-h-[70px] transition-colors cursor-pointer ${isDragOver ? 'bg-blue-100 ring-2 ring-inset ring-blue-400' : today ? 'bg-blue-50/30' : ''
                        }`}
                      onClick={() => { if (!justDroppedRef.current) onCellClick(fecha, tecnico.id); }}
                      onDragOver={(e) => handleDragOver(e, fecha, tecnico.id)}
                      onDragLeave={handleDragLeave}
                      onDrop={(e) => handleDrop(e, fecha, tecnico.id)}
                    >
                      <div className="min-h-[60px] space-y-1">
                        {cellEventos.map((ev, idx) => (
                          <div key={ev.id}>
                            {idx > 0 && (() => {
                              const tt = getTravelTimeBetween(cellEventos[idx - 1].id, ev.id);
                              return tt ? (
                                <div className="flex items-center justify-center gap-1 py-0.5 text-[10px] text-emerald-600 bg-emerald-50 rounded my-0.5" title={`${tt.distanceText} - ${tt.durationText}`}>
                                  <Car className="w-3 h-3" />
                                  <span className="font-medium">{tt.durationText}</span>
                                  <span className="text-emerald-400">({tt.distanceText})</span>
                                </div>
                              ) : null;
                            })()}
                            <EventoCard
                              evento={ev}
                              isDragging={draggedEvento === ev.id}
                              onDragStart={handleDragStart}
                              onDragEnd={handleDragEnd}
                              onClick={(e) => { e.stopPropagation(); onEventoClick(ev.id); }}
                            />
                          </div>
                        ))}
                      </div>
                    </td>
                  );
                })}
              </tr>
            ))}

            {/* Fila de eventos sin asignar */}
            {eventosSinAsignar.length > 0 && (
              <tr className="border-t-2 border-dashed border-orange-300 bg-orange-50/30">
                <td className="p-3 border-r text-sm font-medium text-orange-700 sticky left-0 bg-orange-50/50 z-10 align-top">
                  <div className="flex items-center gap-2">
                    <AlertTriangle className="w-4 h-4 text-orange-500" />
                    <span>Sin asignar</span>
                  </div>
                </td>
                {days.map((day, i) => {
                  const fecha = formatDateISO(day);
                  const cellEventos = eventosSinAsignar.filter(e => e.fecha.split('T')[0] === fecha);
                  return (
                    <td key={i} className="border-r last:border-r-0 p-1 align-top">
                      <div className="min-h-[40px] space-y-1">
                        {cellEventos.map((ev) => (
                          <EventoCard
                            key={ev.id}
                            evento={ev}
                            isDragging={draggedEvento === ev.id}
                            onDragStart={handleDragStart}
                            onDragEnd={handleDragEnd}
                            onClick={(e) => { e.stopPropagation(); onEventoClick(ev.id); }}
                          />
                        ))}
                      </div>
                    </td>
                  );
                })}
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function EventoCard({
  evento, isDragging, onDragStart, onDragEnd, onClick,
}: {
  evento: EventoAgenda;
  isDragging: boolean;
  onDragStart: (e: React.DragEvent, id: string) => void;
  onDragEnd: () => void;
  onClick: (e: React.MouseEvent) => void;
}) {
  const isAusencia = evento.tipo === 'AUSENCIA';
  const isHistorico = (evento.estado === 'COMPLETADO' || evento.estado === 'CANCELADO') && !isAusencia;

  let bg = isHistorico ? '#9ca3af' : (TIPO_EVENTO_BG[evento.tipo] || '#6b7280');
  let stripeStyle = {};
  if (isAusencia) {
    if (evento.titulo.includes('Vacaciones')) {
      bg = '#f59e0b'; stripeStyle = { backgroundImage: 'repeating-linear-gradient(45deg, #fef3c7, #fef3c7 10px, #fffbeb 10px, #fffbeb 20px)' };
    } else if (evento.titulo.includes('Médica')) {
      bg = '#ef4444'; stripeStyle = { backgroundImage: 'repeating-linear-gradient(45deg, #fee2e2, #fee2e2 10px, #fef2f2 10px, #fef2f2 20px)' };
    } else {
      bg = '#3b82f6'; stripeStyle = { backgroundImage: 'repeating-linear-gradient(45deg, #dbeafe, #dbeafe 10px, #eff6ff 10px, #eff6ff 20px)' };
    }
  }

  return (
    <div
      draggable={!isHistorico && !isAusencia}
      onDragStart={(e) => { if (!isHistorico && !isAusencia) onDragStart(e, evento.id); }}
      onDragEnd={onDragEnd}
      onClick={(e) => { if (!isAusencia) onClick(e); }}
      className={`rounded-md px-2 py-1 text-[11px] border-l-[3px] transition-all ${(!isHistorico && !isAusencia) ? 'cursor-grab active:cursor-grabbing hover:shadow-md' : 'cursor-default'
        } ${isDragging ? 'opacity-50 scale-95' : ''} ${isHistorico ? 'opacity-70' : ''}`}
      style={{
        borderLeftColor: bg,
        backgroundColor: isHistorico ? '#f3f4f6' : (isAusencia ? undefined : `${bg}15`),
        ...stripeStyle
      }}
    >
      <div className={`flex items-center gap-1 font-medium truncate ${isHistorico ? 'text-gray-400' : 'text-gray-800'}`}>
        {!isAusencia && tipoIcon(evento.tipo)}
        <span className="truncate">{evento.titulo}</span>
      </div>
      {evento.horaInicio && !isAusencia && (
        <div className={`flex items-center gap-1 mt-0.5 ${isHistorico ? 'text-gray-400' : 'text-gray-500'}`}>
          <Clock className="w-2.5 h-2.5" />
          <span>{evento.horaInicio}{evento.horaFin ? `-${evento.horaFin}` : ''}</span>
        </div>
      )}
      {evento.aviso && evento.aviso.numero && (
        <div className={`truncate ${isHistorico ? 'text-gray-400' : 'text-gray-500'}`}>#{evento.aviso.numero} {evento.aviso.cliente || ''}</div>
      )}
      {evento.asignaciones && evento.asignaciones.length > 1 && !isAusencia && (
        <div className="text-gray-400 mt-0.5">
          +{evento.asignaciones.length - 1} técnico{evento.asignaciones.length > 2 ? 's' : ''}
        </div>
      )}
      {evento.estado !== 'PLANIFICADO' && !isAusencia && (
        <div className={`text-[10px] mt-0.5 ${isHistorico ? 'text-gray-400 font-medium' : 'text-gray-400'}`}>{ESTADO_EVENTO_LABELS[evento.estado]}</div>
      )}
    </div>
  );
}
