<template>
  <div class="card">
    <div class="card-body">
      <h2 class="card-title">출장 신청</h2>
      <p class="require">* 필수입력</p>
      <div class="tbl-wrap">
        <table class="tbl data">
          <tbody>
            <tr>
              <th>출장구분 *</th>
              <td>
                <select class="form-select sm" style="width: 110px;" v-model="bsrpInfo.bsrpSe">
                  <option v-for="(item, idx) of bsrpCodes" :key="idx" :value="item.code"> {{ item.codeNm }} </option>
                </select>
              </td>
              <th>일수</th>
              <td>
                <input type="text" class="form-control sm" v-model="totalDays" readonly />
              </td>
            </tr>
            <tr>
              <th>출장지 *</th>
              <td>
                <input type="text" class="form-control sm" v-model="bsrpInfo.bsrpPlace" />
              </td>
              <th>출장목적 *</th>
              <td>
                <input type="text" class="form-control sm" v-model="bsrpInfo.bsrpPurps" />
              </td>
            </tr>
            <tr>
              <th>출장기간 *</th>
              <td colspan="3">
                <div class="d-flex">
                  <div class="d-flex gap-1 mb-1">
                    <input type="date" class="form-control sm" v-model="bsrpInfo.bgnde" />
                    <input type="text" class="form-control sm" style="width: 100px;" placeholder="시" v-model="bsrpInfo.beginHour" maxlength="2" @input="validateHour('beginHour', $event)" />
                    <input type="text" class="form-control sm" style="width: 100px;" placeholder="분" v-model="bsrpInfo.beginMnt" maxlength="2" @input="validateMinute('beginMnt', $event)" />
                  </div>
                  <div class="d-flex gap-1">
                    <input type="date" class="form-control sm" v-model="bsrpInfo.endde" />
                    <input type="text" class="form-control sm" style="width: 100px;" placeholder="시" v-model="bsrpInfo.endHour" maxlength="2" @input="validateHour('endHour', $event)" />
                    <input type="text" class="form-control sm" style="width: 100px;" placeholder="분" v-model="bsrpInfo.endMnt" maxlength="2" @input="validateMinute('endMnt', $event)" />
                  </div>
                </div>
              </td>
            </tr>
            <tr>
              <th>동행자</th>
              <td>
                <button type="button" title="추가" @click="isOpenNmprModal = true">
                  <PlusCircleFilled />
                </button>
                <HrPopup v-if="isOpenNmprModal" :selectedEmployees="bsrpInfo.bsrpNmprList" idField="triperId" :dateInfo="bsrpInfo" @select="handleCompanionAdd" @close="isOpenNmprModal = false" />
                <div class="approval-container">
                  <div v-for="(item, idx) of bsrpInfo.bsrpNmprList" :key="idx" class="d-flex addapproval">
                    <div class="d-flex align-items-center border-x">
                      <p>{{ item.triperNm }} {{ item.clsfNm }}</p>
                      <button type="button" @click="handleCompanionRemove(idx)" @mousedown.stop>
                        <CloseOutlined />
                      </button>
                    </div>
                  </div>
                </div>
              </td>
              <th>승인자 *</th>
              <td>
                <button type="button" title="추가" @click="isOpenSanctnModal = true">
                  <PlusCircleFilled />
                </button>
                <HrPopup v-if="isOpenSanctnModal" :selectedEmployees="bsrpCnsul.sanctnList" idField="confmerId" @select="handleApproverAdd" @close="isOpenSanctnModal = false" />
                <div class="approval-container">
                  <SanctnList v-model:lists="bsrpCnsul.sanctnList" @delSanctn="handleApproverRemove" />
                </div>
              </td>
            </tr>
            <tr>
              <th>품의내용 *</th>
              <td colspan="3" style="height: calc(100% - 550px);">
                <EditorComponent v-model:contents="bsrpCnsul.cn" />
              </td>
            </tr>
            <tr>
              <th>법인카드</th>
              <td>
                <button type="button" title="추가" @click="isOpenCardModal = true">
                  <PlusCircleFilled />
                </button>
                <CorpCardPopup v-if="isOpenCardModal" :bsrpInfo="bsrpInfo" :lists="cards" @close="isOpenCardModal = false" @onSelected="handleCardAdd" />
                <div class="approval-container">
                  <div v-for="(card, idx) in cards" :key="idx" class="d-flex gap-2 addapproval mb-2">
                    <form class="d-flex align-items-center border-x">
                      <p>{{ card.cardNm }}</p>
                      <button type="button" @click="handleCardRemove(idx)" class="delete-button">
                        <CloseOutlined />
                      </button>
                    </form>
                  </div>
                </div>
              </td>
              <th>법인차량</th>
              <td>
                <button type="button" title="추가" @click="isOpenVhcleModal = true">
                  <PlusCircleFilled />
                </button>
                <CorpCarPopup v-if="isOpenVhcleModal" :bsrpInfo="bsrpInfo" :lists="vhcles" @close="isOpenVhcleModal = false" @onSelected="handleVehicleAdd" />
                <div class="approval-container">
                  <div v-for="(vhcle, idx) in vhcles" :key="idx" class="d-flex gap-2 addapproval mb-2">
                    <p>{{ vhcle.vhcleNm }}</p>
                    <select class="form-select" v-model="vhcle.drverId">
                      <option value="" disabled hidden>운전자 선택</option>
                      <option :value="userInfo.userId">{{ userInfo.userNm }}</option>
                      <option v-for="(item, idx) of bsrpInfo.bsrpNmprList" :key="idx" :value="item.userId"> {{ item.userNm }} </option>
                    </select>
                    <button type="button" @click="handleVehicleRemove(idx)" class="delete-button">
                      <CloseOutlined />
                    </button>
                  </div>
                </div>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
      <div class="buttons">
        <button type="button" class="btn sm btn-red" @click="handleLoadLastApprovers">이전 승인자 불러오기</button>
        <button type="button" class="btn sm primary" v-if="$isEmpty(pageId)" @click="handleSave">신청</button>
        <template v-else>
          <button type="button" class="btn sm primary" v-if="isReapplyMode" @click="handleReapply">재신청</button>
          <button type="button" class="btn sm primary" v-else @click="handleUpdate">수정</button>
          <button type="button" class="btn sm secondary" @click="handleCancel">취소</button>
        </template>
      </div>
    </div>
  </div>
</template>
<script>
import { PlusCircleFilled, CloseOutlined } from '@ant-design/icons-vue';
import HrPopup from '../../../component/Popup/HrPopup.vue';
import CorpCarPopup from '../../../component/Popup/CorpCarPopup.vue';
import CorpCardPopup from '../../../component/Popup/CorpCardPopup.vue';
import SanctnList from '../../../component/Sanctn/SanctnFormList.vue';
import EditorComponent from '../../../component/editor/EditorComponent.vue';
// API
import { saveBsrpProc, findBsrpProc, updateBsrpProc, findLastBsrpCnsulProc, reapplyBsrpProc } from '../../../../resources/api/bsrp';

export default {
  name: 'BsrpInsert',

  components: {
    PlusCircleFilled, CloseOutlined,
    HrPopup, CorpCarPopup, CorpCardPopup, SanctnList, EditorComponent,
  },

  data() {
    return {
      pageId: null,
      pageMode: null,
      userInfo: this.$store.state.userInfo,
      isOpenNmprModal: false,
      isOpenSanctnModal: false,
      isOpenCardModal: false,
      isOpenVhcleModal: false,
      bsrpCodes: [],
      sanctnCodes: [],
      defaultSanctnCode: null,
      bsrpInfo: {
        bsrpId: null,
        applcntId: null,
        bsrpSe: null,
        bsrpSeNm: null,
        bsrpPlace: null,
        bsrpPurps: null,
        bgnde: null,
        beginHour: null,
        beginMnt: null,
        endde: null,
        endHour: null,
        endMnt: null,
        bsrpNmprList: []
      },
      cards: [],
      vhcles: [],
      bsrpCnsul: {
        bsrpId: null,
        cn: null,
        rgsde: null,
        register: null,
        updde: null,
        updusr: null,
        sanctnList: []
      },
      totalDays: 0,
    };
  },

  watch: {
    // 시작일 변동 시 날짜 재계산
    'bsrpInfo.bgnde'() {
      this.calculateDays();
    },
    // 종료일 변동 시 날짜 재계산
    'bsrpInfo.endde'() {
      this.calculateDays();
    },
  },

  computed: {
    // 재신청 여부
    isReapplyMode() {
      return this.pageMode === 'reapply';
    },
  },

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

    this.bsrpCodes = await this.$findChildCodes('sanctn_mby_bsrp'); // 출장 구분 코드 조회
    this.bsrpInfo.bsrpSe = this.bsrpCodes[0].code;

    this.sanctnCodes = await this.$findChildCodes('sanctn_code'); // 결재 구분 코드 조회
    this.defaultSanctnCode = this.sanctnCodes[0].code;
  },

  mounted() {
    if (!this.$isEmpty(this.pageId)) {
      this.fetchData(); // 출장 정보 조회
    }
  },

  methods: {
    // 출장 정보 조회
    async fetchData() {
      try {
        const response = await findBsrpProc(this.pageId);
        const result = response.data.data;

        this.bsrpInfo = result.bsrpInfoDTO;
        this.cards = result.cards;
        this.vhcles = result.vhcles;
        this.bsrpCnsul = result.bsrpCnsulDTO;
      } catch (error) {
        alert(error.response.data.message);
        this.handleNavigation('list');
      }
    },

    // 이전 승인자 조회 핸들러
    async handleLoadLastApprovers() {
      try {
        const response = await findLastBsrpCnsulProc();
        const result = response.data.data;

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

    // 저장 핸들러
    async handleSave() {
      try {
        if (!this.validateForm()) {
          return;
        }

        let data = this.buildSendData("insert");

        const response = await saveBsrpProc(data);
        alert("등록되었습니다.");

        this.handleNavigation('view', response.data.data.pageId);
      } catch (error) {
        this.handleError(error);
      }
    },

    // 수정 핸들러
    async handleUpdate() {
      try {
        if (!this.validateForm()) {
          return;
        }

        let data = this.buildSendData("update");

        const response = await updateBsrpProc(this.pageId, data);
        alert("수정되었습니다.");

        this.handleNavigation('view', response.data.data.pageId);
      } catch (error) {
        this.handleError(error);
      }
    },

    // 재신청 핸들러
    async handleReapply() {
      try {
        if (!this.validateForm()) {
          return;
        }

        let data = this.buildSendData("insert");

        const response = await reapplyBsrpProc(this.pageId, data);
        alert("재신청되었습니다.");

        this.handleNavigation('view', response.data.data.pageId);
      } catch (error) {
        this.handleError(error);
      }
    },

    // 동행자 추가 핸들러
    handleCompanionAdd(item) {
      const data = {
        triperId: item.userId,
        triperNm: item.userNm,
        deptId: item.deptId,
        deptNm: item.deptNm,
        clsf: item.clsf,
        clsfNm: item.clsfNm,
      };

      this.bsrpInfo.bsrpNmprList.push(data);
      this.isOpenNmprModal = false;
    },

    // 동행자 삭제 핸들러
    handleCompanionRemove(idx) {
      this.bsrpInfo.bsrpNmprList.splice(idx, 1);
    },

    // 승인자 추가 핸들러
    handleApproverAdd(user) {
      const data = {
        confmerId: user.userId,
        confmerNm: user.userNm,
        clsf: user.clsf,
        clsfNm: user.clsfNm,
        sanctnOrdr: this.bsrpCnsul.sanctnList.length + 1,
        sanctnIem: 'bsrp_cnsul',
        sanctnSe: this.defaultSanctnCode,
      };

      this.bsrpCnsul.sanctnList.push(data);
      this.isOpenSanctnModal = false;
    },

    // 승인자 삭제 핸들러
    handleApproverRemove(idx) {
      this.bsrpCnsul.sanctnList.splice(idx, 1);
      this.bsrpCnsul.sanctnList.forEach((item, index) => {
        item.sanctnOrdr = index + 1;
      });
    },

    // 법인 카드 추가 핸들러
    handleCardAdd(item) {
      this.cards.push(item);
      this.isOpenCardModal = false;
    },

    // 법인 카드 삭제 핸들러
    handleCardRemove(idx) {
      this.cards.splice(idx, 1);
    },

    // 법인 차량 추가 핸들러
    handleVehicleAdd(item) {
      item.drverId = this.userInfo.userId;
      this.vhcles.push(item);
      this.isOpenVhcleModal = false;
    },

    // 법인 차량 삭제 핸들러
    handleVehicleRemove(idx) {
      this.vhcles.splice(idx, 1);
    },

    // 취소 핸들러
    handleCancel() {
      if (confirm('작성 중인 내용이 삭제됩니다. 계속하시겠습니까?')) {
        this.handleNavigation('view', this.pageId);
      }
    },

    // 페이지 이동 핸들러
    handleNavigation(type, id) {
      const routeMap = {
        'list': { name: 'BsrpListPage' },
        'view': { name: 'BsrpViewPage', query: { id } },
        'bsrpInsert': { name: 'BsrpInsertPage', query: this.$isEmpty(id) ? {} : { id } },
        'bsrpReapply': { name: 'BsrpInsertPage', query: { id, type: 'reapply' } },
        'bsrpRportInsert': { name: 'BsrpRportInsertPage', query: this.$isEmpty(id) ? {} : { id } },
        'bsrpRportReapply': { name: 'BsrpRportInsertPage', query: { id, type: 'reapply' } },
      };

      const route = routeMap[type];
      if (route) {
        this.$router.push(route);
      } else {
        alert("올바르지 않은 경로를 요청하여 목록으로 이동합니다.");
        this.$router.push({ name: 'BsrpListPage' });
      }
    },

    // 에러 핸들러
    handleError(error) {
      const message = error.response?.data?.message || "에러가 발생했습니다.";
      alert(message);
    },

    // 일수 계산 유틸리티
    calculateDays() {
      if (!this.bsrpInfo.bgnde || !this.bsrpInfo.endde) {
        this.totalDays = 0;
        return;
      }

      const startDate = new Date(this.bsrpInfo.bgnde);
      const endDate = new Date(this.bsrpInfo.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;

      this.totalDays = Math.max(0, dayDiff);
    },

    // 출장 시간 유효성 검사 유틸리티
    validateHour(field, event) {
      let value = event.target.value.replace(/[^0-9]/g, '');

      if (value.length > 0) {
        const hour = parseInt(value);
        if (hour > 23) {
          value = '23';
        }
      }

      this.bsrpInfo[field] = value;
    },

    // 출장 분 유효성 검사 유틸리티
    validateMinute(field, event) {
      let value = event.target.value.replace(/[^0-9]/g, '');

      if (value.length > 0) {
        const minute = parseInt(value);
        if (minute > 59) {
          value = '59';
        }
      }

      this.bsrpInfo[field] = value;
    },

    // 입력값 전체 유효성 검사 유틸리티
    validateForm() {
      if (this.$isEmpty(this.bsrpInfo.bsrpSe)) {
        alert('출장구분을 선택해주세요.');
        return false;
      }

      if (this.$isEmpty(this.bsrpInfo.bsrpPlace)) {
        alert('출장지를 입력해주세요.');
        return false;
      }

      if (this.$isEmpty(this.bsrpInfo.bsrpPurps)) {
        alert('출장목적을 입력해주세요.');
        return false;
      }

      if (this.$isEmpty(this.bsrpInfo.bgnde) || this.$isEmpty(this.bsrpInfo.beginHour) || this.$isEmpty(this.bsrpInfo.beginMnt)) {
        alert('출장 시작일시를 모두 입력해주세요.');
        return false;
      }

      if (this.$isEmpty(this.bsrpInfo.endde) || this.$isEmpty(this.bsrpInfo.endHour) || this.$isEmpty(this.bsrpInfo.endMnt)) {
        alert('출장 종료일시를 모두 입력해주세요.');
        return false;
      }

      if (!this.validateTimeRange(this.bsrpInfo.beginHour, this.bsrpInfo.beginMnt, '시작')) {
        return false;
      }

      if (!this.validateTimeRange(this.bsrpInfo.endHour, this.bsrpInfo.endMnt, '종료')) {
        return false;
      }

      if (this.$isEmpty(this.bsrpCnsul.sanctnList) || this.bsrpCnsul.sanctnList.length === 0) {
        alert('승인자를 선택해주세요.');
        return false;
      }

      if (this.$isEmpty(this.bsrpCnsul.cn)) {
        alert('품의내용을 입력해주세요.');
        return false;
      }

      return true;
    },

    // 출장 기간 유효성 검사 유틸리티
    validateTimeRange(hour, minute, timeType) {
      const hourNum = parseInt(hour);
      const minuteNum = parseInt(minute);

      if (isNaN(hourNum) || hourNum < 0 || hourNum > 23) {
        alert(`${timeType} 시간은 0-23 사이의 값을 입력해주세요.`);
        return false;
      }

      if (isNaN(minuteNum) || minuteNum < 0 || minuteNum > 59) {
        alert(`${timeType} 분은 0-59 사이의 값을 입력해주세요.`);
        return false;
      }

      return true;
    },

    // 데이터 가공 유틸리티
    buildSendData(type) {
      let bsrpInfo = {
        applcntId: this.bsrpInfo.applcntId,
        bsrpSe: this.bsrpInfo.bsrpSe,
        bsrpPlace: this.bsrpInfo.bsrpPlace,
        bsrpPurps: this.bsrpInfo.bsrpPurps,
        bgnde: this.bsrpInfo.bgnde,
        beginHour: this.bsrpInfo.beginHour,
        beginMnt: this.bsrpInfo.beginMnt,
        endde: this.bsrpInfo.endde,
        endHour: this.bsrpInfo.endHour,
        endMnt: this.bsrpInfo.endMnt,
        bsrpNmprList: this.bsrpInfo.bsrpNmprList,
      }

      let cards = [];
      for (let card of this.cards) {
        cards.push({
          cardId: card.cardId,
        })
      }

      let vhcles = [];
      for (let vhcle of this.vhcles) {
        vhcles.push({
          vhcleId: vhcle.vhcleId,
          drverId: vhcle.drverId,
        })
      }

      let sanctnList = [];
      for (let sanctn of this.bsrpCnsul.sanctnList) {
        sanctnList.push({
          confmerId: sanctn.confmerId,
          clsf: sanctn.clsf,
          sanctnOrdr: sanctn.sanctnOrdr,
          sanctnIem: sanctn.sanctnIem,
          sanctnSe: sanctn.sanctnSe,
        })
      }

      let bsrpCnsul = {
        cn: this.bsrpCnsul.cn,
        sanctnList: sanctnList,
      }

      if (type === "insert") {
        return {
          insertBsrpInfoDTO: bsrpInfo,
          cardDtlsList: cards,
          vhcleDtlsList: vhcles,
          insertBsrpCnsulDTO: bsrpCnsul,
        };
      } else if (type === "update") {
        return {
          updateBsrpInfoDTO: bsrpInfo,
          cardDtlsList: cards,
          vhcleDtlsList: vhcles,
          updateBsrpCnsulDTO: bsrpCnsul,
        };
      }
    },
  },
};
</script>