"use client";
import React, { useState, useEffect } from "react";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin, { Draggable } from "@fullcalendar/interaction";
import listPlugin from "@fullcalendar/list";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Calendar } from "@/components/ui/calendar";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Book, CheckCheck, Plus, Timer } from "lucide-react";
import { Checkbox } from "@/components/ui/checkbox";
import { EventContentArg } from "@fullcalendar/core";
import EventModal from "./event-modal";
import { useTranslations } from "next-intl";
import dayjs from "dayjs";
import { getCookiesDecrypt } from "@/lib/utils";
import { CalendarCategory } from "./data";
import { error } from "@/config/swal";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { getAgendaSettingsList } from "@/service/agenda-settings/agenda-setting";

const wait = () => new Promise((resolve) => setTimeout(resolve, 1000));

interface CalendarViewProps {
  categories: CalendarCategory[];
}

export type CalendarEvent = {
  id: string;
  title: string;
  start: Date;
  end: Date;
  createBy: string;
  createdByName: string;
  isPublish: boolean | null;
  allDay: boolean;
  extendedProps: {
    calendar: string;
    description: string;
    isPublish?: boolean;
    createdByName?: string;
  };
};

export interface AgendaSettingsAPIResponse {
  id: number;
  title: string;
  createdByName: string;
  description: string;
  agendaType: string;
  startDate: string;
  endDate: string;
  isActive: boolean;
  isPublish: boolean;
  createdAt: string;
  updatedAt: string;
  createdById: number | null;
}

interface YearlyData {
  january?: AgendaSettingsAPIResponse[];
  february?: AgendaSettingsAPIResponse[];
  march?: AgendaSettingsAPIResponse[];
  april?: AgendaSettingsAPIResponse[];
  may?: AgendaSettingsAPIResponse[];
  june?: AgendaSettingsAPIResponse[];
  july?: AgendaSettingsAPIResponse[];
  august?: AgendaSettingsAPIResponse[];
  september?: AgendaSettingsAPIResponse[];
  october?: AgendaSettingsAPIResponse[];
  november?: AgendaSettingsAPIResponse[];
  december?: AgendaSettingsAPIResponse[];
}

interface MonthCardProps {
  monthId: keyof YearlyData;
  label: string;
}

interface ListItemProps {
  item: AgendaSettingsAPIResponse;
  text: string;
  createdBy: string;
  isPublish: boolean | null;
  bgColor: string;
  colorList: string[] | null;
}

interface APIResponse {
  success: boolean;
  message: string;
  data: YearlyData | null;
  errorCode: string | null;
}

type EventType = "0" | "1" | "2" | "3" | "4" | "5";

const INITIAL_YEAR = dayjs().format("YYYY");
const INITIAL_MONTH = dayjs().format("M");

const CalendarView = ({ categories }: CalendarViewProps) => {
  const [selectedCategory, setSelectedCategory] = useState<string[]>([]);
  const [selectedEventDate, setSelectedEventDate] = useState<Date | null>(null);
  const roleId = Number(getCookiesDecrypt("urie")) || 0;
  const levelNumber = Number(getCookiesDecrypt("ulne")) || 0;
  const userLevelId = Number(getCookiesDecrypt("ulie")) || 0;
  const [calendarEvents, setCalendarEvents] = useState<CalendarEvent[]>([]);
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const t = useTranslations("CalendarApp");
  const [sheetOpen, setSheetOpen] = useState<boolean>(false);
  const [date, setDate] = useState<Date>(new Date());
  const [activeView, setActiveView] = useState("listYear");
  const [yearlyData, setYearlyData] = useState<YearlyData>({});
  const [open, setOpen] = useState(false);
  const [selectedEventData, setSelectedEventData] = useState<any>(null);

  const [selectedMonth, setSelectedMonth] = useState(
    dayjs(new Date(Number(INITIAL_YEAR), Number(INITIAL_MONTH) - 1, 1))
  );

  useEffect(() => {
    if (activeView === "listYear") {
      getYearlyEvents();
    } else {
      getCalendarEvents();
    }
  }, [activeView, selectedMonth]);

  useEffect(() => {
    if (categories?.length > 0) {
      setSelectedCategory(categories.map((c) => c.value));
    }
  }, [categories]);

  const getCalendarEvents = async () => {
    setIsLoading(true);
    try {
      const res = await getAgendaSettingsList(
        selectedMonth?.format("YYYY") || INITIAL_YEAR,
        selectedMonth.format("M") || INITIAL_MONTH,
        ""
      );

      if (res?.error) {
        error(res?.message || "Failed to fetch events");
        return;
      }

      const monthData = res?.data?.data;
      if (monthData) {
        const allEvents: CalendarEvent[] = [];
        const events = monthData?.map((event: any) => ({
          id: event.id.toString(),
          title: event.title,
          createBy: event.createdById,
          createdByName: event.createdByName,
          start: new Date(event.startDate),
          end: new Date(event.endDate),
          allDay: true,
          extendedProps: {
            isPublish: event.isPublish,
            calendar: event.agendaType,
            description: event.description,
            createdByName: event.createdByName,
          },
        }));

        console.log("Event Data : ", events);
        setCalendarEvents(events);
      }
    } catch (err) {
      console.error("Failed to fetch calendar events:", err);
      error("Failed to fetch calendar events");
    } finally {
      setIsLoading(false);
    }
  };

  const getYearlyEvents = async () => {
    setIsLoading(true);
    try {
      const res = await getAgendaSettingsList(
        selectedMonth?.format("YYYY") || INITIAL_YEAR,
        "",
        ""
      );

      if (res?.error) {
        error(res?.message || "Failed to fetch yearly events");
        return;
      }

      const yearlyData = res?.data?.data;
      if (yearlyData) {
        setYearlyData(yearlyData);
      }
    } catch (err) {
      console.error("Failed to fetch yearly events:", err);
      error("Failed to fetch yearly events");
    } finally {
      setIsLoading(false);
    }
  };

  const filteredEvents = calendarEvents.filter((event) => {
    if (!selectedCategory.length) return false;
    console.log("Event category : ", selectedCategory);

    const eventCategories = event.extendedProps.calendar
      ?.split(",")
      .map((val: string) => val.trim());

    const allCategoryId = ["1", "2", "3", "4", "5"];
    const hasAllCategories = allCategoryId.every((categoryId) =>
      selectedCategory.includes(categoryId)
    );

    return eventCategories?.some(
      (cat: string) =>
        selectedCategory.includes(cat) || (hasAllCategories && cat == "0")
    );
  });

  const handleEventClick = (arg: any) => {
    setSelectedEventDate(null);
    setSelectedEventData(arg);
    setSheetOpen(true);
    wait().then(() => (document.body.style.pointerEvents = "auto"));
  };

  const handleCloseModal = () => {
    setSheetOpen(false);
    setSelectedEventData(null);
    setSelectedEventDate(null);
  };

  const handleDateClick = (arg: any) => {
    setSheetOpen(true);
    setSelectedEventDate(arg);
    setSelectedEventData(null);
    wait().then(() => (document.body.style.pointerEvents = "auto"));
  };

  const handleCategorySelection = (category: string) => {
    setSelectedCategory((prev) => {
      if (prev.includes(category)) {
        return prev.filter((c) => c !== category);
      } else {
        return [...prev, category];
      }
    });
  };

  const handleDateChange = (startDate: string, endDate: string) => {
    const startDateOfDate = new Date(startDate);
    setSelectedMonth(dayjs(startDateOfDate));
  };

  const handleViewChange = (viewType: string) => {
    setActiveView(viewType);
  };

  const handleClickListItem = (item: AgendaSettingsAPIResponse) => {
    const formattedEvent: CalendarEvent = {
      id: item.id.toString(),
      title: item.title,
      start: new Date(item.startDate),
      end: new Date(item.endDate),
      createBy: item.createdById?.toString() || "",
      createdByName: item.createdByName,
      isPublish: item.isPublish,
      allDay: true,
      extendedProps: {
        calendar: item.agendaType,
        description: item.description,
        isPublish: item.isPublish,
        createdByName: item.createdByName,
      },
    };

    const eventArg = { event: formattedEvent };
    setSelectedEventDate(null);
    setSelectedEventData(eventArg);
    setSheetOpen(true);
    wait().then(() => (document.body.style.pointerEvents = "auto"));
  };

  const getEventColor = (type: EventType): string => {
    const typeSplit = type.split(",");
    const firstType = typeSplit[0] as EventType;

    const colors: Record<EventType, string> = {
      "0": "bg-gray-500",
      "1": "bg-yellow-500",
      "2": "bg-blue-400",
      "3": "bg-slate-400",
      "4": "bg-orange-500",
      "5": "bg-green-400",
    };

    return colors[firstType] || "bg-gray-400";
  };

  const getEventColorList = (type: EventType): string[] | null => {
    const typeSplit = type.split(",");
    const typeList = typeSplit.slice(1);

    if (typeList.length === 0) return null;

    const colors: Record<EventType, string> = {
      "0": "bg-black",
      "1": "bg-yellow-500",
      "2": "bg-blue-400",
      "3": "bg-slate-400",
      "4": "bg-orange-500",
      "5": "bg-green-400",
    };

    return typeList.map((item) => colors[item as EventType] || "bg-gray-200");
  };

  const renderEventContent = (eventInfo: any) => {
    const { title } = eventInfo.event;
    const { createdByName, isPublish, calendar } =
      eventInfo.event.extendedProps;
    const bgColor = getEventColor(calendar);
    const colorList = getEventColorList(calendar);

    return (
      <div
        className={`w-full p-2 mb-2 rounded-md text-white text-sm flex justify-between items-stretch ${bgColor}`}
      >
        <div className="flex-1">
          <div className="flex flex-row items-center">
            {isPublish === true ? (
              <CheckCheck size={15} />
            ) : (
              <Timer size={15} />
            )}
            <p className="ml-1">{title}</p>
          </div>
          <p className="ml-1 text-xs text-start mt-2">
            Created By: {createdByName}
          </p>
        </div>
        {colorList && colorList.length > 0 && (
          <div className="w-3 flex flex-col h-full ml-2 overflow-hidden item-stretch gap-1">
            {colorList.map((color: string, index: number) => (
              <div key={index} className={`h-[10px] rounded-sm ${color}`}></div>
            ))}
          </div>
        )}
      </div>
    );
  };

  const handleClassName = (arg: EventContentArg) => {
    const eventColor = getEventColor(arg.event.extendedProps.calendar);
    return eventColor || "primary";
  };

  // Components
  const ListItem: React.FC<ListItemProps> = ({
    item,
    text,
    createdBy,
    isPublish,
    bgColor,
    colorList,
  }) => (
    <div
      className={`w-full p-2 mb-2 rounded-md text-white text-sm flex justify-between items-stretch cursor-pointer hover:opacity-80 ${bgColor}`}
      onClick={() => handleClickListItem(item)}
    >
      <div className="flex-1">
        <div className="flex flex-row items-center">
          {isPublish ? <CheckCheck size={15} /> : <Timer size={15} />}
          <p className="ml-1">{text}</p>
        </div>
        <p className="ml-1 text-xs text-start mt-2">Created By: {createdBy}</p>
      </div>
      {colorList && colorList.length > 0 && (
        <div className="w-3 flex flex-col h-full ml-2 overflow-hidden item-stretch gap-1">
          {colorList.map((color: string, index: number) => (
            <div key={index} className={`h-[10px] rounded-sm ${color}`}></div>
          ))}
        </div>
      )}
    </div>
  );

  const MonthCard: React.FC<MonthCardProps> = ({ monthId, label }) => {
    const events = yearlyData[monthId] || [];
    const displayedEvents = events.slice(0, 3);
    const hasMoreEvents = events.length > 3;

    return (
      <div className="flex-1 bg-white dark:bg-black rounded-lg shadow-sm border border-gray-200 pb-3 mr-1">
        <div className="py-3">
          <h4 className="font-bold text-center">{label}</h4>
        </div>
        <div className="px-2">
          {events.length === 0 ? (
            <div className="mt-1 py-2 rounded-lg bg-white dark:bg-black border border-black dark:border-gray-500">
              <p className="text-center">
                {t("no-data-yet", { defaultValue: "No Data Yet" })}
              </p>
            </div>
          ) : (
            <>
              {displayedEvents.map((event, index) => (
                <ListItem
                  key={`${event.id}-${index}`}
                  item={event}
                  text={event.title}
                  createdBy={event.createdByName}
                  isPublish={event.isPublish}
                  bgColor={getEventColor(event.agendaType as EventType)}
                  colorList={getEventColorList(event.agendaType as EventType)}
                />
              ))}
              {hasMoreEvents && (
                <Popover>
                  <PopoverTrigger asChild>
                    <Button className="w-full" size="sm">
                      Lihat lebih banyak
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent
                    side="top"
                    className="p-0 overflow-hidden bg-transparent shadow-none border-none"
                  >
                    <Card>
                      <CardHeader className="bg-default p-2 rounded-t-lg">
                        <CardTitle className="text-default-foreground text-base py-0">
                          {label}
                        </CardTitle>
                      </CardHeader>
                      <CardContent className="p-2 text-sm">
                        <div className="max-h-[300px] overflow-y-auto border rounded-md border-gray-300 p-2">
                          {events.map((event, index) => (
                            <ListItem
                              key={`${event.id}-full-${index}`}
                              item={event}
                              text={event.title}
                              createdBy={event.createdByName}
                              isPublish={event.isPublish}
                              bgColor={getEventColor(
                                event.agendaType as EventType
                              )}
                              colorList={getEventColorList(
                                event.agendaType as EventType
                              )}
                            />
                          ))}
                        </div>
                      </CardContent>
                    </Card>
                  </PopoverContent>
                </Popover>
              )}
            </>
          )}
        </div>
      </div>
    );
  };

  const months: Array<{ id: keyof YearlyData; label: string }> = [
    { id: "january", label: "Januari" },
    { id: "february", label: "Februari" },
    { id: "march", label: "Maret" },
    { id: "april", label: "April" },
    { id: "may", label: "Mei" },
    { id: "june", label: "Juni" },
    { id: "july", label: "Juli" },
    { id: "august", label: "Agustus" },
    { id: "september", label: "September" },
    { id: "october", label: "Oktober" },
    { id: "november", label: "November" },
    { id: "december", label: "Desember" },
  ];

  const getModalContent = () => (
    <div className="overflow-x-auto overflow-y-auto">
      {isLoading ? (
        <p>Loading...</p>
      ) : (
        <table className="w-full border-collapse border border-gray-300">
          <thead>
            <tr className="bg-gray-100 border-b">
              <th className="px-4 py-2 text-left">No</th>
              <th className="px-4 py-2 text-left">Ticket Number</th>
              <th className="px-4 py-2 text-left">Date and Time</th>
              <th className="px-4 py-2 text-left">Title</th>
              <th className="px-4 py-2 text-left">Status</th>
            </tr>
          </thead>
          <tbody>
            <tr className="border-b">
              <td className="px-4 py-2">1</td>
              <td className="px-4 py-2">MIA - 001</td>
              <td className="px-4 py-2">23/01/2025 13:00</td>
              <td className="px-4 py-2">Daily Issue 25 Januari 2025</td>
              <td className="px-4 py-2">Completed</td>
            </tr>
          </tbody>
        </table>
      )}
    </div>
  );

  return (
    <>
      <div className="grid grid-cols-12 gap-6 divide-x divide-border bg-slate-100 py-4 px-2">
        <Card className="col-span-12 lg:col-span-4 2xl:col-span-3 pb-5">
          <CardContent className="p-0">
            <CardHeader className="border-none mb-2 pt-5">
              {/* {[3, 11, 2, 12].includes(roleId) && (
                <Button
                  onClick={handleDateClick}
                  className="dark:bg-background dark:text-foreground w-full"
                >
                  <Plus className="w-4 h-4 me-1" />
                  {t("addEvent", { defaultValue: "Add Event" })}
                </Button>
              )} */}
              {/* {[3, 11, 2, 12].includes(roleId) && levelNumber !== 3 && ( */}
                <Button
                  onClick={handleDateClick}
                  className="dark:bg-background dark:text-foreground w-full border"
                >
                  <Plus className="w-4 h-4 me-1" />
                  {t("addEvent", { defaultValue: "Add Event" })}
                </Button>
              {/* )} */}

              {/* {roleId === 3 && userLevelId === 216 && ( */}
                <Dialog open={open} onOpenChange={setOpen}>
                  <DialogTrigger asChild>
                    <Button className="dark:bg-background dark:text-foreground w-full border">
                      <Book size={15} className="w-4 h-4 mr-3" />
                      {t("bag-pa-monitoring-results", {
                        defaultValue: "Bag Pa Monitoring Results",
                      })}
                    </Button>
                  </DialogTrigger>
                  <DialogContent className="sm:max-w-[425px] md:max-w-[500px] lg:max-w-[1500px] overflow-y-auto max-h-[500px]">
                    <DialogHeader>
                      <DialogTitle>
                        {t("monitoring-results", {
                          defaultValue: "Monitoring Results",
                        })}
                      </DialogTitle>
                    </DialogHeader>
                    {getModalContent()}
                  </DialogContent>
                </Dialog>
              {/* )} */}
            </CardHeader>

            <div className="px-3">
              <Calendar
                mode="single"
                selected={date}
                onSelect={(selectedDate) => {
                  if (selectedDate) {
                    setDate(selectedDate);
                    handleDateClick(selectedDate);
                  }
                }}
                className="rounded-md border w-full p-0 border-none border-black"
              />
            </div>

            <div className="py-4 text-default-800 font-semibold text-xs uppercase mt-4 mb-2 px-4">
              {t("filter", { defaultValue: "Filter" })}
            </div>
            <ul className="space-y-3 px-4">
              <li className="flex gap-3">
                <Checkbox
                  checked={selectedCategory.length === categories.length}
                  onCheckedChange={() => {
                    if (selectedCategory.length === categories.length) {
                      setSelectedCategory([]);
                    } else {
                      setSelectedCategory(categories.map((c) => c.value));
                    }
                  }}
                />
                <Label>All</Label>
              </li>
              {categories.map((category) => (
                <li className="flex gap-3" key={category.value}>
                  <Checkbox
                    className={category.className}
                    id={category.label}
                    checked={selectedCategory.includes(category.value)}
                    onCheckedChange={() =>
                      handleCategorySelection(category.value)
                    }
                  />
                  <Label htmlFor={category.label}>{category.label}</Label>
                </li>
              ))}
            </ul>
          </CardContent>
        </Card>

        <Card className="col-span-12 lg:col-span-8 2xl:col-span-9 pt-5">
          <CardContent className="dashcode-app-calendar">
            <FullCalendar
              plugins={[
                dayGridPlugin,
                timeGridPlugin,
                interactionPlugin,
                listPlugin,
              ]}
              headerToolbar={{
                left: "prev,next today",
                center: "title",
                right: "listYear,dayGridMonth,listMonth",
              }}
              views={{
                listYear: {
                  type: "dayGridMonth",
                  buttonText: "Year",
                },
              }}
              events={filteredEvents}
              editable={true}
              rerenderDelay={10}
              eventDurationEditable={false}
              selectable={true}
              selectMirror={true}
              droppable={true}
              dayMaxEvents={2}
              weekends={true}
              eventClassNames={handleClassName}
              dateClick={handleDateClick}
              eventClick={handleEventClick}
              initialView="listYear"
              eventContent={renderEventContent}
              viewDidMount={(info) => handleViewChange(info.view.type)}
              datesSet={(info: any) => {
                handleDateChange(info.view.currentStart, info.view.currentEnd);
                handleViewChange(info.view.type);
              }}
              viewClassNames={
                activeView === "listYear" ? "hide-calendar-grid" : ""
              }
            />

            {activeView === "listYear" && (
              <div className="custom-ui">
                {[0, 3, 6, 9].map((startIndex) => (
                  <div key={startIndex} className="flex gap-1 mt-1">
                    {months.slice(startIndex, startIndex + 3).map((month) => (
                      <MonthCard
                        key={month.id}
                        monthId={month.id}
                        label={month.label}
                      />
                    ))}
                  </div>
                ))}
              </div>
            )}
          </CardContent>
        </Card>
      </div>

      <EventModal
        open={sheetOpen}
        onClose={handleCloseModal}
        categories={categories}
        event={selectedEventData}
        selectedDate={selectedEventDate}
      />
    </>
  );
};

export default CalendarView;
