<template>
  <div class="card">
    <div class="card-body">
      <h2 class="card-title">휴가 신청</h2>
      <p class="require"><img :src="require" alt=""> 필수입력</p>
      <div class="row g-3 needs-validation">
        <div class="col-12">
          <label for="inputName5" class="form-label">
            <p>유형<span class="require"><img :src="require" alt=""></span></p>
          </label>
          <select class="form-select" style="max-width: 200px;" v-model="editData.vcatnKnd" @change="fnOnchangeVcatnKnd">
            <option value="" disabled hidden>유형 선택</option>
            <option v-for="(item, idx) of cmmnCodes.vcatnKndCodeList" :key="idx" :value="item.code">{{ item.codeNm }}</option>
          </select>
          <template v-if="showSubTypeSelect">
            <select class="form-select mt-2" style="max-width: 200px;" v-model="editData.vcatnSubKnd" @change="fnOnchangeVcatnSubKnd">
              <option value="" disabled hidden>세부 유형 선택</option>
              <option v-for="(item, idx) of subTypes" :key="idx" :value="item.code">{{ item.codeNm }}</option>
            </select>
          </template>
        </div>
        <div class="col-12">
          <label for="bgnde" class="form-label">
            <p>시작일<span class="require"><img :src="require" alt=""></span></p>
          </label>
          <div class="d-flex gap-1">
            <input type="date" class="form-control" id="bgnde" v-model="editData.bgnde" @keydown="preventKeyboard" />
            <input type="text" class="form-control" placeholder="시" style="width: 100px;" v-model="editData.beginHour" readonly />
            <input type="text" class="form-control" placeholder="분" style="width: 100px;" v-model="editData.beginMnt" readonly />
          </div>
        </div>
        <div class="col-12">
          <label for="endde" class="form-label">
            <p>종료일<span class="require"><img :src="require" alt=""></span></p>
          </label>
          <div class="d-flex gap-1">
            <input type="date" class="form-control" id="endde" v-model="editData.endde" :readonly="dayCnt === 0.5" @keydown="preventKeyboard" />
            <input type="text" class="form-control" placeholder="시" style="width: 100px;" v-model="editData.endHour" readonly />
            <input type="text" class="form-control" placeholder="분" style="width: 100px;" v-model="editData.endMnt" readonly />
          </div>
        </div>
        <div class="col-12">
          <label for="totalDays" class="form-label">사용 휴가일</label>
          <input type="text" class="form-control" id="totalDays" v-model="totalDays" readonly />
        </div>
        <div class="col-12">
          <label for="member" class="form-label">
            <span>승인자<span class="require"><img :src="require" alt=""></span></span>
            <button type="button" title="추가" @click="isOpenModal = true">
              <PlusCircleFilled />
            </button>
          </label>
          <HrPopup v-if="isOpenModal && isCodesLoaded" :sanctns="editData.sanctnList" :cmmnCodes="cmmnCodes" @onSelected="fnAddSanctn" @close="isOpenModal = false" />
          <div class="approval-container">
            <SanctnList v-model:sanctns="editData.sanctnList" @delSanctn="fnDelSanctn" />
          </div>
        </div>
        <div class="col-12 border-x hyuga">
          <label for="prvonsh" class="form-label">세부사항</label>
          <div>
            <EditorComponent v-model:contents="editData.detailCn" />
          </div>
        </div>
      </div>
      <div class="buttons">
        <button type="button" class="btn btn-red" @click="fnRecord">이전 승인자 불러오기</button>
        <button type="button" class="btn primary" @click="fnSave">신청</button>
        <button type="button" class="btn tertiary" @click="fnMoveTo('list')">취소</button>
      </div>
    </div>
  </div>
</template>
<script>
import { PlusCircleFilled, CloseOutlined } from '@ant-design/icons-vue';
import HrPopup from '../../../component/Popup/HrPopup.vue';
import SanctnList from '../../../component/Sanctn/SanctnFormList.vue';
import EditorComponent from '../../../component/editor/EditorComponent.vue';
// API
import { findVcatnProc, saveVcatnProc, findLastVcatnProc, updateVcatnProc } from '../../../../resources/api/vcatn';

export default {
  components: {
    PlusCircleFilled,
    CloseOutlined,
    HrPopup,
    SanctnList,
    EditorComponent,
  },

  data() {
    return {
      require: "/client/resources/img/require.png",
      pageId: null,
      isOpenModal: false,
      editData: {
        vcatnId: null,
        userId: null,
        vcatnKnd: '',
        vcatnSubKnd: '', // 세부 유형 추가
        deptId: null,
        clsf: null,
        bgnde: null,
        beginHour: null,
        beginMnt: null,
        endde: null,
        endHour: null,
        endMnt: null,
        detailCn: null,
        confmAt: null,
        sanctnList: [],
      },
      dayCnt: 0,
      totalDays: 0,
      cmmnCodes: {},
      workConfig: {
        startHour: 9,    // 근무 시작 시간
        endHour: 18,     // 근무 종료 시간
        lunchStart: 12,  // 점심 시작 시간
        lunchEnd: 13,    // 점심 종료 시간
      },
      subTypes: [],
    };
  },

  computed: {
    // 세부 유형 선택박스를 보여줄지 여부
    showSubTypeSelect() {
      return this.dayCnt === 0.5 && this.subTypes.length > 0;
    },

    // cmmnCodes가 로드되었는지 확인
    isCodesLoaded() {
      return this.cmmnCodes && Object.keys(this.cmmnCodes).length > 0;
    }
  },

  async created() {
    this.pageId = this.$route.query.id;
    this.cmmnCodes = await this.$defaultCodes();
    for (const vcatnType of this.cmmnCodes.vcatnKndCodeList) {
      if (parseFloat(vcatnType.codeValue) === 0.5) {
        this.subTypes = await this.$findChildCodes(vcatnType.code);
        break;
      }
    }
  },

  mounted() {
    if (!this.$isEmpty(this.pageId)) {
      this.findData();
    }
  },

  watch: {
    'editData.bgnde'(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.changeBgnde();
      }
    },
    'editData.endde'(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.validateAndCalculateDays();
      }
    },
  },

  methods: {
    async findData() {
      try {
        const response = await findVcatnProc(this.pageId);
        const result = response.data.data;

        this.editData = result.vo;
        this.editData.bgnde = this.editData.bgnde.split(' ')[0];
        this.editData.endde = this.editData.endde.split(' ')[0];

        let sanctns = [];
        for (let sanctn of this.editData.sanctnList) {
          let data = {
            confmerId: sanctn.confmerId,
            clsf: sanctn.clsf,
            sanctnOrdr: sanctn.sanctnOrdr,
            sanctnSe: sanctn.sanctnSe,
            clsfNm: sanctn.confmerInfo?.clsf,
            userNm: sanctn.confmerInfo?.userNm
          }
          sanctns.push(data);
        }
        this.editData.sanctnList = sanctns;

        await this.fnOnchangeVcatnKnd();
      } catch (error) {
        console.error('데이터 조회 실패:', error);
        const message = error.response?.data?.message || "데이터를 불러오는데 실패했습니다.";
        alert(message);
        this.fnMoveTo('list');
      }
    },

    // 유형 변경
    async fnOnchangeVcatnKnd() {
      if (!this.isCodesLoaded || !Array.isArray(this.cmmnCodes.vcatnKndCodeList)) {
        console.warn('cmmnCodes가 초기화되지 않았습니다.');
        return;
      }

      const selectedVcatn = this.cmmnCodes.vcatnKndCodeList.find(item => item.code === this.editData.vcatnKnd);
      if (!selectedVcatn) {
        console.warn('선택된 휴가 유형을 찾을 수 없습니다.');
        return;
      }

      this.dayCnt = parseFloat(selectedVcatn.codeValue);

      if (this.dayCnt === 0.5) {
        this.changeBgnde(); // 반차일 경우 종료일을 시작일과 동일하게 설정
      } else {
        this.editData.vcatnSubKnd = ''; // 세부 유형 선택 초기화

        // 전체 근무시간으로 설정
        this.editData.beginHour = this.workConfig.startHour.toString().padStart(2, '0');
        this.editData.beginMnt = '00';
        this.editData.endHour = this.workConfig.endHour.toString().padStart(2, '0');
        this.editData.endMnt = '00';
        this.calculateTotalDays();
      }
    },

    // 세부 유형 변경
    fnOnchangeVcatnSubKnd() {
      if (this.dayCnt === 0.5) {
        const selectedSubType = this.subTypes.find(item => item.code === this.editData.vcatnSubKnd);
        if (selectedSubType) {
          this.setHalfDayTime(selectedSubType);
        }
      }
      this.calculateTotalDays();
    },

    // 반차 시간 설정 메서드
    setHalfDayTime(selectedSubType) {
      const codeValue = selectedSubType.codeValue;

      // 전체 실제 근무시간 계산 (점심시간 제외)
      const totalHours = this.workConfig.endHour - this.workConfig.startHour; // 전체 시간
      const lunchHours = this.workConfig.lunchEnd - this.workConfig.lunchStart; // 점심시간
      const actualWorkHours = totalHours - lunchHours; // 실제 근무시간
      const halfWorkHours = actualWorkHours / 2; // 반차 시간

      this.editData.beginMnt = '00';
      this.editData.endMnt = '00';

      if (codeValue === 'AM') {
        this.editData.beginHour = this.workConfig.startHour.toString().padStart(2, '0');
        this.editData.endHour = this.calculateTimeWithLunch(this.workConfig.startHour, halfWorkHours, 1).toString().padStart(2, '0');
      } else if (codeValue === 'PM') {
        this.editData.beginHour = this.calculateTimeWithLunch(this.workConfig.endHour, halfWorkHours, -1).toString().padStart(2, '0');
        this.editData.endHour = this.workConfig.endHour.toString().padStart(2, '0');
      }
    },

    // 점심시간을 고려하여 시간 계산 (방향: 1=앞으로, -1=뒤로)
    calculateTimeWithLunch(startTime, workHours, direction = 1) {
      let currentHour = startTime;
      let remainingHours = workHours;

      while (remainingHours > 0) {
        if (direction === 1) {
          // 앞으로 계산 (종료시간 구하기)
          if (currentHour >= this.workConfig.lunchStart && currentHour < this.workConfig.lunchEnd) {
            currentHour++;
          } else {
            currentHour++;
            remainingHours--;
          }
        } else {
          // 뒤로 계산 (시작시간 구하기)
          currentHour--;
          if (!(currentHour >= this.workConfig.lunchStart && currentHour < this.workConfig.lunchEnd)) {
            remainingHours--;
          }
        }
      }

      return currentHour;
    },

    // 시작일과 종료일 통일
    changeBgnde() {
      if (!this.editData.bgnde) {
        return;
      }

      // 반차인 경우 종료일을 시작일과 동일하게 설정
      if (this.dayCnt === 0.5) {
        this.editData.endde = this.editData.bgnde;
      }

      this.validateAndCalculateDays(); // 사용 휴가일 계산
    },

    // 사용 휴가일 계산
    validateAndCalculateDays() {
      if (!this.editData.bgnde || !this.editData.endde) {
        this.totalDays = 0;
        return;
      }

      const startDate = new Date(this.editData.bgnde);
      const endDate = new Date(this.editData.endde);

      // 날짜 유효성 검사
      if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
        this.totalDays = 0;
        return;
      }

      // 종료일이 시작일보다 이전인지 확인 (반차가 아닌 경우)
      if (this.dayCnt !== 0.5 && endDate < startDate) {
        alert('종료일은 시작일보다 이전일 수 없습니다.');
        this.editData.endde = this.editData.bgnde;
        return;
      }

      this.calculateTotalDays();
    },

    calculateTotalDays() {
      if (!this.editData.bgnde || !this.editData.endde) {
        this.totalDays = 0;
        return;
      }

      const startDate = new Date(this.editData.bgnde);
      const endDate = new Date(this.editData.endde);

      if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
        this.totalDays = 0;
        return;
      }

      const timeDiff = endDate.getTime() - startDate.getTime();
      const dayDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24)) + 1;

      // 반차의 경우 0.5일, 그 외의 경우 실제 일수 계산
      if (this.dayCnt === 0.5) {
        this.totalDays = 0.5;
      } else {
        this.totalDays = Math.max(0, dayDiff);
      }
    },

    preventKeyboard(event) {
      if (event.key !== 'Tab') {
        event.preventDefault();
      }
    },

    // 승인자
    fnAddSanctn(user) {
      const data = {
        confmerId: user.userId,
        clsf: user.clsf,
        sanctnOrdr: this.editData.nmprList.length + 1,
        sanctnSe: this.cmmnCodes.sanctnCodeList[0].code,

        clsfNm: this.formatClsf(user.clsf),
        userNm: user.userNm,
      };

      this.editData.sanctnList.push(data);
      this.isOpenModal = false;
    },

    fnDelSanctn(idx) {
      this.editData.sanctnList.splice(idx, 1);
      this.editData.sanctnList.forEach((item, index) => {
        item.sanctnOrdr = index + 1;
      });
    },

    // 직급 매칭
    formatClsf(code) {
      const clsfCode = this.cmmnCodes?.clsfCodeList?.find(item => item.code === code);
      return clsfCode?.codeNm || code;
    },

    async fnRecord() {
      try {
        const response = await findLastVcatnProc();
        const result = response.data.data;

        if (this.$isEmpty(result.lists)) {
          alert("휴가 기록이 존재하지 않아, 이전 승인자를 불러올 수 없습니다.");
          return;
        }

        this.editData.sanctnList = result.lists;
      } catch (error) {
        console.error('이전 승인자 조회 실패:', error);
        const message = error.response?.data?.message || "이전 승인자를 불러오는데 실패했습니다.";
        alert(message);
      }
    },

    validateForm() {
      if (this.$isEmpty(this.editData.vcatnKnd)) {
        alert("유형을 선택해 주세요.");
        return false;
      }

      if (this.$isEmpty(this.editData.bgnde)) {
        alert("시작일을 선택해 주세요.");
        return false;
      }

      if (this.$isEmpty(this.editData.endde)) {
        alert("종료일을 선택해 주세요.");
        return false;
      }

      if (this.$isEmpty(this.editData.sanctnList)) {
        alert("승인자를 선택해 주세요.");
        return false;
      }

      if (this.dayCnt === 0.5) {
        if (this.$isEmpty(this.editData.vcatnSubKnd)) {
          alert("세부 유형을 선택해 주세요.");
          return false;
        }
      }

      return true;
    },

    async fnSave() {
      try {
        if (!this.validateForm()) {
          return;
        }

        if (!this.$isEmpty(this.pageId)) {
          this.editData.confm_at = 'W';
        }

        const response = this.$isEmpty(this.pageId) ? await saveVcatnProc(this.editData) : await updateVcatnProc(this.editData);
        const message = this.$isEmpty(this.pageId) ? "등록되었습니다." : "수정되었습니다.";
        alert(message);

        this.fnMoveTo('view', response.data.data.pageId);
      } catch (error) {
        console.error('저장 실패:', error);
        const message = error.response?.data?.message || "저장에 실패했습니다.";
        alert(message);
      }
    },

    fnMoveTo(type, id) {
      const routes = {
        'list': { name: 'hyugaStatue' },
        'view': { name: 'HyugaDetail', query: { id } },
        'edit': { name: 'hyugaInsert', query: this.$isEmpty(id) ? {} : { id } },
      };

      if (routes[type]) {
        if (!this.$isEmpty(this.pageId) && type === 'list') {
          this.$router.push({ name: 'HyugaDetail', query: { id: this.pageId } });
          return;
        }
        this.$router.push(routes[type]);
      } else {
        alert("올바르지 않은 경로를 요청하여 목록으로 이동합니다.");
        this.$router.push(routes['list']);
      }
    },
  },
};
</script>