import React, { useState, useEffect } from "react";
import {
  Clock,
  Plus,
  Trash2,
  Save,
  Copy,
  Calendar as CalendarIcon,
  AlertCircle,
} from "lucide-react";
import toast from "react-hot-toast";
import { format, addDays, startOfWeek } from "date-fns";
import { ptBR } from "date-fns/locale";
import availabilityService from "../services/availabilityService";
import exceptionService from "../services/exceptionService";
import { useAuth } from "../hooks/useAuth";

interface TimeSlot {
  id: string;
  inicio: string;
  fim: string;
  ativo: boolean;
}

interface DaySchedule {
  day: string;
  dayOfWeek: number;
  enabled: boolean;
  slots: TimeSlot[];
}

const daysOfWeek = [
  { key: 0, label: "Domingo", dbKey: "domingo" },
  { key: 1, label: "Segunda-feira", dbKey: "segunda" },
  { key: 2, label: "Terça-feira", dbKey: "terca" },
  { key: 3, label: "Quarta-feira", dbKey: "quarta" },
  { key: 4, label: "Quinta-feira", dbKey: "quinta" },
  { key: 5, label: "Sexta-feira", dbKey: "sexta" },
  { key: 6, label: "Sábado", dbKey: "sabado" },
];

const DisponibilidadeMedico: React.FC = () => {
  const { user } = useAuth();
  const medicoId = user?.id || "";

  const [schedule, setSchedule] = useState<Record<number, DaySchedule>>({});
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [activeTab, setActiveTab] = useState<"weekly" | "blocked" | "settings">(
    "weekly"
  );

  // States for adding slots
  const [showAddSlotDialog, setShowAddSlotDialog] = useState(false);
  const [selectedDay, setSelectedDay] = useState<number | null>(null);
  const [newSlot, setNewSlot] = useState({ inicio: "09:00", fim: "10:00" });

  // States for blocked dates
  const [selectedDate, setSelectedDate] = useState<Date | undefined>(
    new Date()
  );
  const [blockedDates, setBlockedDates] = useState<Date[]>([]);
  const [exceptions, setExceptions] = useState<any[]>([]);

  // Settings
  const [consultationDuration, setConsultationDuration] = useState("60");
  const [breakTime, setBreakTime] = useState("0");

  useEffect(() => {
    if (medicoId) {
      loadAvailability();
      loadExceptions();
    }
  }, [medicoId]);

  const loadAvailability = async () => {
    try {
      setLoading(true);
      const response = await availabilityService.getAvailability(medicoId);

      if (response.success && response.data && response.data.length > 0) {
        const availabilityData = response.data[0];
        const newSchedule: Record<number, DaySchedule> = {};

        daysOfWeek.forEach(({ key, label, dbKey }) => {
          const dayData = availabilityData[dbKey];
          newSchedule[key] = {
            day: label,
            dayOfWeek: key,
            enabled: dayData?.ativo || false,
            slots:
              dayData?.horarios?.map((h: any, index: number) => ({
                id: `${key}-${index}`,
                inicio: h.inicio,
                fim: h.fim,
                ativo: h.ativo !== false,
              })) || [],
          };
        });

        setSchedule(newSchedule);
      } else {
        // Initialize empty schedule
        const newSchedule: Record<number, DaySchedule> = {};
        daysOfWeek.forEach(({ key, label }) => {
          newSchedule[key] = {
            day: label,
            dayOfWeek: key,
            enabled: false,
            slots: [],
          };
        });
        setSchedule(newSchedule);
      }
    } catch (error) {
      console.error("Erro ao carregar disponibilidade:", error);
      toast.error("Erro ao carregar disponibilidade");
    } finally {
      setLoading(false);
    }
  };

  const loadExceptions = async () => {
    try {
      const response = await exceptionService.listExceptions(medicoId);
      if (response.success && response.data) {
        setExceptions(response.data);
        const blocked = response.data
          .filter((exc: any) => exc.tipo === "bloqueio")
          .map((exc: any) => new Date(exc.data));
        setBlockedDates(blocked);
      }
    } catch (error) {
      console.error("Erro ao carregar exceções:", error);
    }
  };

  const toggleDay = (dayKey: number) => {
    setSchedule((prev) => ({
      ...prev,
      [dayKey]: {
        ...prev[dayKey],
        enabled: !prev[dayKey].enabled,
      },
    }));
  };

  const addTimeSlot = () => {
    if (selectedDay !== null) {
      const newSlotId = `${selectedDay}-${Date.now()}`;
      setSchedule((prev) => ({
        ...prev,
        [selectedDay]: {
          ...prev[selectedDay],
          slots: [
            ...prev[selectedDay].slots,
            {
              id: newSlotId,
              inicio: newSlot.inicio,
              fim: newSlot.fim,
              ativo: true,
            },
          ],
        },
      }));
      setShowAddSlotDialog(false);
      setNewSlot({ inicio: "09:00", fim: "10:00" });
      setSelectedDay(null);
    }
  };

  const removeTimeSlot = (dayKey: number, slotId: string) => {
    setSchedule((prev) => ({
      ...prev,
      [dayKey]: {
        ...prev[dayKey],
        slots: prev[dayKey].slots.filter((slot) => slot.id !== slotId),
      },
    }));
  };

  const toggleSlotAvailability = (dayKey: number, slotId: string) => {
    setSchedule((prev) => ({
      ...prev,
      [dayKey]: {
        ...prev[dayKey],
        slots: prev[dayKey].slots.map((slot) =>
          slot.id === slotId ? { ...slot, ativo: !slot.ativo } : slot
        ),
      },
    }));
  };

  const copySchedule = (fromDay: number) => {
    const sourceSchedule = schedule[fromDay];
    if (!sourceSchedule.enabled || sourceSchedule.slots.length === 0) {
      toast.error("Dia não tem horários configurados");
      return;
    }

    const updatedSchedule = { ...schedule };
    Object.keys(updatedSchedule).forEach((key) => {
      const dayKey = Number(key);
      if (dayKey !== fromDay && updatedSchedule[dayKey].enabled) {
        updatedSchedule[dayKey].slots = sourceSchedule.slots.map((slot) => ({
          ...slot,
          id: `${dayKey}-${slot.id}`,
        }));
      }
    });
    setSchedule(updatedSchedule);
    toast.success("Horários copiados com sucesso!");
  };

  const handleSaveSchedule = async () => {
    try {
      setSaving(true);

      // Build availability object
      const availabilityData: any = {
        medico_id: medicoId,
      };

      daysOfWeek.forEach(({ key, dbKey }) => {
        const daySchedule = schedule[key];
        availabilityData[dbKey] = {
          ativo: daySchedule.enabled,
          horarios: daySchedule.slots.map((slot) => ({
            inicio: slot.inicio,
            fim: slot.fim,
            ativo: slot.ativo,
          })),
        };
      });

      const response = await availabilityService.createAvailability(
        availabilityData
      );

      if (response.success) {
        toast.success("Disponibilidade salva com sucesso!");
        loadAvailability();
      } else {
        throw new Error(response.message || "Erro ao salvar");
      }
    } catch (error: any) {
      console.error("Erro ao salvar disponibilidade:", error);
      toast.error(error.message || "Erro ao salvar disponibilidade");
    } finally {
      setSaving(false);
    }
  };

  const toggleBlockedDate = async () => {
    if (!selectedDate) return;

    const dateString = format(selectedDate, "yyyy-MM-dd");
    const dateExists = blockedDates.some(
      (d) => format(d, "yyyy-MM-dd") === dateString
    );

    try {
      if (dateExists) {
        // Remove block
        const exception = exceptions.find(
          (exc) => format(new Date(exc.data), "yyyy-MM-dd") === dateString
        );
        if (exception) {
          await exceptionService.deleteException(exception._id);
          setBlockedDates(
            blockedDates.filter((d) => format(d, "yyyy-MM-dd") !== dateString)
          );
          toast.success("Data desbloqueada");
        }
      } else {
        // Add block
        const response = await exceptionService.createException({
          medicoId,
          data: dateString,
          tipo: "bloqueio",
          motivo: "Data bloqueada pelo médico",
        });
        if (response.success) {
          setBlockedDates([...blockedDates, selectedDate]);
          toast.success("Data bloqueada");
        }
      }
      loadExceptions();
    } catch (error) {
      console.error("Erro ao alternar bloqueio de data:", error);
      toast.error("Erro ao bloquear/desbloquear data");
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center h-64">
        <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-indigo-600"></div>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-2xl font-bold text-gray-900 dark:text-white">
            Gerenciar Disponibilidade
          </h2>
          <p className="text-gray-600 dark:text-gray-400">
            Configure seus horários de atendimento
          </p>
        </div>
        <button
          onClick={handleSaveSchedule}
          disabled={saving}
          className="flex items-center gap-2 px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg transition-colors disabled:opacity-50"
        >
          <Save className="h-4 w-4" />
          {saving ? "Salvando..." : "Salvar Alterações"}
        </button>
      </div>

      {/* Tabs */}
      <div className="border-b border-gray-200 dark:border-gray-700">
        <nav className="-mb-px flex space-x-8">
          <button
            onClick={() => setActiveTab("weekly")}
            className={`py-4 px-1 border-b-2 font-medium text-sm ${
              activeTab === "weekly"
                ? "border-indigo-500 text-indigo-600 dark:text-indigo-400"
                : "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"
            }`}
          >
            Horário Semanal
          </button>
          <button
            onClick={() => setActiveTab("blocked")}
            className={`py-4 px-1 border-b-2 font-medium text-sm ${
              activeTab === "blocked"
                ? "border-indigo-500 text-indigo-600 dark:text-indigo-400"
                : "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"
            }`}
          >
            Datas Bloqueadas ({blockedDates.length})
          </button>
          <button
            onClick={() => setActiveTab("settings")}
            className={`py-4 px-1 border-b-2 font-medium text-sm ${
              activeTab === "settings"
                ? "border-indigo-500 text-indigo-600 dark:text-indigo-400"
                : "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"
            }`}
          >
            Configurações
          </button>
        </nav>
      </div>

      {/* Tab Content - Weekly Schedule */}
      {activeTab === "weekly" && (
        <div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-6">
          <div className="space-y-6">
            <div>
              <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
                Horários por Dia da Semana
              </h3>
              <p className="text-gray-600 dark:text-gray-400">
                Defina seus horários de atendimento para cada dia da semana
              </p>
            </div>

            {daysOfWeek.map(({ key, label }) => (
              <div key={key} className="space-y-3">
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-3">
                    <label className="relative inline-flex items-center cursor-pointer">
                      <input
                        type="checkbox"
                        className="sr-only peer"
                        checked={schedule[key]?.enabled || false}
                        onChange={() => toggleDay(key)}
                      />
                      <div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 dark:peer-focus:ring-indigo-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-600"></div>
                    </label>
                    <span className="text-gray-900 dark:text-white font-medium">
                      {label}
                    </span>
                    {schedule[key]?.enabled && (
                      <span className="px-2 py-1 bg-indigo-100 dark:bg-indigo-900 text-indigo-600 dark:text-indigo-400 text-xs rounded">
                        {schedule[key]?.slots.length || 0} horário(s)
                      </span>
                    )}
                  </div>
                  {schedule[key]?.enabled && (
                    <div className="flex gap-2">
                      <button
                        onClick={() => copySchedule(key)}
                        className="flex items-center gap-1 px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
                      >
                        <Copy className="h-4 w-4" />
                        Copiar
                      </button>
                      <button
                        onClick={() => {
                          setSelectedDay(key);
                          setShowAddSlotDialog(true);
                        }}
                        className="flex items-center gap-1 px-3 py-1.5 text-sm bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg transition-colors"
                      >
                        <Plus className="h-4 w-4" />
                        Adicionar Horário
                      </button>
                    </div>
                  )}
                </div>

                {schedule[key]?.enabled && (
                  <div className="ml-14 space-y-2">
                    {schedule[key]?.slots.length === 0 ? (
                      <p className="text-gray-500 dark:text-gray-400">
                        Nenhum horário configurado
                      </p>
                    ) : (
                      schedule[key]?.slots.map((slot) => (
                        <div
                          key={slot.id}
                          className="flex items-center justify-between p-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/50"
                        >
                          <div className="flex items-center gap-3">
                            <label className="relative inline-flex items-center cursor-pointer">
                              <input
                                type="checkbox"
                                className="sr-only peer"
                                checked={slot.ativo}
                                onChange={() =>
                                  toggleSlotAvailability(key, slot.id)
                                }
                              />
                              <div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 dark:peer-focus:ring-indigo-800 rounded-full peer dark:bg-gray-600 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-600"></div>
                            </label>
                            <Clock className="h-4 w-4 text-gray-400" />
                            <span className="text-gray-900 dark:text-white">
                              {slot.inicio} - {slot.fim}
                            </span>
                            {!slot.ativo && (
                              <span className="px-2 py-1 bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200 text-xs rounded">
                                Bloqueado
                              </span>
                            )}
                          </div>
                          <button
                            onClick={() => removeTimeSlot(key, slot.id)}
                            className="p-2 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-colors"
                          >
                            <Trash2 className="h-4 w-4 text-red-600 dark:text-red-400" />
                          </button>
                        </div>
                      ))
                    )}
                  </div>
                )}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Tab Content - Blocked Dates */}
      {activeTab === "blocked" && (
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
          <div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-6">
            <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-4">
              Selecionar Datas
            </h3>
            <p className="text-gray-600 dark:text-gray-400 mb-4">
              Clique em uma data no calendário e depois no botão para
              bloquear/desbloquear
            </p>
            <div className="space-y-4">
              <input
                type="date"
                value={selectedDate ? format(selectedDate, "yyyy-MM-dd") : ""}
                onChange={(e) => setSelectedDate(new Date(e.target.value))}
                className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white"
              />
              <button
                onClick={toggleBlockedDate}
                disabled={!selectedDate}
                className="w-full py-2 px-4 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg transition-colors disabled:opacity-50"
              >
                {selectedDate &&
                blockedDates.some(
                  (d) =>
                    format(d, "yyyy-MM-dd") ===
                    format(selectedDate, "yyyy-MM-dd")
                )
                  ? "Desbloquear Data"
                  : "Bloquear Data"}
              </button>
            </div>
          </div>

          <div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-6">
            <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
              Datas Bloqueadas
            </h3>
            <p className="text-gray-600 dark:text-gray-400 mb-4">
              {blockedDates.length} data(s) bloqueada(s)
            </p>
            {blockedDates.length === 0 ? (
              <p className="text-gray-500 dark:text-gray-400 text-center py-8">
                Nenhuma data bloqueada
              </p>
            ) : (
              <div className="space-y-2 max-h-96 overflow-y-auto">
                {blockedDates.map((date, index) => (
                  <div
                    key={index}
                    className="flex items-center justify-between p-3 rounded-lg border border-gray-200 dark:border-gray-700"
                  >
                    <span className="text-gray-900 dark:text-white">
                      {format(date, "EEEE, dd 'de' MMMM 'de' yyyy", {
                        locale: ptBR,
                      })}
                    </span>
                    <button
                      onClick={() => {
                        setSelectedDate(date);
                        toggleBlockedDate();
                      }}
                      className="p-2 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-colors"
                    >
                      <Trash2 className="h-4 w-4 text-red-600 dark:text-red-400" />
                    </button>
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>
      )}

      {/* Tab Content - Settings */}
      {activeTab === "settings" && (
        <div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-6">
          <div className="space-y-6">
            <div>
              <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
                Configurações de Consulta
              </h3>
              <p className="text-gray-600 dark:text-gray-400">
                Defina as configurações padrão para suas consultas
              </p>
            </div>

            <div className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                  Duração Padrão da Consulta
                </label>
                <select
                  value={consultationDuration}
                  onChange={(e) => setConsultationDuration(e.target.value)}
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white"
                >
                  <option value="30">30 minutos</option>
                  <option value="45">45 minutos</option>
                  <option value="60">1 hora</option>
                  <option value="90">1 hora e 30 minutos</option>
                  <option value="120">2 horas</option>
                </select>
                <p className="text-gray-500 dark:text-gray-400 text-sm mt-1">
                  Esta duração será usada para calcular os horários disponíveis
                </p>
              </div>

              <div>
                <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                  Intervalo entre Consultas
                </label>
                <select
                  value={breakTime}
                  onChange={(e) => setBreakTime(e.target.value)}
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white"
                >
                  <option value="0">Sem intervalo</option>
                  <option value="15">15 minutos</option>
                  <option value="30">30 minutos</option>
                </select>
                <p className="text-gray-500 dark:text-gray-400 text-sm mt-1">
                  Tempo de descanso entre consultas
                </p>
              </div>

              <div className="flex items-center justify-between p-4 rounded-lg border border-gray-200 dark:border-gray-700">
                <div>
                  <p className="text-gray-900 dark:text-white font-medium">
                    Aceitar consultas online
                  </p>
                  <p className="text-gray-500 dark:text-gray-400 text-sm">
                    Permitir agendamento de teleconsultas
                  </p>
                </div>
                <label className="relative inline-flex items-center cursor-pointer">
                  <input
                    type="checkbox"
                    className="sr-only peer"
                    defaultChecked
                  />
                  <div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 dark:peer-focus:ring-indigo-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-600"></div>
                </label>
              </div>

              <div className="flex items-center justify-between p-4 rounded-lg border border-gray-200 dark:border-gray-700">
                <div>
                  <p className="text-gray-900 dark:text-white font-medium">
                    Confirmação automática
                  </p>
                  <p className="text-gray-500 dark:text-gray-400 text-sm">
                    Aprovar agendamentos automaticamente
                  </p>
                </div>
                <label className="relative inline-flex items-center cursor-pointer">
                  <input type="checkbox" className="sr-only peer" />
                  <div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 dark:peer-focus:ring-indigo-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-600"></div>
                </label>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Add Time Slot Dialog */}
      {showAddSlotDialog && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
          <div className="bg-white dark:bg-gray-800 rounded-lg p-6 max-w-md w-full mx-4">
            <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-4">
              Adicionar Horário
            </h3>
            <p className="text-gray-600 dark:text-gray-400 mb-4">
              Defina o período de atendimento para{" "}
              {selectedDay !== null ? schedule[selectedDay]?.day : ""}
            </p>
            <div className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                  Horário de Início
                </label>
                <input
                  type="time"
                  value={newSlot.inicio}
                  onChange={(e) =>
                    setNewSlot({ ...newSlot, inicio: e.target.value })
                  }
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white"
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                  Horário de Término
                </label>
                <input
                  type="time"
                  value={newSlot.fim}
                  onChange={(e) =>
                    setNewSlot({ ...newSlot, fim: e.target.value })
                  }
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white"
                />
              </div>
            </div>
            <div className="flex gap-2 mt-6">
              <button
                onClick={() => {
                  setShowAddSlotDialog(false);
                  setSelectedDay(null);
                }}
                className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
              >
                Cancelar
              </button>
              <button
                onClick={addTimeSlot}
                className="flex-1 px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg transition-colors"
              >
                Adicionar
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default DisponibilidadeMedico;
