import React, { useState, useEffect } from "react";
import { Clock, Plus, Trash2, Save, Copy } from "lucide-react";
import toast from "react-hot-toast";
import { format } from "date-fns";
import { ptBR } from "date-fns/locale";
import { availabilityService, doctorService } from "../services/index";
import type {
  DoctorException,
  DoctorAvailability,
} from "../services/availability/types";
import { useAuth } from "../hooks/useAuth";

interface TimeSlot {
  id: string;
  dbId?: string;
  inicio: string;
  fim: string;
  ativo: boolean;
  slotMinutes?: number;
  appointmentType?: "presencial" | "telemedicina";
}

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

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

const DisponibilidadeMedico: React.FC = () => {
  const { user } = useAuth();
  const [doctorId, setDoctorId] = useState<string | null>(null);
  const [schedule, setSchedule] = useState<Record<number, DaySchedule>>({});
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [activeTab, setActiveTab] = useState<"weekly" | "blocked">("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",
    slotMinutes: 30,
    appointmentType: "presencial" as "presencial" | "telemedicina",
  });

  // States for exceptions
  const [exceptions, setExceptions] = useState<DoctorException[]>([]);
  const [exceptionForm, setExceptionForm] = useState({
    date: format(new Date(), "yyyy-MM-dd"),
    kind: "bloqueio" as "bloqueio" | "disponibilidade_extra",
    start_time: "09:00",
    end_time: "18:00",
    wholeDayBlock: true,
    reason: "",
  });

  // Load doctor ID
  useEffect(() => {
    const loadDoctorId = async () => {
      if (!user?.id) return;
      try {
        const doctors = await doctorService.list({});
        const doctor = doctors.find((d: any) => d.user_id === user.id);
        if (doctor) {
          setDoctorId(doctor.id);
        }
      } catch (error) {
        console.error("Erro ao buscar ID do médico:", error);
      }
    };
    loadDoctorId();
  }, [user?.id]);

  const loadAvailability = React.useCallback(async () => {
    if (!doctorId) return;

    try {
      setLoading(true);
      const availabilities = await availabilityService.list({
        doctor_id: doctorId,
      });

      const newSchedule: Record<number, DaySchedule> = {};
      daysOfWeek.forEach(({ key, label }) => {
        newSchedule[key] = {
          day: label,
          dayOfWeek: key,
          enabled: false,
          slots: [],
        };
      });

      availabilities.forEach((avail: DoctorAvailability) => {
        const dayKey = avail.weekday;
        if (!newSchedule[dayKey]) return;

        newSchedule[dayKey].enabled = true;
        newSchedule[dayKey].slots.push({
          id: `${dayKey}-${avail.id || Math.random().toString(36).slice(2)}`,
          dbId: avail.id,
          inicio: avail.start_time?.slice(0, 5) || "09:00",
          fim: avail.end_time?.slice(0, 5) || "17:00",
          ativo: avail.active ?? true,
          slotMinutes: avail.slot_minutes || 30,
          appointmentType: avail.appointment_type || "presencial",
        });
      });

      setSchedule(newSchedule);
    } catch (error) {
      console.error("Erro ao carregar disponibilidade:", error);
      toast.error("Erro ao carregar disponibilidade");
    } finally {
      setLoading(false);
    }
  }, [doctorId]);

  const loadExceptions = React.useCallback(async () => {
    if (!doctorId) return;

    try {
      const exceptions = await availabilityService.listExceptions({
        doctor_id: doctorId,
      });
      setExceptions(exceptions);
    } catch (error) {
      console.error("Erro ao carregar exceções:", error);
    }
  }, [doctorId]);

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

  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,
              slotMinutes: newSlot.slotMinutes,
              appointmentType: newSlot.appointmentType,
            },
          ],
        },
      }));
      setShowAddSlotDialog(false);
      setNewSlot({
        inicio: "09:00",
        fim: "10:00",
        slotMinutes: 30,
        appointmentType: "presencial",
      });
      setSelectedDay(null);
    }
  };

  const removeTimeSlot = async (dayKey: number, slotId: string) => {
    const slot = schedule[dayKey]?.slots.find((s) => s.id === slotId);

    if (slot?.dbId) {
      try {
        await availabilityService.delete(slot.dbId);
        toast.success("Horário removido com sucesso");
      } catch (error) {
        console.error("Erro ao remover horário:", error);
        toast.error("Erro ao remover horário");
        return;
      }
    }

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

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

      if (!doctorId) {
        toast.error("Médico não autenticado");
        return;
      }

      const requests: Array<Promise<unknown>> = [];

      daysOfWeek.forEach(({ key }) => {
        const daySchedule = schedule[key];

        if (!daySchedule || !daySchedule.enabled) {
          daySchedule?.slots.forEach((slot) => {
            if (slot.dbId) {
              requests.push(availabilityService.delete(slot.dbId));
            }
          });
          return;
        }

        daySchedule.slots.forEach((slot) => {
          const payload: any = {
            weekday: key,
            start_time: slot.inicio,
            end_time: slot.fim,
            slot_minutes: slot.slotMinutes || 30,
            appointment_type: slot.appointmentType || "presencial",
            active: !!slot.ativo,
          };

          if (slot.dbId) {
            requests.push(availabilityService.update(slot.dbId, payload));
          } else {
            requests.push(
              availabilityService.create({
                doctor_id: doctorId,
                ...payload,
              })
            );
          }
        });
      });

      await Promise.all(requests);
      toast.success("Disponibilidade salva com sucesso!");
      loadAvailability();
    } catch (error) {
      console.error("Erro ao salvar disponibilidade:", error);
      toast.error("Erro ao salvar disponibilidade");
    } finally {
      setSaving(false);
    }
  };

  const handleCreateException = async () => {
    if (!doctorId) {
      toast.error("Médico não identificado");
      return;
    }

    try {
      await availabilityService.createException({
        doctor_id: doctorId,
        date: exceptionForm.date,
        kind: exceptionForm.kind,
        start_time: exceptionForm.wholeDayBlock
          ? null
          : exceptionForm.start_time,
        end_time: exceptionForm.wholeDayBlock ? null : exceptionForm.end_time,
        reason: exceptionForm.reason || null,
        created_by: user?.id || doctorId,
      });

      toast.success(
        exceptionForm.kind === "bloqueio"
          ? "Bloqueio criado com sucesso"
          : "Disponibilidade extra adicionada"
      );

      setExceptionForm({
        date: format(new Date(), "yyyy-MM-dd"),
        kind: "bloqueio",
        start_time: "09:00",
        end_time: "18:00",
        wholeDayBlock: true,
        reason: "",
      });

      loadExceptions();
    } catch (error) {
      console.error("Erro ao criar exceção:", error);
      toast.error("Erro ao criar exceção");
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center py-12">
        <div className="text-gray-600 dark:text-gray-400">Carregando...</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">
            Minha Disponibilidade
          </h2>
          <p className="text-gray-600 dark:text-gray-400">
            Gerencie seus horários de atendimento e exceções
          </p>
        </div>
      </div>

      {/* Tabs */}
      <div className="border-b border-gray-200 dark:border-gray-700">
        <nav className="flex gap-4">
          <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"
            }`}
          >
            Exceções ({exceptions.length})
          </button>
        </nav>
      </div>

      {/* Weekly Schedule Tab */}
      {activeTab === "weekly" && (
        <div className="space-y-6">
          <div className="flex justify-end">
            <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>

          <div className="space-y-4">
            {daysOfWeek.map(({ key, label }) => (
              <div
                key={key}
                className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4"
              >
                <div className="flex items-center justify-between mb-4">
                  <div className="flex items-center gap-3">
                    <input
                      type="checkbox"
                      checked={schedule[key]?.enabled || false}
                      onChange={() => toggleDay(key)}
                      className="form-checkbox"
                    />
                    <span className="text-lg font-medium text-gray-900 dark:text-white">
                      {label}
                    </span>
                  </div>
                  {schedule[key]?.enabled && (
                    <button
                      onClick={() => {
                        setSelectedDay(key);
                        setShowAddSlotDialog(true);
                      }}
                      className="flex items-center gap-2 px-3 py-1 text-sm text-indigo-600 hover:bg-indigo-50 dark:hover:bg-indigo-900/20 rounded-lg transition-colors"
                    >
                      <Plus className="h-4 w-4" />
                      Adicionar Horário
                    </button>
                  )}
                </div>

                {schedule[key]?.enabled && (
                  <div className="space-y-2 pl-8">
                    {schedule[key]?.slots.length === 0 ? (
                      <p className="text-gray-500 dark:text-gray-400 text-sm">
                        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"
                        >
                          <div className="flex items-center gap-3">
                            <Clock className="h-4 w-4 text-gray-400" />
                            <span className="text-gray-900 dark:text-white">
                              {slot.inicio} - {slot.fim}
                            </span>
                            <span className="text-sm text-gray-500">
                              ({slot.slotMinutes || 30} min)
                            </span>
                            <span className="text-xs px-2 py-0.5 rounded-full bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400">
                              {slot.appointmentType === "presencial"
                                ? "Presencial"
                                : "Telemedicina"}
                            </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>
      )}

      {/* Exceptions Tab */}
      {activeTab === "blocked" && (
        <div className="space-y-6">
          {/* Create Exception Form */}
          <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">
              Criar Exceção de Agenda
            </h3>
            <div className="space-y-4">
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                    Data
                  </label>
                  <input
                    type="date"
                    value={exceptionForm.date}
                    onChange={(e) =>
                      setExceptionForm({
                        ...exceptionForm,
                        date: e.target.value,
                      })
                    }
                    className="form-input w-full"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                    Tipo
                  </label>
                  <select
                    value={exceptionForm.kind}
                    onChange={(e) =>
                      setExceptionForm({
                        ...exceptionForm,
                        kind: e.target.value as
                          | "bloqueio"
                          | "disponibilidade_extra",
                      })
                    }
                    className="form-input w-full"
                  >
                    <option value="bloqueio">Bloqueio</option>
                    <option value="disponibilidade_extra">
                      Disponibilidade Extra
                    </option>
                  </select>
                </div>
              </div>

              <div className="flex items-center gap-2">
                <input
                  type="checkbox"
                  id="wholeDayBlock"
                  checked={exceptionForm.wholeDayBlock}
                  onChange={(e) =>
                    setExceptionForm({
                      ...exceptionForm,
                      wholeDayBlock: e.target.checked,
                    })
                  }
                  className="form-checkbox"
                />
                <label
                  htmlFor="wholeDayBlock"
                  className="text-sm text-gray-900 dark:text-white"
                >
                  Dia inteiro
                </label>
              </div>

              {!exceptionForm.wholeDayBlock && (
                <div className="grid grid-cols-2 gap-4">
                  <div>
                    <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                      Horário Início
                    </label>
                    <input
                      type="time"
                      value={exceptionForm.start_time}
                      onChange={(e) =>
                        setExceptionForm({
                          ...exceptionForm,
                          start_time: e.target.value,
                        })
                      }
                      className="form-input w-full"
                    />
                  </div>
                  <div>
                    <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                      Horário Fim
                    </label>
                    <input
                      type="time"
                      value={exceptionForm.end_time}
                      onChange={(e) =>
                        setExceptionForm({
                          ...exceptionForm,
                          end_time: e.target.value,
                        })
                      }
                      className="form-input w-full"
                    />
                  </div>
                </div>
              )}

              <div>
                <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                  Motivo (opcional)
                </label>
                <textarea
                  value={exceptionForm.reason}
                  onChange={(e) =>
                    setExceptionForm({
                      ...exceptionForm,
                      reason: e.target.value,
                    })
                  }
                  placeholder="Ex: Férias, Feriado, Plantão extra..."
                  className="form-input w-full"
                  rows={2}
                />
              </div>

              <button
                onClick={handleCreateException}
                className="w-full py-2 px-4 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg transition-colors"
              >
                Criar Exceção
              </button>
            </div>
          </div>

          {/* List Exceptions */}
          <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">
              Exceções Cadastradas
            </h3>
            {exceptions.length === 0 ? (
              <p className="text-gray-500 dark:text-gray-400 text-center py-8">
                Nenhuma exceção cadastrada
              </p>
            ) : (
              <div className="space-y-2">
                {exceptions.map((exception) => (
                  <div
                    key={exception.id}
                    className="flex items-center justify-between p-4 rounded-lg border border-gray-200 dark:border-gray-700"
                  >
                    <div className="flex-1">
                      <div className="flex items-center gap-2 mb-1">
                        <span
                          className={`px-2 py-0.5 text-xs rounded-full font-medium ${
                            exception.kind === "bloqueio"
                              ? "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400"
                              : "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400"
                          }`}
                        >
                          {exception.kind === "bloqueio"
                            ? "Bloqueio"
                            : "Disponibilidade Extra"}
                        </span>
                        <span className="text-sm font-medium text-gray-900 dark:text-white">
                          {format(new Date(exception.date!), "dd/MM/yyyy")}
                        </span>
                      </div>
                      <div className="text-sm text-gray-600 dark:text-gray-400">
                        {exception.start_time && exception.end_time
                          ? `${exception.start_time} - ${exception.end_time}`
                          : "Dia inteiro"}
                        {exception.reason && (
                          <span className="ml-2">• {exception.reason}</span>
                        )}
                      </div>
                    </div>
                    <button
                      onClick={async () => {
                        if (!exception.id) return;
                        try {
                          await availabilityService.deleteException(
                            exception.id
                          );
                          toast.success("Exceção removida");
                          loadExceptions();
                        } catch (error) {
                          console.error("Erro ao remover exceção:", error);
                          toast.error("Erro ao remover exceção");
                        }
                      }}
                      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>
      )}

      {/* 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>
            <div className="space-y-4">
              <div className="grid grid-cols-2 gap-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="form-input w-full"
                  />
                </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="form-input w-full"
                  />
                </div>
              </div>

              <div>
                <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                  Duração da Consulta (minutos)
                </label>
                <select
                  value={newSlot.slotMinutes}
                  onChange={(e) =>
                    setNewSlot({
                      ...newSlot,
                      slotMinutes: parseInt(e.target.value),
                    })
                  }
                  className="form-input w-full"
                >
                  <option value={15}>15 minutos</option>
                  <option value={30}>30 minutos</option>
                  <option value={45}>45 minutos</option>
                  <option value={60}>60 minutos</option>
                </select>
              </div>

              <div>
                <label className="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                  Tipo de Atendimento
                </label>
                <select
                  value={newSlot.appointmentType}
                  onChange={(e) =>
                    setNewSlot({
                      ...newSlot,
                      appointmentType: e.target.value as
                        | "presencial"
                        | "telemedicina",
                    })
                  }
                  className="form-input w-full"
                >
                  <option value="presencial">Presencial</option>
                  <option value="telemedicina">Telemedicina</option>
                </select>
              </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;
