'use client';

import { useState, useMemo } from 'react';
import {
  Clock, Wrench, ClipboardList, Briefcase, User, Car,
  MapPin, Navigation, Share2, ExternalLink, Route,
} from 'lucide-react';
import {
  TIPO_EVENTO_BG, ESTADO_EVENTO_LABELS, ESTADO_EVENTO_COLORS,
  TIPO_EVENTO_LABELS,
} from '@/lib/agenda/constants';
import type { EventoAgenda, Tecnico, TravelTime } from './agenda-content';

interface Props {
  currentDate: 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 HOURS = Array.from({ length: 13 }, (_, i) => i + 7); // 7:00 - 19:00
const HOUR_HEIGHT = 80; // px per hour
const MIN_HEIGHT = HOUR_HEIGHT / 60; // px per minute

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 timeToMinutes(t: string): number {
  const [h, m] = t.split(':').map(Number);
  return h * 60 + m;
}

function minutesToTime(m: number): string {
  const hh = Math.floor(m / 60);
  const mm = m % 60;
  return `${String(hh).padStart(2, '0')}:${String(mm).padStart(2, '0')}`;
}

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

function getClientAddress(evento: EventoAgenda): string | null {
  const dirs = evento.aviso?.clienteRef?.direcciones;
  if (!dirs || dirs.length === 0) return null;
  const d = dirs[0];
  return [d.calle, d.numero, d.codigoPostal, d.ciudad, d.provincia].filter(Boolean).join(', ');
}

export default function AgendaDiaria({
  currentDate, eventos, tecnicos, loading, userRole, userId, travelTimes,
  onCellClick, onEventoClick, onEventoMoved, onAvisoDrop,
}: Props) {
  const [dragOverCell, setDragOverCell] = useState<string | null>(null);
  const [showRouteModal, setShowRouteModal] = useState<string | null>(null); // tecnicoId
  const fecha = formatDateISO(currentDate);

  const dayEventos = useMemo(() =>
    eventos.filter(e => e.fecha.split('T')[0] === fecha),
    [eventos, fecha]
  );

  const tecnicoIds = userRole === 'operario' ? [userId] : tecnicos.map(t => t.id);

  const getEventosForTecnico = (tecnicoId: string): EventoAgenda[] => {
    return dayEventos
      .filter(e => e.asignaciones.some(a => a.tecnicoId === tecnicoId))
      .sort((a, b) => {
        if (!a.horaInicio) return -1;
        if (!b.horaInicio) return 1;
        return a.horaInicio.localeCompare(b.horaInicio);
      });
  };

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

  const getEventPosition = (evento: EventoAgenda) => {
    if (!evento.horaInicio) return null;
    const startMin = timeToMinutes(evento.horaInicio) - 7 * 60;
    let durationMin = 60;
    if (evento.horaFin) {
      durationMin = timeToMinutes(evento.horaFin) - timeToMinutes(evento.horaInicio);
    } else if (evento.duracionMinutos) {
      durationMin = evento.duracionMinutos;
    }
    return {
      top: Math.max(0, startMin * MIN_HEIGHT),
      height: Math.max(24, durationMin * MIN_HEIGHT),
      startMin,
      durationMin,
    };
  };

  // Build Google Maps route URL for a technician
  const buildRouteUrl = (tecnicoId: string): string | null => {
    const tecEventos = getEventosForTecnico(tecnicoId)
      .filter(e => e.horaInicio && !e.todoElDia && getClientAddress(e));
    if (tecEventos.length < 2) return null;
    const addresses = tecEventos.map(e => getClientAddress(e)!).map(a => encodeURIComponent(a));
    // Google Maps directions: origin / destination / waypoints
    const origin = addresses[0];
    const destination = addresses[addresses.length - 1];
    const waypoints = addresses.slice(1, -1).join('|');
    let url = `https://www.google.com/maps/dir/?api=1&origin=${origin}&destination=${destination}`;
    if (waypoints) url += `&waypoints=${waypoints}`;
    url += '&travelmode=driving';
    return url;
  };

  const handleDragOver = (e: React.DragEvent, 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(tecnicoId);
    }
  };

  const handleDrop = (e: React.DragEvent, tecnicoId: string) => {
    e.preventDefault();
    e.stopPropagation();
    const avisoId = e.dataTransfer.getData('application/aviso-id');
    if (avisoId) {
      onAvisoDrop(avisoId, fecha, tecnicoId);
    } else {
      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);
    }
    setDragOverCell(null);
  };

  const handleShareRoute = async (tecnicoId: string) => {
    const url = buildRouteUrl(tecnicoId);
    if (!url) return;
    if (navigator.share) {
      try {
        const tecnico = tecnicos.find(t => t.id === tecnicoId);
        await navigator.share({
          title: `Ruta de ${tecnico?.name || 'Técnico'} - ${currentDate.toLocaleDateString('es-ES')}`,
          text: `Ruta optimizada para ${currentDate.toLocaleDateString('es-ES', { weekday: 'long', day: 'numeric', month: 'long' })}`,
          url,
        });
      } catch { /* user cancelled */ }
    } else {
      try {
        await navigator.clipboard.writeText(url);
        alert('Enlace de ruta copiado al portapapeles');
      } catch {
        window.open(url, '_blank');
      }
    }
  };

  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...</p>
      </div>
    );
  }

  const totalMinutes = 13 * 60; // 7:00 to 20:00
  const gridHeight = totalMinutes * MIN_HEIGHT;

  return (
    <div className="bg-white rounded-xl border overflow-hidden">
      <div className="overflow-x-auto">
        <div className="min-w-[600px]">
          {/* Header: Technician columns */}
          <div className="flex border-b bg-gray-50">
            <div className="w-16 flex-shrink-0 p-2 border-r">
              <span className="text-[10px] text-gray-400 uppercase">Hora</span>
            </div>
            {tecnicoIds.map(tid => {
              const t = tecnicos.find(tc => tc.id === tid);
              const routeUrl = buildRouteUrl(tid);
              const tecEventos = getEventosForTecnico(tid).filter(e => e.horaInicio && !e.todoElDia);
              return (
                <div key={tid} className="flex-1 min-w-[200px] p-3 border-r last:border-r-0">
                  <div className="flex items-center justify-between">
                    <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">
                        {t?.name?.charAt(0).toUpperCase() || '?'}
                      </div>
                      <div>
                        <span className="text-sm font-medium text-gray-800 block">{t?.name || tid}</span>
                        <span className="text-[10px] text-gray-400">{tecEventos.length} citas</span>
                      </div>
                    </div>
                    {routeUrl && (
                      <div className="flex items-center gap-1">
                        <button
                          onClick={() => window.open(routeUrl, '_blank')}
                          className="flex items-center gap-1 px-2 py-1 text-[10px] font-medium bg-emerald-50 text-emerald-700 rounded-md hover:bg-emerald-100 transition-colors"
                          title="Ver ruta optimizada"
                        >
                          <Route className="w-3 h-3" /> Ruta
                        </button>
                        <button
                          onClick={() => handleShareRoute(tid)}
                          className="p-1 text-gray-400 hover:text-emerald-600 transition-colors"
                          title="Compartir ruta"
                        >
                          <Share2 className="w-3.5 h-3.5" />
                        </button>
                      </div>
                    )}
                  </div>
                </div>
              );
            })}
          </div>

          {/* Time grid */}
          <div className="flex" style={{ height: `${gridHeight}px` }}>
            {/* Hours column */}
            <div className="w-16 flex-shrink-0 border-r relative bg-gray-50/50">
              {HOURS.map(h => (
                <div
                  key={h}
                  className="absolute left-0 right-0 border-t border-gray-200 px-2"
                  style={{ top: `${(h - 7) * HOUR_HEIGHT}px`, height: `${HOUR_HEIGHT}px` }}
                >
                  <span className="text-[10px] text-gray-500 font-medium -translate-y-1/2 block">
                    {String(h).padStart(2, '0')}:00
                  </span>
                </div>
              ))}
            </div>

            {/* Technician columns */}
            {tecnicoIds.map(tid => {
              const tecEventos = getEventosForTecnico(tid);
              const isDragOver = dragOverCell === tid;
              const timedEvents = tecEventos.filter(e => e.horaInicio && !e.todoElDia);
              const allDayEvents = tecEventos.filter(e => e.todoElDia || !e.horaInicio);

              return (
                <div
                  key={tid}
                  className={`flex-1 min-w-[200px] border-r last:border-r-0 relative ${isDragOver ? 'bg-blue-50/50' : ''
                    }`}
                  onClick={() => onCellClick(fecha, tid)}
                  onDragOver={(e) => handleDragOver(e, tid)}
                  onDragLeave={() => setDragOverCell(null)}
                  onDrop={(e) => handleDrop(e, tid)}
                >
                  {/* Hour lines */}
                  {HOURS.map(h => (
                    <div
                      key={h}
                      className="absolute left-0 right-0 border-t border-gray-100"
                      style={{ top: `${(h - 7) * HOUR_HEIGHT}px`, height: `${HOUR_HEIGHT}px` }}
                    />
                  ))}
                  {/* Half-hour lines */}
                  {HOURS.map(h => (
                    <div
                      key={`half-${h}`}
                      className="absolute left-0 right-0 border-t border-gray-50"
                      style={{ top: `${(h - 7) * HOUR_HEIGHT + HOUR_HEIGHT / 2}px` }}
                    />
                  ))}

                  {/* All-day events at top */}
                  {allDayEvents.map((ev, idx) => {
                    const isAusencia = ev.tipo === 'AUSENCIA';
                    const isHistorico = (ev.estado === 'COMPLETADO' || ev.estado === 'CANCELADO') && !isAusencia;

                    let bg = isHistorico ? '#9ca3af' : (TIPO_EVENTO_BG[ev.tipo] || '#6b7280');
                    let stripeStyle = {};
                    if (isAusencia) {
                      if (ev.titulo.includes('Vacaciones')) {
                        bg = '#f59e0b'; stripeStyle = { backgroundImage: 'repeating-linear-gradient(45deg, #fef3c7, #fef3c7 10px, #fffbeb 10px, #fffbeb 20px)' };
                      } else if (ev.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
                        key={ev.id}
                        onClick={(e) => { e.stopPropagation(); if (!isAusencia) onEventoClick(ev.id); }}
                        className={`mx-1 rounded-md p-1.5 text-[11px] border-l-[3px] relative z-10 
                          ${!isAusencia ? 'cursor-pointer hover:shadow-md' : 'cursor-default'} 
                          ${isHistorico ? 'opacity-70' : ''}`}
                        style={{
                          borderLeftColor: bg,
                          backgroundColor: isHistorico ? '#f3f4f6' : (isAusencia ? undefined : `${bg}15`),
                          marginTop: `${idx * 28 + 4}px`,
                          ...stripeStyle
                        }}
                      >
                        <div className={`flex items-center gap-1 font-bold ${isHistorico ? 'text-gray-400' : 'text-gray-800'}`}>
                          {!isAusencia && tipoIcon(ev.tipo)}
                          <span className="truncate">{ev.titulo}</span>
                        </div>
                        {!isAusencia && <span className="text-gray-400 text-[10px]">Todo el día</span>}
                      </div>
                    );
                  })}

                  {/* Timed events */}
                  {timedEvents.map((ev, evIdx) => {
                    const pos = getEventPosition(ev);
                    if (!pos) return null;
                    const isHistorico = ev.estado === 'COMPLETADO' || ev.estado === 'CANCELADO';
                    const bg = isHistorico ? '#9ca3af' : (TIPO_EVENTO_BG[ev.tipo] || '#6b7280');
                    const address = getClientAddress(ev);

                    // Find travel time TO this event (from previous)
                    let travelBefore: TravelTime | undefined;
                    if (evIdx > 0) {
                      travelBefore = getTravelTimeBetween(timedEvents[evIdx - 1].id, ev.id);
                    }

                    return (
                      <div key={ev.id}>
                        {/* Travel time indicator BEFORE event */}
                        {travelBefore && (() => {
                          const prevEv = timedEvents[evIdx - 1];
                          const prevPos = getEventPosition(prevEv);
                          if (!prevPos) return null;
                          const travelTop = prevPos.top + prevPos.height;
                          const travelHeight = pos.top - travelTop;
                          if (travelHeight < 8) return null;
                          return (
                            <div
                              className="absolute left-2 right-2 flex items-center justify-center z-5"
                              style={{
                                top: `${travelTop}px`,
                                height: `${travelHeight}px`,
                              }}
                            >
                              <div className="flex items-center gap-1 bg-amber-50 border border-amber-200 rounded px-2 py-0.5">
                                <Car className="w-3 h-3 text-amber-600" />
                                <span className="text-[10px] font-medium text-amber-700">
                                  {travelBefore.durationText} ({travelBefore.distanceText})
                                </span>
                              </div>
                            </div>
                          );
                        })()}

                        {/* Event block */}
                        <div
                          onClick={(e) => { e.stopPropagation(); onEventoClick(ev.id); }}
                          draggable
                          onDragStart={(e) => {
                            e.dataTransfer.setData('text/plain', `evento:${ev.id}`);
                            e.dataTransfer.setData('application/evento-id', ev.id);
                          }}
                          className={`absolute left-1 right-1 rounded-lg p-2 text-[11px] cursor-pointer hover:shadow-lg border-l-[3px] overflow-hidden z-10 transition-shadow ${isHistorico ? 'opacity-70' : ''}`}
                          style={{
                            top: `${pos.top}px`,
                            height: `${pos.height}px`,
                            minHeight: '28px',
                            borderLeftColor: bg,
                            backgroundColor: isHistorico ? '#f3f4f6' : `${bg}18`,
                          }}
                        >
                          <div className={`flex items-center gap-1 font-semibold ${isHistorico ? 'text-gray-400' : 'text-gray-800'}`}>
                            {tipoIcon(ev.tipo)}
                            <span className="truncate">{ev.titulo}</span>
                          </div>
                          <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 className="font-medium">{ev.horaInicio}{ev.horaFin ? ` - ${ev.horaFin}` : ''}</span>
                            {ev.duracionMinutos && <span className={isHistorico ? 'text-gray-400' : 'text-gray-400'}>({ev.duracionMinutos}min)</span>}
                          </div>
                          {ev.aviso && ev.aviso.numero && pos.height > 48 && (
                            <div className={`flex items-center gap-1 mt-0.5 ${isHistorico ? 'text-gray-400' : 'text-gray-500'}`}>
                              <User className="w-2.5 h-2.5" />
                              <span className="truncate">#{ev.aviso.numero} {ev.aviso.cliente || ''}</span>
                            </div>
                          )}
                          {address && pos.height > 64 && (
                            <div className="flex items-center gap-1 text-gray-400 mt-0.5">
                              <MapPin className="w-2.5 h-2.5" />
                              <span className="truncate text-[10px]">{address}</span>
                            </div>
                          )}
                          {ev.estado !== 'PLANIFICADO' && pos.height > 50 && (
                            <span className={`text-[10px] px-1 py-0.5 rounded mt-0.5 inline-block ${isHistorico ? 'bg-gray-100 text-gray-400' : (ESTADO_EVENTO_COLORS[ev.estado] || '')}`}>
                              {ESTADO_EVENTO_LABELS[ev.estado]}
                            </span>
                          )}
                        </div>
                      </div>
                    );
                  })}
                </div>
              );
            })}
          </div>

          {/* Summary strip at bottom */}
          <div className="flex border-t bg-gray-50">
            <div className="w-16 flex-shrink-0 border-r p-2">
              <span className="text-[10px] text-gray-400">Total</span>
            </div>
            {tecnicoIds.map(tid => {
              const tecEventos = getEventosForTecnico(tid).filter(e => e.horaInicio && !e.todoElDia);
              const totalMin = tecEventos.reduce((sum, e) => {
                if (e.horaInicio && e.horaFin) {
                  return sum + (timeToMinutes(e.horaFin) - timeToMinutes(e.horaInicio));
                }
                return sum + (e.duracionMinutos || 60);
              }, 0);
              // Sum travel times for this technician
              const tecTravelMin = travelTimes
                .filter(t => tecEventos.some(e => e.id === t.fromEventoId || e.id === t.toEventoId))
                .reduce((sum, t) => sum + t.durationMinutes, 0);

              return (
                <div key={tid} className="flex-1 min-w-[200px] p-2 border-r last:border-r-0">
                  <div className="flex items-center gap-3 text-[10px] text-gray-500">
                    <span>{tecEventos.length} citas</span>
                    <span>{Math.floor(totalMin / 60)}h {totalMin % 60}min trabajo</span>
                    {tecTravelMin > 0 && (
                      <span className="flex items-center gap-0.5 text-amber-600">
                        <Car className="w-2.5 h-2.5" />
                        {tecTravelMin}min traslado
                      </span>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}
