import DialogAlert from "@/components/Alerts/dialogAlert";
import Button from "@/components/Forms/Button";
import Container from "@/components/Forms/Container";
import ModalComponente from "@/components/Modal/ModalComponente";
import LoaderSun from "@/components/common/Loader/LoaderSun";
import {
  Drawer,
  DrawerContent,
  DrawerDescription,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@/components/ui/drawer";
import {
  apagarTarefa,
  cadastrarTarefa,
  editarDemanda,
  listarDemandas,
  listarUsuario,
} from "@/requests/CRM/agenda";

import { TipoTarefa } from "@/enums/enums";
import { useAuth } from "@/src/contexts/authContext";
import { useSocketContext } from "@/src/contexts/SocketContext";
import { GetForm } from "@/utils";
import brLocale from "@fullcalendar/core/locales/pt-br";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";
import FullCalendar from "@fullcalendar/react";
import timeGridPlugin from "@fullcalendar/timegrid";
import { ChevronLeft, ChevronRight, PlusCircle } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import Swal from "sweetalert2";
import tippy from "tippy.js";
import "tippy.js/dist/tippy.css";
import * as yup from "yup";
import InputGroup from "../../components/Forms/InputGroup";
import InputSelectComponent from "../../components/Forms/InputSelect";
import EditDateScheduler from "./modalEditDateScheduler";
import NewDateScheduler from "./modalNewDateScheduler";

const Calendar = ({ onSubmitFunction }: any) => {
  const [openModal, setOpenModal] = useState(false);
  const [openModalAlert, setOpenModalAlert] = useState(false);
  const [isLoading, setIsLoading] = useState(false);

  const [valuesForm, setValues] = useState({
    urgencia: "",
    id_cliente: "",
    tipoAtv: "",
  });
  const calendarRef = useRef<any>();
  const [tarefas, setTarefas] = useState<any[]>([]);
  const [selectedDateTime, setSelectedDateTime] = useState(null);
  const { valuesSession, perfil } = useAuth();
  const { notificarNotificacao } = useSocketContext();
  const { session } = valuesSession();
  const id_usuario = session.id_usuario;

  const [usuario, setUsuario] = useState<any[]>([]);
  const [usuarioSelecionado, setUsuarioSelecionado] = useState<any>(id_usuario);
  const [eventosDiaMobile, setEventosDiaMobile] = useState<any[]>([]);
  const [modalType, setModalType] = useState("");
  const [tipoTarefaSelected, setTipoTarefaSelected] = useState("");
  const [title, setTitle] = useState("");
  const [selectedTaskData, setSelectedTaskData] = useState<any>(null);
  const [view, setView] = useState("dayGridMonth");
  const [yupSchema, setYupSchema] = useState<
    yup.ObjectSchema<{}, yup.AnyObject, {}, "">
  >(yup.object().shape({}));
  const { handleSubmit, ...form } = GetForm(yupSchema, setYupSchema);
  const [mobileView, setMobileView] = useState(false);
  const [valueView, setValueView] = useState(1);
  const [eventSchema, setEventSchema] = useState<
    yup.ObjectSchema<{}, yup.AnyObject, {}, "">
  >(yup.object().shape({}));
  const { ...formEvent } = GetForm(eventSchema, setEventSchema);

  useEffect(() => {
    let timer: any;

    if (isLoading) {
      timer = setTimeout(() => {
        setIsLoading(false);
      }, 4000);
    }

    return () => {
      clearTimeout(timer);
    };
  }, [isLoading]);

  useEffect(() => {
    listarUsuario().then((e: any) => {
      setUsuario(e);
    });
    getEvents();
  }, []);

  useEffect(() => {
    formEvent.setValue("datafim" as never, "" as never);
    formEvent.setValue("horafim" as never, "" as never);
    if (!openModal) {
      formEvent.reset();
    }
  }, [openModal]);

  const getEvents = async () => {
    setIsLoading(true);
    // const dataFiltro = [
    //   {
    //     selectedUser: usuarioSelecionado,
    //     idUsuario: id_usuario,
    //     tipoTarefa: tipoTarefaSelected,
    //   },
    // ];
    const res = await listarDemandas(
      usuarioSelecionado || id_usuario,
      tipoTarefaSelected,
    );
    setIsLoading(false);
    const eventosFormatados = res.map((evento: any) => {
      const dataAtual = new Date();
      const dataHoraTarefa: any =
        evento.dt_inicio_agendamento + " " + evento.hora_inicio_agendamento;
      const dataTarefa = new Date(dataHoraTarefa);
      let color = "";
      if (dataAtual > dataTarefa) {
        color = "red";
      } else {
        color = "blue";
      }
      return {
        title: [evento.nome_cliente].join("\n") || "Evento Pessoal",
        start:
          evento.dt_inicio_agendamento +
          (evento.hora_inicio_agendamento
            ? "T" + evento.hora_inicio_agendamento
            : ""),
        end: evento.dt_fim_agendamento,
        data: evento,
        backgroundColor: color,
        onclick: handleclickTask,
      };
    });
    setTarefas(eventosFormatados);
  };

  const handleclickTask = (data: any) => {
    data = { ...data, id_usuario };
  };
  const openDynamicallyDrawer = () => {
    const triggerElement = document.querySelector(
      ".triggerCalendarDrawer",
    ) as HTMLButtonElement | null;
    if (triggerElement) {
      triggerElement.click();
    }
  };

  const handleDataClick = (info: any) => {
    if (mobileView) {
      const events = handleDateClick(info);

      openDynamicallyDrawer();
      if (events.length > 0) {
        setEventosDiaMobile(events);
      } else {
        setEventosDiaMobile([]);
      }
    } else {
      if (info.event) {
        setModalType("Editar Tarefa");
        setSelectedTaskData(info.event.extendedProps.data);
      } else {
        Object.keys(valuesForm).map((values: any) => {
          formEvent.setValue(values as never, "" as never);
        });
        setModalType("Nova Tarefa");
      }
      setOpenModal(true);
    }

    setSelectedDateTime(info.date || info.event.start);
  };
  const handleDateClick = (info: any) => {
    const calendarApi = calendarRef.current.getApi();
    const events = calendarApi.getEvents();
    const clickedDateEvents = events.filter((event: any) => {
      return event.start.toISOString().slice(0, 10) === info.dateStr;
    });
    return clickedDateEvents;
  };

  const handleCadastrar = (data: any) => {
    if (
      (data["dt_fim_agendamento"] && !data["hora_fim_agendamento"]) ||
      (!data["dt_fim_agendamento"] && data["hora_fim_agendamento"])
    ) {
      return Swal.fire(
        "Ação não Permitida!",
        `Por favor, preencha ambos os campos de <br>Data Fim e Hora Fim.`,
        "warning",
      );
    }
    let cont = 0;
    let msg = "";

    if (!data["tipo_agendamento"]) {
      msg += "<br>Tipo Agendamento";
      cont++;
    }
    if (!data["urgencia_agendamento"]) {
      msg += "<br>Urgência";
      cont++;
    }

    if (data["tipo_agendamento"] == TipoTarefa.Cliente) {
      if (!data["cod_cliente"]) {
        msg += "<br>Código Cliente";
        cont++;
      }
      if (!data["nome_negocio"]) {
        msg += "<br>Negócio";
        cont++;
      }
      if (!data["visita_cliente_agendamento"]) {
        msg += "<br>Visita ao Cliente";
        cont++;
      }
    }

    if (!data["dt_inicio_agendamento"]) {
      msg += "<br>Data Início";
      cont++;
    }
    if (!data["hora_inicio_agendamento"]) {
      msg += "<br>Hora Início";
      cont++;
    }
    if (!data["descricao_agendamento"]) {
      msg += "<br>Descrição";
      cont++;
    }
    if (msg) {
      return Swal.fire(
        "Ação não Permitida!",
        `Por favor, preencha ${cont > 1 ? "os" : "o"} campo${cont > 1 ? "s" : ""} ${cont > 1 ? "listados " : ""}abaixo.${msg}`,
        "warning",
      );
    }

    const dados = {
      ...data,
      cod_usuario: id_usuario,
    };
    // cadastrarDemanda(dados).then((res: any) => {
    //   setValues({
    //     urgencia: "",
    //     id_cliente: "",
    //     tipoAtv: "",
    //   });

    //   setOpenModal(false);
    //   getEvents();
    // });
    cadastrarTarefa(dados).then((res: any) => {
      setValues({
        urgencia: "",
        id_cliente: "",
        tipoAtv: "",
      });

      setOpenModal(false);
      getEvents();
      notificarNotificacao();
    });
  };

  const handleEditar = (data: any) => {
    if (
      (data["dt_fim_agendamento"] && !data["hora_fim_agendamento"]) ||
      (!data["dt_fim_agendamento"] && data["hora_fim_agendamento"])
    ) {
      return Swal.fire(
        "Ação não Permitida!",
        `Por favor, preencha ambos os campos de <br>Data Fim e Hora Fim.`,
        "warning",
      );
    }
    let cont = 0;
    let msg = "";

    if (!data["tipo_agendamento"]) {
      msg += "<br>Tipo A";
      cont++;
    }
    if (!data["urgencia_agendamento"]) {
      msg += "<br>Urgência";
      cont++;
    }

    if (data["tipo_agendamento"] == TipoTarefa.Cliente) {
      if (!data["cod_cliente"]) {
        msg += "<br>Código Cliente";
        cont++;
      }
      if (!data["nome_negocio"]) {
        msg += "<br>Negócio";
        cont++;
      }
      if (!data["visita_cliente_agendamento"]) {
        msg += "<br>Visita ao Cliente";
        cont++;
      }
    }

    if (!data["dt_inicio_agendamento"]) {
      msg += "<br>Data Início";
      cont++;
    }
    if (!data["hora_inicio_agendamento"]) {
      msg += "<br>Hora Início";
      cont++;
    }
    if (!data["descricao_agendamento"]) {
      msg += "<br>Descrição";
      cont++;
    }
    if (msg) {
      return Swal.fire(
        "Ação não Permitida!",
        `Por favor, preencha ${cont > 1 ? "os" : "o"} campo${cont > 1 ? "s" : ""} ${cont > 1 ? "listados " : ""}abaixo.${msg}`,
        "warning",
      );
    }

    const dados = {
      ...data,
      cod_usuario: id_usuario,
      id_agendamento: selectedTaskData.id_agendamento,
    };
    editarDemanda(dados).then((res: any) => {
      setOpenModal(true);
      setOpenModal(false);
      getEvents();
    });
  };

  const handleApagar = (data: any) => {
    const dados = {
      id_agendamento: selectedTaskData.id_agendamento,
    };
    apagarTarefa(dados).then((res: any) => {
      setOpenModalAlert(true);
      setOpenModalAlert(false);
      setOpenModal(false);
      getEvents();
    });
  };

  useEffect(() => {
    const updateMenuView = () => {
      const windowSize = window.innerWidth;
      setMobileView(windowSize < 640);
    };
    updateMenuView();

    window.addEventListener("resize", updateMenuView);

    return () => {
      window.removeEventListener("resize", updateMenuView);
    };
  }, []);

  const handleChangeViewDate = (e: any) => {
    let defineView = "";
    if (e == 1) {
      defineView = "dayGridMonth";
    } else if (e == 2) {
      defineView = "timeGridWeek";
    } else if (e == 3) {
      defineView = "timeGridDay";
    }
    setView(defineView);
    setValueView(e);
  };
  // fc-scrollgrid  fc-scrollgrid-liquid

  // Define custom button functions outside handleSelect
  const nextHandle = () => {
    const api = calendarRef.current.getApi();

    api.next();
    setTitle(api.currentData.viewTitle);
  };

  const prevHandle = () => {
    const api = calendarRef.current.getApi();
    api.prev();
    setTitle(api.currentData.viewTitle);
  };

  const getWeekdayShort = (date: Date, locale: Locale): string => {
    const weekdaysShort = ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"];
    const weekdayIndex = date.getDay();
    return weekdaysShort[weekdayIndex];
  };
  const tiposTarefa = [
    {
      value: 0,
      label: "Todos",
    },
    {
      value: 1,
      label: "Com Cliente",
    },
    {
      value: 2,
      label: "Pessoal",
    },
  ];

  const Calendar = (
    <FullCalendar
      ref={calendarRef}
      events={tarefas}
      locale={brLocale}
      eventTimeFormat={{
        hour: "numeric",
        minute: "2-digit",
        meridiem: false,
      }}
      // dayHeaderContent={(args) => {
      //   if (view === "timeGridWeek") {
      //     const formattedDate = format(args.date, "d", {
      //       locale: ptBR,
      //     });
      //     const result = isToday(args.date);
      //     const weekdayShort = getWeekdayShort(args.date, ptBR);

      //     return (
      //       <>
      //         <span>{weekdayShort}.</span>{" "}
      //         <span className={`${result ? "isTodayBaby " : ""} py-2 my-1`}>
      //           {formattedDate}
      //         </span>
      //       </>
      //     );
      //   } else if (view === "dayGridMonth") {
      //     const weekdayShort = getWeekdayShort(args.date, ptBR);
      //     return <span>{weekdayShort}.</span>;
      //   }
      // }}
      plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
      initialView={view}
      headerToolbar={{
        start: "dayGridMonth,timeGridWeek,timeGridDay",
        // start: "mes,semana,dia",
        center: "title",
        end: "today prev,next",
      }}
      // customButtons={{
      //   mes: {
      //     text: "Mês",
      //     click: function () {
      //       handleChangeViewDate(1);
      //     },
      //   },
      //   semana: {
      //     text: "Semana",
      //     click: function () {
      //       handleChangeViewDate(2);
      //     },
      //   },
      //   dia: {
      //     text: "Dia",
      //     click: function () {
      //       handleChangeViewDate(3);
      //     },
      //   },
      // }}
      eventBackgroundColor="blue"
      // buttonText={
      //   {
      //     // today: "Hoje",
      //     //   month: "PAU",
      //     //   week: "PIM",
      //     // day: "POW",
      //   }
      // }
      height={"70vh"}
      dateClick={handleDataClick}
      eventClick={handleDataClick}
      dayMaxEvents={3}
      moreLinkClick="popover"
      dayPopoverFormat={{
        month: "long",
        day: "numeric",
        weekday: "long",
      }}
      selectLongPressDelay={1}
      viewDidMount={(info: any) => {
        setTitle(info.view.title);
      }}
      eventDidMount={(info: any) => {
        const evento = info.event.extendedProps.data;
        if (mobileView) {
          const eventos = document.querySelectorAll("[data-date]");

          const eventoBD = tarefas.filter(
            (agenda: any) =>
              agenda.data.dt_inicio_agendamento == evento.dt_inicio_agendamento,
          );

          eventos.forEach((elemento: any) => {
            if (elemento.dataset.date == evento.dt_inicio_agendamento) {
              const divEvento = elemento.querySelector(
                ".fc-daygrid-event-harness",
              );

              if (divEvento) {
                divEvento.innerHTML = "";
                const eventEvt = `
                   <div class="limp eventEvt text-[10px] rounded-full  h-4 w-4 justify-center flex items-center font-semibold text-black-2 bg-[#ff2d2d]" >
                   ${eventoBD.length}
                   </div>
                 `;
                divEvento.innerHTML = eventEvt;
              }
            }
          });
        }
        const { nome_usuario, descricao_agendamento } = evento;
        const tooltipContent = `
          <div style="text-align: left; width: 300px;"> 
            <strong>Responsável:</strong> ${nome_usuario} <br>
            <strong>Descrição:</strong> ${descricao_agendamento}
          </div>
        `;

        tippy(info.el, {
          content: tooltipContent,
          placement: "top",
          interactive: true,
          trigger: "mouseenter",
          allowHTML: true,
        });
      }}
    />
  );
  return (
    <>
      <form onSubmit={handleSubmit(onSubmitFunction)} className="max-sm:hidden">
        <InputGroup className=" items-end">
          {perfil?.visualiza_todas_agendas_perfil == "1" && (
            <InputSelectComponent
              name="usuarios_agendamento"
              width="xl:w-1/1"
              formulario={form}
              label="Usuario"
              options={[
                { value: "todos", label: "Todos" },
                ...Object.values(usuario).map((res: any) => ({
                  value: res.id_usuario,
                  label: res.nome_usuario,
                })),
              ]}
              isMulti={true}
              onChange={(selectedOptions: any) => {
                const usuarioSelecionado = selectedOptions
                  .map((option: any) => option.value)
                  .join(", ");
                setUsuarioSelecionado(usuarioSelecionado);
                if (selectedOptions.some((e: any) => e.value == "*")) {
                  if (selectedOptions.some((e: any) => e.value == "*")) {
                    form.setValue(
                      "usuarios_agendamento" as never,
                      [{ label: "Todos", value: "todos" }] as never,
                    );
                  }
                }
              }}
            />
          )}
          <InputSelectComponent
            name="tipo_agendamento"
            width="xl:w-1/6"
            formulario={form}
            label="Tipo Agendamento"
            options={tiposTarefa}
            onChange={(e: any) => {
              setTipoTarefaSelected(e.value);
            }}
          />

          <div className="w-full xl:w-1/6">
            <Button
              style={{ marginBlockEnd: "auto" }}
              type="button"
              className="w-full  h-10 rounded bg-success text-sm px-3 font-medium text-gray mb-4"
              onClick={getEvents}
              loading={isLoading}
            >
              Filtrar
            </Button>
          </div>
          <div className="">
            <Button
              style={{ marginBlockEnd: "auto" }}
              type="button"
              className="w-full  h-10 rounded bg-primary text-sm px-3 font-medium text-gray mb-4"
              onClick={() => {
                setModalType("Nova Tarefa");
                setOpenModal(true);
              }}
            >
              Adicionar{" "}
              <span className="pl-2">
                <PlusCircle size={19} />
              </span>
            </Button>
          </div>
        </InputGroup>
      </form>

      {isLoading && (
        <div className="flex  h-fit items-center justify-center bg-transparent">
          <LoaderSun />
        </div>
      )}
      {!isLoading && (
        <div className="flex flex-col">
          {/* <div className="flex md:hidden w-full items-center justify-between">
            <div></div>
            <Combobox
              handleChange={handleChangeViewDate}
              className="w-26"
              defaultValue="1"
              options={[
                { value: "1", label: "Mês" },
                { value: "2", label: "Semana" },
                { value: "3", label: "Dia" },
              ]}
            />
          </div> */}
          <div
            className="testetDeinl pt-4 justify-between flex
      md:hidden"
          >
            <button
              className="btn p-1 bg-black rounded-md"
              onClick={prevHandle}
            >
              <ChevronLeft />
            </button>
            <span className="dark:text-white first-letter:capitalize">
              {title}
            </span>
            {/* <button className="btn" onClick={() => todayHandle()}>
              Today
            </button> */}
            <button
              className="btn p-1 bg-black rounded-md"
              onClick={nextHandle}
            >
              <ChevronRight />
            </button>
          </div>
        </div>
      )}

      {!isLoading &&
        (!mobileView ? (
          <Container>
            <div className="z-0 relative ">{Calendar}</div>
          </Container>
        ) : (
          <div
            id={`${view}`}
            className={`z-0 relative testeDeclasss h-[200px] ${view}`}
          >
            {Calendar}
          </div>
        ))}
      {modalType === "Nova Tarefa" && openModal && (
        <ModalComponente
          saved={formEvent.handleSubmit(handleCadastrar)}
          opened={openModal}
          onClose={() => setOpenModal(!openModal)}
          header="Novo Agendamento"
        >
          <NewDateScheduler
            selectedDateTime={selectedDateTime}
            form={formEvent}
          />
        </ModalComponente>
      )}

      <Drawer>
        <DrawerTrigger className="triggerCalendarDrawer hidden"></DrawerTrigger>
        <DrawerContent className="dark:bg-form-input">
          {eventosDiaMobile.length > 0 ? (
            <DrawerHeader>
              <DrawerTitle className="dark:text-white">Eventos: </DrawerTitle>
              {eventosDiaMobile.map((evento: any, index: number) => {
                const eventData = evento.extendedProps.data;
                return (
                  <div
                    key={index}
                    onClick={() => {
                      setModalType("Editar Tarefa");
                      setSelectedTaskData(eventData);
                      openDynamicallyDrawer();
                      setOpenModal(true);
                    }}
                    className="w-full bg-strokedark rounded-lg text-start items-center justify-between px-5 p-2 flex dark:text-white"
                  >
                    <div className="flex-col flex">
                      <span>{eventData.descricao_agendamento}</span>
                      <span className="text-sm text-stroke">
                        {eventData.nome_cliente} -{" "}
                        {eventData.nome_negocio_coleta}
                      </span>
                    </div>
                    <span className="h-3 w-3 rounded-full bg-danger"></span>
                  </div>
                );
              })}

              <Button
                onClick={() => {
                  Object.keys(valuesForm).map((values: any) => {
                    formEvent.setValue(values as never, "" as never);
                  });
                  setModalType("Nova Tarefa");
                  openDynamicallyDrawer();
                  setOpenModal(true);
                }}
                className=" bg-[#34a6d6] justify-self-center gap-2 px-9"
              >
                <PlusCircle size={19} />
                Adicionar
              </Button>
            </DrawerHeader>
          ) : (
            <DrawerHeader>
              <DrawerTitle className="dark:text-white">
                Sem eventos{" "}
              </DrawerTitle>
              <DrawerDescription>Gostaria de adicionar?</DrawerDescription>
              <Button
                onClick={() => {
                  Object.keys(valuesForm).map((values: any) => {
                    formEvent.setValue(values as never, "" as never);
                  });
                  setModalType("Nova Tarefa");
                  openDynamicallyDrawer();
                  setOpenModal(true);
                }}
                className=" bg-[#34a6d6] justify-self-center gap-2 px-9"
              >
                <PlusCircle size={19} />
                Adicionar
              </Button>
            </DrawerHeader>
          )}
        </DrawerContent>
      </Drawer>

      {modalType === "Editar Tarefa" && (
        <ModalComponente
          opened={openModal}
          saved={formEvent.handleSubmit(handleEditar)}
          hasDenyButton={true}
          denyButtonText="Deletar"
          onDeny={() => setOpenModalAlert(!openModalAlert)}
          onClose={() => setOpenModal(!openModal)}
          header="Editar Tarefa"
        >
          <DialogAlert
            title="Deseja excluir essa Tarefa?"
            tipo="warning"
            open={openModalAlert}
            onSave={formEvent.handleSubmit(handleApagar)}
            onClose={() => setOpenModalAlert(!openModalAlert)}
          />
          <EditDateScheduler
            selectedDateTime={selectedDateTime}
            form={formEvent}
            taskData={selectedTaskData}
          />
        </ModalComponente>
      )}
    </>
  );
};

export default Calendar;
