/**
 * @file CalendarWeekView.tsx
 * @description Componente visual para apresentação de Agendamentos sob a perspetiva de uma semana.
 * Implementa lógica de negócio de calendário (cálculo de slots horários de 30 minutos, 
 * identificação do dia atual e posicionamento dinâmico do indicador da hora presente).
 */
import { useMemo, useState, useEffect } from 'react';
import { ChevronLeft, ChevronRight, ZoomIn, ZoomOut, RefreshCw } from 'lucide-react';
import { Appointment, BarberShop } from '../types';
import { Badge } from './ui/badge';
import { Button } from './ui/button';

type CalendarWeekViewProps = {
  week: Date;
  appointments: Appointment[];
  shop: BarberShop;
  onWeekChange: (date: Date) => void;
  onStatusChange: (id: string, status: Appointment['status']) => void;
};

export const CalendarWeekView = ({
  week,
  appointments,
  shop,
  onWeekChange,
  onStatusChange,
}: CalendarWeekViewProps) => {
  const [currentTime, setCurrentTime] = useState(new Date());

  // Atualizar hora atual a cada minuto
  useEffect(() => {
    const interval = setInterval(() => {
      setCurrentTime(new Date());
    }, 60000);
    return () => clearInterval(interval);
  }, []);

  // Obter dias da semana
  const weekDays = useMemo(() => {
    const startOfWeek = new Date(week);
    const day = startOfWeek.getDay();
    const diff = startOfWeek.getDate() - day + (day === 0 ? -6 : 1); // Segunda-feira
    startOfWeek.setDate(diff);

    const days = [];
    for (let i = 0; i < 7; i++) {
      const date = new Date(startOfWeek);
      date.setDate(startOfWeek.getDate() + i);
      days.push(date);
    }
    return days;
  }, [week]);

  // Gerar slots de horário (08:00 até 18:00, intervalos de 30 minutos)
  const timeSlots = useMemo(() => {
    const slots: string[] = [];
    for (let hour = 8; hour <= 18; hour++) {
      slots.push(`${hour.toString().padStart(2, '0')}:00`);
      if (hour < 18) {
        slots.push(`${hour.toString().padStart(2, '0')}:30`);
      }
    }
    return slots;
  }, []);

  // Formatar data para YYYY-MM-DD
  const formatDateKey = (date: Date) => {
    return date.toISOString().split('T')[0];
  };

  // Obter agendamentos para um dia e horário específicos
  const getAppointmentsAtSlot = (date: Date, timeSlot: string) => {
    const dateKey = formatDateKey(date);
    return appointments.filter((apt) => {
      const aptDate = apt.date.split(' ')[0];
      const aptTime = apt.date.split(' ')[1]?.substring(0, 5);
      return aptDate === dateKey && aptTime === timeSlot;
    });
  };

  // Navegação de semana
  const goToPreviousWeek = () => {
    const newDate = new Date(week);
    newDate.setDate(newDate.getDate() - 7);
    onWeekChange(newDate);
  };

  const goToNextWeek = () => {
    const newDate = new Date(week);
    newDate.setDate(newDate.getDate() + 7);
    onWeekChange(newDate);
  };

  const goToToday = () => {
    onWeekChange(new Date());
  };

  // Verificar se é hoje
  const isToday = (date: Date) => {
    const today = new Date();
    return (
      date.getDate() === today.getDate() &&
      date.getMonth() === today.getMonth() &&
      date.getFullYear() === today.getFullYear()
    );
  };

  // Obter posição da linha de hora atual
  const getCurrentTimePosition = (date: Date) => {
    if (!isToday(date)) return null;
    const now = currentTime;
    const hours = now.getHours();
    const minutes = now.getMinutes();
    const totalMinutes = hours * 60 + minutes;
    const startMinutes = 8 * 60; // 08:00
    const slotIndex = Math.floor((totalMinutes - startMinutes) / 30);
    if (slotIndex < 0 || slotIndex >= timeSlots.length) return null;
    return slotIndex;
  };

  // Nomes dos dias da semana
  const dayNames = ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb', 'Dom'];
  const dayNamesFull = ['Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado', 'Domingo'];

  return (
    <div className="space-y-4">
      {/* Header com navegação */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <Button variant="outline" size="sm" onClick={goToPreviousWeek}>
            <ChevronLeft size={18} />
          </Button>
          <Button variant="outline" size="sm" onClick={goToToday}>
            Hoje
          </Button>
          <Button variant="outline" size="sm" onClick={goToNextWeek}>
            <ChevronRight size={18} />
          </Button>
          <div className="ml-4">
            <h3 className="text-lg font-bold text-slate-900">
              {weekDays[0].toLocaleDateString('pt-PT', { day: 'numeric', month: 'long' })} -{' '}
              {weekDays[6].toLocaleDateString('pt-PT', { day: 'numeric', month: 'long' })}
            </h3>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <Button variant="ghost" size="sm">
            <ZoomOut size={18} />
          </Button>
          <Button variant="ghost" size="sm">
            <ZoomIn size={18} />
          </Button>
          <Button variant="ghost" size="sm">
            <RefreshCw size={18} />
          </Button>
        </div>
      </div>

      {/* Calendário */}
      <div className="border border-slate-200 rounded-lg overflow-hidden">
        {/* Cabeçalho com dias da semana */}
        <div className="grid grid-cols-8 border-b border-slate-200 bg-slate-50">
          <div className="p-3 border-r border-slate-200"></div>
          {weekDays.map((day, idx) => (
            <div
              key={idx}
              className={`p-3 text-center border-r border-slate-200 last:border-r-0 ${isToday(day) ? 'bg-indigo-50' : ''
                }`}
            >
              <div className="text-xs font-medium text-slate-500 mb-1">{dayNames[idx]}</div>
              <div
                className={`text-lg font-bold ${isToday(day) ? 'text-indigo-700' : 'text-slate-900'
                  }`}
              >
                {day.getDate()}
              </div>
            </div>
          ))}
        </div>

        {/* Grade de horários */}
        <div className="overflow-y-auto max-h-[600px]">
          <div className="grid grid-cols-8">
            {/* Coluna de horários */}
            <div className="border-r border-slate-200 bg-slate-50">
              {timeSlots.map((slot) => (
                <div
                  key={slot}
                  className="h-16 border-b border-slate-100 flex items-start justify-end pr-2 pt-1"
                >
                  <span className="text-xs text-slate-500">{slot}</span>
                </div>
              ))}
            </div>

            {/* Colunas dos dias */}
            {weekDays.map((day, dayIdx) => {
              const currentTimePos = getCurrentTimePosition(day);
              return (
                <div key={dayIdx} className="border-r border-slate-200 last:border-r-0 relative">
                  {timeSlots.map((slot, slotIdx) => {
                    const slotAppointments = getAppointmentsAtSlot(day, slot);
                    const isCurrentTimeSlot = currentTimePos === slotIdx;

                    return (
                      <div
                        key={slot}
                        className="h-16 border-b border-slate-100 relative hover:bg-slate-50/50 transition-colors"
                      >
                        {/* Linha de hora atual */}
                        {isCurrentTimeSlot && (
                          <div className="absolute top-0 left-0 right-0 h-0.5 bg-indigo-500 z-10">
                            <div className="absolute -left-2 top-1/2 -translate-y-1/2 w-3 h-3 bg-indigo-500 rounded-full"></div>
                          </div>
                        )}

                        {/* Agendamentos */}
                        {slotAppointments.map((apt, aptIdx) => {
                          const service = shop.services.find((s) => s.id === apt.serviceId);
                          const barber = shop.barbers.find((b) => b.id === apt.barberId);
                          const statusColors = {
                            pendente: 'bg-indigo-100 border-indigo-300 text-indigo-800',
                            confirmado: 'bg-green-100 border-green-300 text-green-800',
                            concluido: 'bg-blue-100 border-blue-300 text-blue-800',
                            cancelado: 'bg-red-100 border-red-300 text-red-800',
                          };

                          return (
                            <div
                              key={apt.id}
                              className={`absolute left-1 right-1 top-1 bottom-1 rounded border-l-2 p-1 text-xs overflow-hidden ${statusColors[apt.status]}`}
                              style={{ zIndex: 5 + aptIdx }}
                            >
                              <div className="font-semibold truncate">{service?.name || 'Serviço'}</div>
                              <div className="text-[10px] opacity-80 truncate">{barber?.name || 'Barbeiro'}</div>
                              <div className="text-[10px] opacity-70 mt-0.5">
                                {apt.date.split(' ')[1]?.substring(0, 5)}
                              </div>
                            </div>
                          );
                        })}
                      </div>
                    );
                  })}
                </div>
              );
            })}
          </div>
        </div>
      </div>

      {/* Legenda */}
      <div className="flex items-center gap-4 text-xs">
        <div className="flex items-center gap-2">
          <div className="w-4 h-4 rounded border-l-2 bg-indigo-100 border-indigo-300"></div>
          <span>Pendente</span>
        </div>
        <div className="flex items-center gap-2">
          <div className="w-4 h-4 rounded border-l-2 bg-green-100 border-green-300"></div>
          <span>Confirmado</span>
        </div>
        <div className="flex items-center gap-2">
          <div className="w-4 h-4 rounded border-l-2 bg-blue-100 border-blue-300"></div>
          <span>Concluído</span>
        </div>
        <div className="flex items-center gap-2">
          <div className="w-4 h-4 rounded border-l-2 bg-red-100 border-red-300"></div>
          <span>Cancelado</span>
        </div>
      </div>
    </div>
  );
};
