<template>
    <div class="container-xxl flex-grow-1 container-p-y pb-0">
        <div class="card app-calendar-wrapper">
            <div class="row g-0">
                <div class="col-3 border-end text-center" id="app-calendar-sidebar">
                    <div class="card-body">
                        <img v-if="user" :src="`${baseUrl}upload/img/profile/${user.profile}`" alt="Profile Image" class="w-px-50 h-px-50 rounded-circle" @error="$event.target.src = '/img/icons/icon.png'"/>
                        <p class="mt-2 fw-bold">
                            {{ user.name }}
                        </p>

                        <CommuterBtn
                            :userId="user.id"
                            :checkedInProject="checkedInProject || {}"
                            :pendingProjectChange="pendingProjectChange"
                            @workTimeUpdated="handleWorkTimeUpdate"
                            @leaveTimeUpdated="handleLeaveTimeUpdate"
                            ref="workTimeComponentRef"
                        />

                        <CommuterProjectList
                            :project="project"
                            :commuters="commuters"
                            :baseUrl="baseUrl"
                            :user="user"
                            :selectedProject="selectedProject"
                            :checkedInProject="checkedInProject"
                            @drop="handleProjectDrop"
                        />
                    </div>
                </div>

                <div class="col app-calendar-content">
                    <div class="card shadow-none border-0">
                        <div class="card-body">
                            <full-calendar
                                ref="fullCalendarRef"
                                :events="calendarEvents"
                                :options="calendarOptions"
                                defaultView="dayGridMonth"
                                class="flatpickr-calendar-only"
                            >
                            </full-calendar>
                            <input ref="calendarDatepicker" type="text" class="d-none" />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <CenterModal :display="isModalOpen" @close="closeModal">
        <template #title>
            {{ eventDate }}
        </template>
        <template #body>
            <div v-if="selectedDateCommuters.length > 0">
                <div v-for="(commuter, index) in selectedDateCommuters" :key="index">
                    <div class="d-flex align-items-center my-2">
                        <img :src="`${baseUrl}upload/img/profile/${commuter.profile}`"
                        class="rounded-circle me-2 w-px-50 h-px-50"
                        @error="$event.target.src = '/img/icons/icon.png'">

                        <span class="fw-bold">{{ commuter.memberName }}</span>

                        <div class="ms-auto text-start fw-bold">
                            <div class="d-flex gap-1 align-items-center ">
                                출근 :
                                <div class="text-white rounded px-2" :style="`background: ${commuter.projctcolor} !important;`">
                                    {{ commuter.PROJCTNAM }}
                                </div>
                                ({{ commuter.COMMUTCMT }})
                            </div>
                            <div v-if="commuter.PROJCTLVE" class="d-flex gap-1 mt-1">
                                퇴근 :
                                <div class="text-white rounded px-2" :style="`background: ${commuter.leaveProjectColor} !important;`">
                                    {{ commuter.leaveProjectName }}
                                </div>
                                ({{ commuter.COMMUTLVE || "00:00:00" }})
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </template>
        <template #footer>
            <BackBtn @click="closeModal" />
        </template>
    </CenterModal>

</template>

<script setup>
import FullCalendar from '@fullcalendar/vue3';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
import CenterModal from '@c/modal/CenterModal.vue';
import { computed, inject, nextTick, onMounted, reactive, ref, watch } from 'vue';
import $api from '@api';
import 'flatpickr/dist/flatpickr.min.css';
import '@/assets/css/app-calendar.css';
import { fetchHolidays } from '@c/calendar/holiday';
import { useUserInfoStore } from '@/stores/useUserInfoStore';
import { useProjectStore } from '@/stores/useProjectStore';
import CommuterBtn from '@c/commuters/CommuterBtn.vue';
import CommuterProjectList from '@c/commuters/CommuterProjectList.vue';
import BackBtn from '@c/button/BackBtn.vue';
import { useDatePicker } from '@/stores/useDatePicker';

const datePickerStore = useDatePicker();

const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
const user = ref({});
const project = ref({});
const userStore = useUserInfoStore();
const projectStore = useProjectStore();

const dayjs = inject('dayjs');
const fullCalendarRef = ref(null);
const workTimeComponentRef = ref(null);
const calendarEvents = ref([]);
const eventDate = ref('');

const selectedProject = ref(null);
const checkedInProject = ref(null);

const isModalOpen = ref(false);

const commuters = ref([]);
const monthlyCommuters = ref([]);

const calendarDatepicker = ref(null);

const pendingProjectChange = ref(null);


// 출퇴근 컴포넌트 이벤트 핸들러
const handleWorkTimeUpdate = () => {
    todaysCommuter();
    loadCommuters();
};

const handleLeaveTimeUpdate = () => {
    todaysCommuter();
};

// 프로젝트 드롭 이벤트 핸들러 (ProjectList 컴포넌트에서 전달받음)
const handleProjectDrop = ({ event, targetProject }) => {
    const draggedProjectData = JSON.parse(event.dataTransfer.getData('application/json'));

    // 기존 프로젝트와 동일한 경우 변경 안 함
    if (draggedProjectData.PROJCTSEQ === targetProject.PROJCTSEQ) {
        return;
    }

    pendingProjectChange.value = {
        projctSeq: targetProject.PROJCTSEQ,
        memberSeq: user.value.id
    };

    checkedInProject.value = targetProject;
    selectedProject.value = targetProject.PROJCTSEQ;
    projectStore.setSelectedProject(targetProject);

    // 기존 UI 업데이트
    commuters.value = commuters.value.map(commuter =>
        commuter.MEMBERSEQ === user.value.id
            ? { ...commuter, PROJCTNAM: targetProject.PROJCTNAM, PROJCTLVE: targetProject.PROJCTSEQ }
            : commuter
    );
};

// 오늘 출근 모든 사용자 조회
const todaysCommuter = async () => {
    const res = await $api.get(`commuters/todays`);
    if (res.status === 200 ) {
        commuters.value = res.data.data;
    }
};

// 캘린더 데이터 가져오기
const fetchData = async () => {
    // FullCalendar API 인스턴스 가져오기
    const calendarApi = fullCalendarRef.value?.getApi();
    if (!calendarApi) return;

    // 현재 표시된 달력의 연도, 월 추출
    const date = calendarApi.currentData.viewTitle;
    const dateArr = date.split(' ');
    let currentYear = dateArr[0].trim();
    let currentMonth = dateArr[1].trim();
    const regex = /\D/g;
    // 숫자가 아닌 문자 제거 후 정수로 변환
    currentYear = parseInt(currentYear.replace(regex, ''), 10);
    currentMonth = parseInt(currentMonth.replace(regex, ''), 10);

    try {
        // 현재 표시 중인 월의 공휴일 정보 가져오기
        const holidayEvents = await fetchHolidays(currentYear, String(currentMonth).padStart(2, '0'));
        // 기존 이벤트에서 공휴일 이벤트를 제외한 이벤트만 필터링
        const existingEvents = calendarEvents.value.filter(event => !event.classNames?.includes('holiday-event'));
        // 필터링된 이벤트와 새로 가져온 공휴일 이벤트 병합
        calendarEvents.value = [...existingEvents, ...holidayEvents];

        // 출근 정보
        await loadCommuters();

    } catch (error) {
        console.error('공휴일 정보 로딩 실패:', error);
    }
};

// 캘린더 이동 함수 (이전, 다음, 오늘)
const moveCalendar = async (value = 0) => {
    const calendarApi = fullCalendarRef.value?.getApi();

    if (value === 1) {
        calendarApi.prev();  // 이전 달로 이동
    } else if (value === 2) {
        calendarApi.next();  // 다음 달로 이동
    } else if (value === 3) {
        calendarApi.today();  // 오늘 날짜로 이동
    }

    await fetchData();
};

// 날짜 선택 가능 여부를 확인하는 공통 함수
const isSelectableDate = (date) => {
    const checkDate = dayjs(date);
    const isWeekend = checkDate.day() === 0 || checkDate.day() === 6;
    // 공휴일 체크
    const isHoliday = calendarEvents.value.some(event =>
        event.classNames?.includes('holiday-event') &&
        dayjs(event.start).format('YYYY-MM-DD') === checkDate.format('YYYY-MM-DD')
    );

    return !isWeekend && !isHoliday;
};


// 날짜 클릭 이벤트 함수
let todayElement = null;
const handleDateClick = (info) => {
    const clickedDate = dayjs(info.date).format('YYYY-MM-DD');

    // 클릭한 날짜에 월별 출근 정보가 있는지 확인
    const dateCommuters = monthlyCommuters.value.filter(commuter =>
        commuter.COMMUTDAY === clickedDate
    );

    // 출근 기록이 있는 경우에만 모달 열기
    if (dateCommuters.length > 0) {
        eventDate.value = clickedDate;
        isModalOpen.value = true;
    }

    if (isSelectableDate(info.date)) {
        const isToday = dayjs(info.date).isSame(dayjs(), 'day');

        if (isToday) {
            // 오늘 날짜 클릭 시 클래스 제거하고 요소 저장
            todayElement = info.dayEl;
            todayElement.classList.remove('fc-day-today');
        } else if (todayElement) {
            // 다른 날짜 클릭 시 저장된 오늘 요소에 클래스 다시 추가
            todayElement.classList.add('fc-day-today');
            todayElement = null;
        }
    }
};

// 바깥 클릭 시 todayElement 클래스 복구
document.addEventListener('click', (event) => {
    if (todayElement && !event.target.closest('.fc-daygrid-day')) {
        todayElement.classList.add('fc-day-today');
        todayElement = null;
    }
}, true);

// 날짜 셀 클래스 추가 함수
const getCellClassNames = (arg) => {
    const cellDate = dayjs(arg.date);
    const classes = [];

    // 선택 불가능한 날짜(과거, 주말, 공휴일)에 동일한 클래스 추가
    if (!isSelectableDate(cellDate)) {
        classes.push('fc-day-sat-sun');
    }

    return classes;
};

// 현재 달의 모든 출근 정보 조회
const loadCommuters = async () => {
    const calendarApi = fullCalendarRef.value?.getApi();
    if (!calendarApi) return;
    const date = calendarApi.currentData.viewTitle;
    const dateArr = date.split(' ');
    let currentYear = dateArr[0].trim();
    let currentMonth = dateArr[1].trim();
    const regex = /\D/g;
    currentYear = parseInt(currentYear.replace(regex, ''), 10);
    currentMonth = parseInt(currentMonth.replace(regex, ''), 10);

    const res = await $api.get('commuters/month', {
        params: {
            year: currentYear,
            month: currentMonth
        }
    });
    if (res.status === 200) {
        // 월별 출근 정보 저장
        monthlyCommuters.value = res.data.data;

        document.querySelectorAll('.fc-daygrid-day-events img.rounded-circle').forEach(img => {
            img.remove();
        });

        monthlyCommuters.value.forEach(commuter => {
            const date = commuter.COMMUTDAY;
            const dateCell = document.querySelector(`.fc-day[data-date="${date}"]`) ||
                document.querySelector(`.fc-daygrid-day[data-date="${date}"]`);
            if (dateCell) {
                const dayEvents = dateCell.querySelector('.fc-daygrid-day-events');
                if (dayEvents) {
                    dayEvents.classList.add('text-center');
                    // 프로필 이미지 생성
                    const profileImg = document.createElement('img');
                    profileImg.src = `${baseUrl}upload/img/profile/${commuter.profile}`;
                    profileImg.className = 'rounded-circle w-px-20 h-px-20 mx-1 mb-1 position-relative z-5 m-auto';
                    profileImg.style.border = `2px solid ${commuter.projctcolor}`;
                    profileImg.onerror = () => { profileImg.src = '/img/icons/icon.png'; };

                    dayEvents.appendChild(profileImg);
                }
            }
        });
    }
};


// 캘린더 옵션 설정
const calendarOptions = reactive({
    plugins: [dayGridPlugin, interactionPlugin],
    initialView: 'dayGridMonth',
    headerToolbar: {
        left: 'today',
        center: 'title',
        right: 'prev,next',
    },
    locale: 'kr',
    events: calendarEvents,
    eventOrder: 'sortIdx',
    contentHeight:"auto",
    // eventContent: calendarCommuter,
    // 날짜 선택 관련 옵션 수정
    selectable: true,
    selectAllow: (selectInfo) => isSelectableDate(selectInfo.start),
    dateClick: handleDateClick,
    dayCellClassNames: getCellClassNames,

    // 날짜 클릭 비활성화를 위한 추가 설정
    unselectAuto: true,
    droppable: false,
    eventDisplay: 'block',

    // 커스텀 버튼 정의
    customButtons: {
        prev: {
            text: 'PREV',
            click: () => moveCalendar(1),
        },
        today: {
            text: 'TODAY',
            click: () => moveCalendar(3),
        },
        next: {
            text: 'NEXT',
            click: () => moveCalendar(2),
        },
    },
});

// 달력 뷰 변경 감지 (월 변경 시 데이터 다시 가져오기)
watch(() => fullCalendarRef.value?.getApi().currentData.viewTitle, async () => {
    await fetchData();
});

// selectedProject 변경 감지
watch(() => projectStore.selectedProject, (newProject) => {
    if (newProject) {
        selectedProject.value = newProject.PROJCTSEQ;
        checkedInProject.value = newProject;
    }
});

// 모달 닫기
const closeModal = () => {
    isModalOpen.value = false;
};

const selectedDateCommuters = computed(() => {
    return monthlyCommuters.value.filter(commuter =>
        commuter.COMMUTDAY === eventDate.value
    );
});
onMounted(async () => {
    await fetchData();
    await userStore.userInfo();
    user.value = userStore.user;
    await projectStore.getProjectList('', '', 'true');
    project.value = projectStore.activeProjectList;

    await todaysCommuter();

    // 저장된 선택 프로젝트 가져오기
    const storedProject = projectStore.getSelectedProject();
    if (storedProject) {
        selectedProject.value = storedProject.PROJCTSEQ;
        checkedInProject.value = storedProject;
    }

    datePickerStore.initDatePicker(
        fullCalendarRef,
        async (year, month, options) => {
            // 데이터 다시 불러오기
            await fetchData();
        }
    );
});
</script>

