<template>
  <div class="card">
    <div class="card-body">
      <h2 class="card-title">휴가 신청</h2>
      <p class="require"><img :src="require" alt=""> 필수입력</p>
      <div class="tbl-wrap">
        <table class="tbl data">
          <tbody>
            <tr>
              <th scope="row">
                유형 <span class="require"><img :src="require" alt=""></span>
              </th>
              <td>
                <select class="form-select sm" style="max-width: 200px;" v-model="editData.vcatnKnd" @change="fnOnchangeVcatnKnd">
                  <option value="" disabled hidden>유형 선택</option>
                  <option v-for="(item, idx) of vcatnKnds" :key="idx" :value="item.code">{{ item.codeNm }}</option>
                </select>
              </td>
            </tr>
            <tr>
              <th scope="row">
                시작일 <span class="require"><img :src="require" alt=""></span>
              </th>
              <td>
                <div class="d-flex gap-1">
                  <input type="date" class="form-control sm" v-model="editData.bgnde" @keydown="preventKeyboard" />
                  <input type="text" class="form-control sm" placeholder="시" style="width: 100px;" v-model="editData.beginHour" readonly />
                  <input type="text" class="form-control sm" placeholder="분" style="width: 100px;" v-model="editData.beginMnt" readonly />
                </div>
              </td>
            </tr>
            <tr>
              <th scope="row">
                종료일 <span class="require"><img :src="require" alt=""></span>
              </th>
              <td>
                <div class="d-flex gap-1">
                  <input type="date" class="form-control sm" v-model="editData.endde" :readonly="dayCnt === 0.5" @keydown="preventKeyboard" />
                  <input type="text" class="form-control sm" placeholder="시" style="width: 100px;" v-model="editData.endHour" readonly />
                  <input type="text" class="form-control sm" placeholder="분" style="width: 100px;" v-model="editData.endMnt" readonly />
                </div>
              </td>
            </tr>
            <tr>
              <th scope="row">사용 휴가일</th>
              <td>
                <input type="text" class="form-control sm" v-model="totalDays" readonly />
              </td>
            </tr>
            <tr>
              <th scope="row">
                승인자 <span class="require"><img :src="require" alt=""></span>
              </th>
              <td>
                <button type="button" title="추가" @click="isOpenModal = true">
                  <PlusCircleFilled />
                </button>
                <HrPopup v-if="isOpenModal" :lists="editData.sanctnList" @onSelected="fnAddSanctn" @close="isOpenModal = false" />
                <div class="approval-container">
                  <SanctnList v-model:lists="editData.sanctnList" @delSanctn="fnDelSanctn" />
                </div>
              </td>
            </tr>
            <tr>
              <th scope="row">세부사항</th>
              <td>
                <EditorComponent v-model:contents="editData.detailCn" />
              </td>
            </tr>
          </tbody>
        </table>
      </div>

      <div class="buttons">
        <button type="button" class="btn sm btn-red" @click="fnRecord">이전 승인자 불러오기</button>
        <button type="button" class="btn sm primary" @click="fnSave">신청</button>
        <button type="button" class="btn sm 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: null,
        deptId: null,
        clsf: null,
        bgnde: null,
        beginHour: null,
        beginMnt: null,
        endde: null,
        endHour: null,
        endMnt: null,
        detailCn: null,
        confmAt: null,
        rgsde: null,
        register: null,
        updde: null,
        updusr: null,
        sanctnList: []
      },
      dayCnt: 0,
      totalDays: 0,
      workConfig: {
        startHour: 9,    // 근무 시작 시간
        endHour: 18,     // 근무 종료 시간
        lunchStart: 12,  // 점심 시작 시간
        lunchEnd: 13,    // 점심 종료 시간
      },

      vcatnKnds: [],
      halfDaySubTypes: [],
      vcatnSubKnd: null,

      sanctnCodes: [],
    };
  },

  computed: {
    showSubTypeSelect() {
      return this.dayCnt === 0.5;
    },

    // 현재 선택된 유형이 반차 하위 유형인지 확인
    isHalfDaySubType() {
      return this.halfDaySubTypes.some(item => item.code === this.editData.vcatnKnd);
    }
  },

  async created() {
    this.pageId = this.$route.query.id;

    // 휴가 유형 조회
    this.vcatnKnds = []; // 초기화
    let halfDaySubTypes = [];
    const vcatnKndCodes = await this.$findChildCodes('sanctn_mby_vcatn');
    for (const code of vcatnKndCodes) {
      const childCodes = await this.$findChildCodes(code.code);
      for (const childCode of childCodes) {
        if (parseFloat(childCode.codeValue) === 0.5) {
          // 반차(0.5)인 경우 해당 유형은 제외하고 하위 코드만 추가
          const subTypes = await this.$findChildCodes(childCode.code);
          this.vcatnKnds.push(...subTypes);
          halfDaySubTypes.push(...subTypes);
        } else {
          // 반차가 아닌 경우 그대로 추가
          this.vcatnKnds.push(childCode);
        }
      }
    }
    this.halfDaySubTypes = halfDaySubTypes;

    if (this.vcatnKnds.length > 0) {
      this.editData.vcatnKnd = this.vcatnKnds[0].code;
    }

    // 결재 구분
    this.sanctnCodes = await this.$findChildCodes('sanctn_code');

    // 상세 조회 (pageId가 있는 경우)
    if (!this.$isEmpty(this.pageId)) {
      await this.findData();
    }
  },

  mounted() { },

  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];

        await this.$nextTick();
        await this.fnOnchangeVcatnKnd();

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

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

      // 반차 하위 유형인지 확인
      if (this.isHalfDaySubType) {
        this.dayCnt = 0.5;
        this.setHalfDayTime(selectedVcatn);
        this.changeBgnde(); // 반차일 경우 종료일을 시작일과 동일하게 설정
      } else {
        this.dayCnt = parseFloat(selectedVcatn.codeValue);

        // 전체 근무시간으로 설정
        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();
      }
    },

    // 반차 시간 설정 메서드
    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 = {
        sanctnId: null,                                   // 결재 아이디
        confmerId: user.userId,                           // 승인자 아이디
        clsf: user.clsf,                                  // 직급
        sanctnOrdr: this.editData.sanctnList.length + 1,  // 결재 순서
        sanctnIem: this.editData.vcatnKnd,                // 결재 항목
        sanctnMbyId: null,                                // 결재 주체 아이디
        sanctnSe: this.sanctnCodes[0].code,               // 결재구분

        confmerNm: user.userNm,                           // 승인자 이름
        clsfNm: user.clsfNm,                              // 직급 이름
      };

      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;
      });
    },

    // 이전 승인자 조회
    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;
      }

      return true;
    },

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

        // 데이터 세팅
        let data = this.editData;
        if (!this.$isEmpty(this.pageId)) {
          data.confmAt = 'W';
        }

        const response = this.$isEmpty(this.pageId) ? await saveVcatnProc(data) : await updateVcatnProc(data);
        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>