<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>{{ bsrpInfo.bsrpSeNm }}</td>
            </tr>
            <tr>
              <th>출장지</th>
              <td>{{ bsrpInfo.bsrpPlace }}</td>
            </tr>
            <tr>
              <th>출장목적</th>
              <td>{{ bsrpInfo.bsrpPurps }}</td>
            </tr>
            <tr>
              <th>출장기간</th>
              <td>{{ $formattedDates(bsrpInfo) }}</td>
            </tr>
            <tr>
              <th>동행자</th>
              <td>
                <span v-for="(item, idx) of bsrpInfo.bsrpNmprList" :key="idx"> {{ item.triperNm }}{{ idx !== bsrpInfo.bsrpNmprList.length - 1 ? ', ' : '' }} </span>
              </td>
            </tr>
            <tr>
              <th>법인카드</th>
              <td>
                <span v-for="(item, idx) of cards" :key="idx">{{ item.cardNm }}</span>
              </td>
            </tr>
            <tr>
              <th>법인차량</th>
              <td>
                <span v-for="(item, idx) of vhcles" :key="idx">{{ item.vhcleNm }}</span>
              </td>
            </tr>
            <tr>
              <th>승인자 *</th>
              <td>
                <button type="button" title="추가" @click="isOpenSanctnModal = true">
                  <PlusCircleFilled />
                </button>
                <HrPopup v-if="isOpenSanctnModal" :selectedEmployees="bsrpRport.sanctnList" idField="confmerId" @select="handleApproverAdd" @close="isOpenSanctnModal = false" />
                <div class="approval-container">
                  <SanctnList v-model:lists="bsrpRport.sanctnList" @delSanctn="handleApproverRemove" />
                </div>
              </td>
            </tr>
            <tr>
              <th>복명내용 *</th>
              <td style="height: calc(100% - 550px);">
                <EditorComponent v-model:contents="bsrpRport.cn" />
              </td>
            </tr>
            <tr>
              <th>여비계산</th>
              <td>
                <button type="button" title="추가" @click="handleExpenseAdd">
                  <PlusCircleFilled />
                </button>
                <div v-for="(item, idx) of bsrpRport.bsrpTrvctList" :key="idx" class="d-flex gap-2 addapproval mb-2">
                  <select class="form-select" v-model="item.se" style="width: 140px;">
                    <option value="" disabled hidden>결제 방식</option>
                    <option v-for="code of trvctTypeCodes" :key="code.code" :value="code.code"> {{ code.codeNm }} </option>
                  </select>
                  <select class="form-select" v-model="item.setleMbyId" style="width: 140px;">
                    <option value="" disabled hidden>결제 주체</option>
                    <template v-if="item.se === 'PERSONAL'">
                      <option :value="userInfo.userId">{{ userInfo.userNm }}</option>
                      <option v-for="nmpr of bsrpInfo.bsrpNmprList" :key="nmpr.userId" :value="nmpr.userId"> {{ nmpr.triperNm }} </option>
                    </template>
                    <template v-else-if="item.se === 'CORPORATE'">
                      <option v-for="card of cards" :key="card.cardId" :value="card.cardId"> {{ card.cardNm }} </option>
                    </template>
                  </select>
                  <select class="form-select" v-model="item.ty" style="width: 140px;">
                    <option value="" disabled hidden>출장비 구분</option>
                    <option v-for="expense of travelExpenseCodes" :key="expense.code" :value="expense.code"> {{ expense.codeNm }} </option>
                  </select>
                  <input type="number" class="form-control" placeholder="금액입력" v-model="item.amount" style="max-width: 150px;" />
                  <div>
                    <label :for="'fileUpload-' + idx" class="btn sm primary">영수증 첨부</label>
                    <input :id="'fileUpload-' + idx" type="file" @change="handleFileUpload(idx, $event)" class="hidden-file-input" accept="image/*,.pdf" />
                    <span v-if="item.fileName" class="file-name">{{ item.fileName }}</span>
                  </div>
                  <button type="button" @click="handleExpenseRemove(idx)" class="delete-button">
                    <CloseOutlined />
                  </button>
                </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="!this.hasBsrpRport" @click="handleSave">신청</button>
        <template v-else>
          <button type="button" class="btn sm primary" @click="handleUpdate"> {{ submitButtonText }} </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 SanctnList from '../../../component/Sanctn/SanctnFormList.vue';
import EditorComponent from '../../../component/editor/EditorComponent.vue';
// API
import { findBsrpProc } from '../../../../resources/api/bsrp';
import { findBsrpRportProc, saveBsrpRportProc, updateBsrpRport, findLastBsrpRportProc } from '../../../../resources/api/bsrpRport';

export default {
  name: 'BsrpRportInsert',

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

  data() {
    return {
      pageId: null,
      pageMode: null,
      userInfo: this.$store.state.userInfo,
      isOpenSanctnModal: false,
      sanctnCodes: [],
      defaultSanctnCode: null,
      trvctTypeCodes: [],
      travelExpenseCodes: [],
      bsrpInfo: {
        bsrpNmprList: []
      },
      cards: [],
      vhcles: [],
      hasBsrpRport: false,
      bsrpRport: {
        cn: null,
        fileId: null,
        bsrpTrvctList: [],
        sanctnList: [],
      },
    };
  },

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

    // 재신청 여부에 따른 등록 버튼 변경
    submitButtonText() {
      return this.isReapplyMode ? '재신청' : '수정';
    }
  },

  async created() {
    this.pageId = this.$route.query.id;
    this.pageMode = this.$route.query.type;
    if (this.$isEmpty(this.pageId)) {
      alert("게시물이 존재하지 않습니다.");
      this.handleNavigation('list');
      return;
    }

    this.sanctnCodes = await this.$findChildCodes('sanctn_code');
    this.defaultSanctnCode = this.sanctnCodes[0]?.code;

    this.trvctTypeCodes = await this.$findChildCodes('BSRP_TRVCT');
    this.travelExpenseCodes = await this.$findChildCodes('TRAVEL_EXPENSE');

  },

  async mounted() {
    await 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.hasBsrpRport = result.hasBsrpRport;

        if (this.hasBsrpRport) {
          this.fetchReportData(); // 출장 복명 정보 조회
        }
      } catch (error) {
        alert('데이터 조회에 실패했습니다.');
        this.handleNavigation('list');
      }
    },

    // 출장 복명 정보 조회
    async fetchReportData() {
      try {
        const response = await findBsrpRportProc(this.pageId);
        const result = response.data.data;

        this.bsrpRport = result;
        if (this.bsrpRport.bsrpTrvctList && this.bsrpRport.fileList) {
          this.bsrpRport.bsrpTrvctList.forEach(trvct => {
            const file = this.bsrpRport.fileList.find(f => f.ordr === trvct.ordr);
            if (file) {
              trvct.fileName = file.fileNm;
              trvct.isExistingFile = true;
            } else {
              this.initializeExpenseFile(trvct);
            }
          });
        }
      } catch (error) {
        alert('데이터 조회에 실패했습니다.');
        this.handleNavigation('list');
      }
    },

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

        if (result == null || result.length == 0) {
          alert("출장 복명 기록이 존재하지 않아, 이전 승인자를 불러올 수 없습니다.");
          return;
        }

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

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

      try {
        const formData = this.buildFormData();

        this.bsrpRport.bsrpTrvctList.forEach(item => {
          if (item.file) {
            formData.append('files', item.file);
          }
        });

        await saveBsrpRportProc(formData);
        alert('출장 복명서가 등록되었습니다.');
        this.handleNavigation('view', this.pageId);
      } catch (error) {
        alert(error.response?.data?.message || '저장에 실패했습니다.');
      }
    },

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

      try {
        const formData = this.buildFormData();

        const oldFiles = [];
        const newFileItems = [];

        this.bsrpRport.bsrpTrvctList.forEach(item => {
          if (item.isExistingFile && item.ordr > 0) {
            oldFiles.push(String(item.ordr));
          } else if (item.file) {
            newFileItems.push(item);
          }
        });

        formData.append('oldFiles', new Blob([JSON.stringify(oldFiles)], { type: 'application/json' }));

        newFileItems.forEach(item => {
          formData.append('files', item.file);
        });

        await updateBsrpRport(formData);
        const message = this.isReapplyMode ? "재신청되었습니다." : "수정되었습니다.";
        alert(message);

        this.handleNavigation('view', this.pageId);
      } catch (error) {
        alert(error.response?.data?.message || '수정에 실패했습니다.');
      }
    },

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

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

    // 여비 계산 추가 핸들러
    handleExpenseAdd() {
      this.bsrpRport.bsrpTrvctList.push({
        se: this.cards.length > 0 ? 'CORPORATE' : 'PERSONAL',
        setleMbyId: this.cards.length > 0 ? this.cards[0].cardId : this.userInfo.userId,
        ty: '',
        amount: null,
        ordr: 0,
        file: null,
        fileName: '',
        isExistingFile: false
      });
    },

    // 여비 계산 삭제 핸들러
    handleExpenseRemove(idx) {
      this.bsrpRport.bsrpTrvctList.splice(idx, 1);
    },

    // 파일 업로드 핸들러
    handleFileUpload(idx, event) {
      const file = event.target.files[0];
      if (!file) return;

      const trvct = this.bsrpRport.bsrpTrvctList[idx];
      trvct.file = file;
      trvct.fileName = file.name;
      trvct.isExistingFile = false;
    },

    // 취소 핸들러
    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(routeMap['list']);
      }
    },

    // 파일 정보 초기화 유틸리티
    initializeExpenseFile(trvct) {
      trvct.ordr = 0;
      trvct.isExistingFile = false;
      trvct.file = null;
      trvct.fileName = '';
    },

    // 입력값 전체 유효성 검사 유틸리티
    validateForm() {
      if (!this.bsrpRport.cn?.trim()) {
        alert('복명내용을 입력해주세요.');
        return false;
      }

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

      for (let [idx, item] of this.bsrpRport.bsrpTrvctList.entries()) {
        const num = idx + 1;
        if (!item.se) {
          alert(`${num}번째 여비계산의 결제 방식을 선택해주세요.`);
          return false;
        }
        if (!item.setleMbyId) {
          alert(`${num}번째 여비계산의 결제 주체를 선택해주세요.`);
          return false;
        }
        if (!item.ty) {
          alert(`${num}번째 여비계산의 출장비 구분을 선택해주세요.`);
          return false;
        }
        if (!item.amount || item.amount <= 0) {
          alert(`${num}번째 여비계산의 금액을 입력해주세요.`);
          return false;
        }
        if (!item.fileName) {
          alert(`${num}번째 여비계산의 영수증을 첨부해주세요.`);
          return false;
        }
      }
      return true;
    },

    // 데이터 가공 유틸리티
    buildFormData() {
      const formData = new FormData();
      formData.append('bsrpId', this.pageId);

      const dto = {
        cn: this.bsrpRport.cn,
        sanctnList: this.bsrpRport.sanctnList.map(s => ({
          confmerId: s.confmerId,
          clsf: s.clsf,
          sanctnOrdr: s.sanctnOrdr,
          sanctnIem: s.sanctnIem,
          sanctnSe: s.sanctnSe,
        })),
        bsrpTrvctList: this.bsrpRport.bsrpTrvctList.map(t => ({
          se: t.se,
          setleMbyId: t.setleMbyId,
          ty: t.ty,
          amount: t.amount,
          ordr: t.ordr || 0,
        }))
      };

      if (this.bsrpRport.fileId) {
        dto.fileId = this.bsrpRport.fileId;
      }

      formData.append('bsrpRportDTO', new Blob([JSON.stringify(dto)], { type: 'application/json' }));
      return formData;
    },
  },
};
</script>