<template>
    <div class="vacation-management">
      <div class="container-xxl flex-grow-1 container-p-y">
        <div class="card app-calendar-wrapper">
          <div class="row g-0">
            <div class="col app-calendar-content">
              <div class="card shadow-none border-0">
                <ProfileList
                  @profileClick="handleProfileClick"
                  :remainingVacationData="remainingVacationData"
                />
                <div class="card-body w-75 p-3 align-self-center">
                  <!-- 모달에 필터링된 연차 목록 전달 -->
                  <VacationModal
                    v-if="isModalOpen"
                    :isOpen="isModalOpen"
                    :myVacations="filteredMyVacations"
                    :receivedVacations="filteredReceivedVacations"
                    :userColors="userColors"
                    @close="isModalOpen = false"
                  />

                  <VacationGrantModal
                    v-if="isGrantModalOpen"
                    :isOpen="isGrantModalOpen"
                    :targetUser="selectedUser"
                    :remainingQuota="remainingVacationData[selectedUser?.MEMBERSEQ] || 0"
                    @close="isGrantModalOpen = false"
                    @updateVacation="fetchRemainingVacation"
                  />
                  <full-calendar
                    ref="fullCalendarRef"
                    :options="calendarOptions"
                    class="flatpickr-calendar-only"
                  />
                  <HalfDayButtons
                    @toggleHalfDay="toggleHalfDay"
                    @addVacationRequests="saveVacationChanges"
                  />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </template>

  <script setup>
  import { reactive, ref, onMounted, nextTick, computed } from "vue";
  import axios from "@api";
  import FullCalendar from "@fullcalendar/vue3";
  import dayGridPlugin from "@fullcalendar/daygrid";
  import interactionPlugin from "@fullcalendar/interaction";
  import "flatpickr/dist/flatpickr.min.css";
  import "@/assets/css/app-calendar.css";
  import "bootstrap-icons/font/bootstrap-icons.css";
  import HalfDayButtons from "@c/button/HalfDayButtons.vue";
  import ProfileList from "@c/vacation/ProfileList.vue";
  import VacationModal from "@c/modal/VacationModal.vue";
  import VacationGrantModal from "@c/modal/VacationGrantModal.vue";
  import { useUserStore } from "@s/userList";
  import { useUserInfoStore } from "@s/useUserInfoStore";
  import { fetchHolidays } from "@c/calendar/holiday.js";

  const userStore = useUserInfoStore();
  const userListStore = useUserStore();
  const userList = ref([]);
  const userColors = ref({});
  const myVacations = ref([]); // 전체 "사용한 연차" 목록
  const receivedVacations = ref([]); // 전체 "받은 연차" 목록
  const isModalOpen = ref(false);
  const remainingVacationData = ref({});
  // 모달을 열 때 기준 연도 (모달에 표시할 연도)
  const modalYear  = ref(new Date().getFullYear());
  const modalMonth = ref(String(new Date().getMonth() + 1).padStart(2, "0"));
  const lastRemainingYear = ref(new Date().getFullYear());

  const isGrantModalOpen = ref(false);
  const selectedUser = ref(null);

  // FullCalendar 관련
  const fullCalendarRef = ref(null);
  const calendarEvents = ref([]);
  const selectedDates = ref(new Map());
  const halfDayType = ref(null);
  const vacationCodeMap = ref({});
  const holidayDates = ref(new Set());
  const fetchedEvents = ref([]);

  const calendarOptions = reactive({
    plugins: [dayGridPlugin, interactionPlugin],
    initialView: "dayGridMonth",
    headerToolbar: {
      left: "today",
      center: "title",
      right: "prev,next",
    },
    locale: "ko",
    selectable: false,
    dateClick: handleDateClick,
    datesSet: handleMonthChange,
    events: calendarEvents,
  });

  onMounted(async () => {
    await userStore.userInfo();
    await fetchRemainingVacation();
  });

  const fetchRemainingVacation = async () => {
    try {
      const response = await axios.get("vacation/remaining");
      if (response.status === 200) {
        remainingVacationData.value = response.data.data.reduce((acc, vacation) => {
          acc[vacation.employeeId] = vacation.remainingQuota;
          return acc;
        }, {});
      }
    } catch (error) {
      console.error("🚨 남은 연차 데이터를 불러오지 못했습니다:", error);
    }
  };

  // 프로필 클릭 시 연차 내역 가져오기
// 프로필 클릭 시 연차 내역 가져오기
const handleProfileClick = async (user) => {
  try {
    if (user.MEMBERSEQ === userStore.user.id) {
      const year = new Date().getFullYear(); // 현재 연도
      // 연도 파라미터를 전달하여 전체 연도의 연차 내역을 조회
      const response = await axios.get(`vacation/history?year=${year}`);
      if (response.status === 200 && response.data) {
        myVacations.value = response.data.data.usedVacations || [];
        receivedVacations.value = response.data.data.receivedVacations || [];
        isModalOpen.value = true;
        // 모달을 열 때 기준 연도 갱신
        modalYear.value = year;
        isGrantModalOpen.value = false;
      } else {
        console.warn("❌ 연차 내역을 불러오지 못했습니다.");
      }
    } else {
      selectedUser.value = user;
      isGrantModalOpen.value = true;
      isModalOpen.value = false;
    }
  } catch (error) {
    console.error("🚨 연차 데이터 불러오기 실패:", error);
  }
};

  const fetchUserList = async () => {
    try {
      await userListStore.fetchUserList();
      userList.value = userListStore.userList;
      if (!userList.value.length) {
        console.warn("📌 사용자 목록이 비어 있음!");
        return;
      }
      userColors.value = {};
      userList.value.forEach((user) => {
        userColors.value[user.MEMBERSEQ] = user.usercolor || "#FFFFFF";
      });
    } catch (error) {
      console.error("📌 사용자 목록 불러오기 오류:", error);
    }
  };

  const fetchVacationCodes = async () => {
    try {
      const response = await axios.get("vacation/codes");
      if (response.status === 200 && response.data) {
        vacationCodeMap.value = response.data.data.reduce((acc, item) => {
          acc[item.code] = item.name;
          return acc;
        }, {});
      } else {
        console.warn("❌ 공통 코드 데이터를 불러오지 못했습니다.");
      }
    } catch (error) {
      console.error("🚨 공통 코드 API 호출 실패:", error);
    }
  };

  const getVacationType = (typeCode) => {
    return vacationCodeMap.value[typeCode] || "기타";
  };

  // computed: modalYear와 일치하는 항목만 필터링
const filteredMyVacations = computed(() => {
  const filtered = myVacations.value.filter(vac => {
    // vac.date가 없으면 vac.LOCVACUDT를 사용하도록 함
    const dateStr = vac.date || vac.LOCVACUDT;
    const year = dateStr ? dateStr.split("T")[0].substring(0, 4) : null;
    console.log("vacation year:", year, "modalYear:", modalYear.value);
    return year === String(modalYear.value);
  });
  console.log("filteredMyVacations:", filtered);
  return filtered;
});

const filteredReceivedVacations = computed(() => {
  return receivedVacations.value.filter(vac => {
    const dateStr = vac.date || vac.LOCVACUDT;
    const year = dateStr ? dateStr.split("T")[0].substring(0, 4) : null;
    console.log("vacation year:", year, "modalYear:", modalYear.value);
    return dateStr && year === String(modalYear.value);
  });
});


  function updateCalendarEvents() {
    const selectedEvents = Array.from(selectedDates.value)
      .filter(([date, type]) => type !== "delete")
      .map(([date, type]) => ({
        title: getVacationType(type),
        start: date,
        backgroundColor: "rgb(113 212 243 / 76%)",
        textColor: "#fff",
        display: "background",
        classNames: [getVacationTypeClass(type), "selected-event"]
      }));
    const filteredFetchedEvents = fetchedEvents.value.filter(event => {
      if (event.saved) {
        return selectedDates.value.get(event.start) !== "delete";
      }
      return true;
    });
    calendarEvents.value = [...filteredFetchedEvents, ...selectedEvents];
  }

  const getVacationTypeClass = (type) => {
    if (type === "700101") return "half-day-am";
    if (type === "700102") return "half-day-pm";
    return "full-day";
  };

  function handleDateClick(info) {
    const clickedDateStr = info.dateStr;
    const clickedDate = info.date;
    const todayStr = new Date().toISOString().split("T")[0];
    if (
      clickedDate.getDay() === 0 ||
      clickedDate.getDay() === 6 ||
      holidayDates.value.has(clickedDateStr) ||
      clickedDateStr < todayStr
    ) {
      return;
    }
    if (selectedDates.value.has(clickedDateStr)) {
      selectedDates.value.delete(clickedDateStr);
      updateCalendarEvents();
      return;
    }
    const unsentVacation = myVacations.value.find(
      (vac) => vac.LOCVACUDT && vac.LOCVACUDT.startsWith(clickedDateStr) && !vac.LOCVACRMM
    );
    if (unsentVacation) {
      selectedDates.value.set(clickedDateStr, "delete");
    } else {
      const type = halfDayType.value
        ? (halfDayType.value === "AM" ? "700101" : "700102")
        : "700103";
      selectedDates.value.set(clickedDateStr, type);
    }
    halfDayType.value = null;
    updateCalendarEvents();
  }

  function toggleHalfDay(type) {
    halfDayType.value = halfDayType.value === type ? null : type;
  }

  async function fetchVacationData(year, month) {
  try {
    const response = await axios.get(`vacation/list/${year}/${month}`);
    if (response.status === 200) {
      const vacationList = response.data;
      // 모달이 열려 있더라도 전달받은 연도가 기존 modalYear와 다르면 업데이트
      if (modalYear.value !== year) {
        myVacations.value = vacationList.filter(
          (vac) => vac.MEMBERSEQ === userStore.user.id
        );
        modalYear.value = year;
        // modalMonth는 그대로 유지 (월은 모달 업데이트 조건에서 제외)
      }
      // 캘린더 이벤트 매핑
      const events = vacationList
        .filter((vac) => !vac.LOCVACRMM)
        .map((vac) => {
          let dateStr = vac.LOCVACUDT ? vac.LOCVACUDT.split("T")[0] : "";
          let backgroundColor = userColors.value[vac.MEMBERSEQ] || "#FFFFFF";
          return {
            title: getVacationType(vac.LOCVACTYP),
            start: dateStr,
            backgroundColor,
            classNames: [getVacationTypeClass(vac.LOCVACTYP)],
            saved: true,
          };
        })
        .filter((event) => event.start);
      return events;
    } else {
      console.warn("📌 휴가 데이터를 불러오지 못함");
      return [];
    }
  } catch (error) {
    console.error("Error fetching vacation data:", error);
    return [];
  }
}

  async function saveVacationChanges() {
    const selectedDatesArray = Array.from(selectedDates.value);
    const vacationsToAdd = selectedDatesArray
      .filter(([date, type]) => type !== "delete")
      .filter(([date, type]) =>
        !myVacations.value.some(vac => vac.LOCVACUDT && vac.LOCVACUDT.startsWith(date)) ||
        myVacations.value.some(vac => vac.LOCVACUDT && vac.LOCVACUDT.startsWith(date) && vac.LOCVACRMM)
      )
      .map(([date, type]) => ({ date, type }));
    const vacationsToDelete = myVacations.value
      .filter(vac => {
        if (!vac.LOCVACUDT) return false;
        const date = vac.LOCVACUDT.split("T")[0];
        return selectedDates.value.get(date) === "delete" && !vac.LOCVACRMM;
      })
      .map(vac => {
        const id = vac.LOCVACSEQ;
        return typeof id === "number" ? Number(id) : id;
      });
    try {
      const response = await axios.post("vacation/batchUpdate", {
        add: vacationsToAdd,
        delete: vacationsToDelete
      });
      if (response.data && response.data.status === "OK") {
        alert("✅ 휴가 변경 사항이 저장되었습니다.");
        await fetchRemainingVacation();
        const currentDate = fullCalendarRef.value.getApi().getDate();
        await loadCalendarData(currentDate.getFullYear(), currentDate.getMonth() + 1);
        selectedDates.value.clear();
        updateCalendarEvents();
      } else {
        alert("❌ 휴가 저장 중 오류가 발생했습니다.");
      }
    } catch (error) {
      console.error("🚨 휴가 변경 저장 실패:", error);
      alert("❌ 휴가 저장 요청에 실패했습니다.");
    }
  }

  function handleMonthChange(viewInfo) {
    const currentDate = viewInfo.view.currentStart;
    const year = currentDate.getFullYear();
    const month = String(currentDate.getMonth() + 1).padStart(2, "0");
    loadCalendarData(year, month);
  }

  async function loadCalendarData(year, month) {
    if (lastRemainingYear.value !== year) {
      await fetchRemainingVacation();
      lastRemainingYear.value = year;
    }
    fetchedEvents.value = [];
    const [vacationEvents, holidayEvents] = await Promise.all([
      fetchVacationData(year, month),
      fetchHolidays(year, month),
    ]);
    holidayDates.value = new Set(holidayEvents.map((event) => event.start));
    fetchedEvents.value = [...vacationEvents, ...holidayEvents];
    updateCalendarEvents();
    await nextTick();
    fullCalendarRef.value.getApi().refetchEvents();
  }

  onMounted(async () => {
    await fetchUserList();
    await fetchVacationCodes();
    const today = new Date();
    const year = today.getFullYear();
    const month = String(today.getMonth() + 1).padStart(2, "0");
    await loadCalendarData(year, month);
  });
  </script>

  <style>
  /* 스타일 정의 */
  </style>
