<template>
  <div class="content">
    <div class="sub-title-area mb-30">
      <h2>사진 기록물</h2>
      <div class="breadcrumb-list">
        <ul>
          <li>
            <img :src="homeicon" alt="Home Icon">
            <p>기록물</p>
          </li>
          <li><img :src="righticon" alt=""></li>
          <li>사진 기록물</li>
        </ul>
      </div>
    </div>
    <form class="insert-form mb-50" @submit.prevent>
      <dl>
        <dd>
          <label for="sj" class="require">제목</label>
          <div class="wfull"><input type="text" id="sj" placeholder="제목을 입력하세요." v-model="requestDTO.sj"></div>
        </dd>
        <div class="hr"></div>
        <dd>
          <label for="prdctnYear">생산연도</label>
          <input type="text" id="prdctnYear" placeholder="생산연도를 입력하세요" v-model="requestDTO.prdctnYear" pattern="[0-9]{4}" maxlength="4" @input="onlyNumberInput">
        </dd>
        <div class="hr"></div>
        <dd>
          <label for="adres">주소</label>
          <div class="wfull"><input type="text" id="adres" placeholder="주소를 입력하세요" v-model="requestDTO.adres"></div>
        </dd>
        <div class="hr"></div>
        <dd>
          <label for="text">내용</label>
          <div class="wfull">
            <EditorComponent v-model:contents="requestDTO.cn" />
          </div>
        </dd>
        <div class="hr"></div>
        <dd>
          <label for="category" class="flex align-center">
            <p>카테고리</p><button type="button" class="category-add" @click="fnToggleModal">추가하기</button>
          </label>
          <ul class="category">
            <li v-for="(item, idx) of selectedCtgries" :key="idx">{{ item.ctgryNm }} <button type="button" class="cancel" @click="fnDelCtgry(item.ctgryId)"><b>✕</b></button></li>
          </ul>
        </dd>
        <div class="hr"></div>
        <dd>
          <label for="file" class="require">파일</label>
          <ul class="wfull">
            <li class="flex align-center">
              <p>파일첨부</p>
              <div class="invalid-feedback"><img :src="erroricon" alt=""><span>첨부파일은 건당 최대 10GB를 초과할 수 없습니다.</span>
              </div>
            </li>
            <li class="file-insert">
              <input type="file" id="fileInput" class="file-input" multiple accept="image/jpeg,image/png,image/gif,image/jpg" @change="handleFileSelect">
              <label for="fileInput" class="file-label mb-20" @dragover.prevent="handleDragOver" @dragleave.prevent="handleDragLeave" @drop.prevent="handleDrop" :class="{ 'drag-over': isDragging }">
                <div class="flex-center align-center">
                  <img :src="fileicon" alt="">
                  <p>파일첨부하기</p>
                </div>
                <p>파일을 첨부하시려면 이 영역으로 파일을 끌고 오거나 클릭해주세요</p>
              </label>
              <p class="mb-10">파일목록</p>
              <div id="fileNames" class="file-names">
                <div v-if="requestDTO.files.length === 0 && multipartFiles.length === 0">선택된 파일이 없습니다.</div>
                <!-- 기존 등록된 파일 목록 -->
                <div v-for="(file, idx) of requestDTO.files" :key="idx" class="mb-5">
                  <input type="radio" name="thumbAt" :id="'oldFile_' + file.fileOrdr" v-model="selectedThumb" :value="file.fileNm">
                  <label :for="'oldFile_' + file.fileOrdr">
                    <p>썸네일여부</p>
                    <div class="flex-sp-bw file-wrap">
                      <div class="file-name">
                        <img src="/client/resources/images/icon/imgicon.png" alt="fileicon">
                        <p>{{ file.fileNm }}</p>
                      </div>
                      <button type="button" class="cancel" @click="fnDelFile('old', file.fileOrdr)"><b>✕</b></button>
                    </div>
                  </label>
                </div>
                <!-- 새로 추가된 파일 목록 -->
                <div v-for="(file, idx) of multipartFiles" :key="idx" class="mb-5">
                  <input type="radio" name="thumbAt" :id="'newFile_' + idx" v-model="selectedThumb" :value="file.name">
                  <label :for="'newFile_' + idx">
                    <p>썸네일여부</p>
                    <div class="flex-sp-bw file-wrap">
                      <div class="file-name">
                        <img src="/client/resources/images/icon/imgicon.png" alt="fileicon">
                        <p>{{ file.name }}</p>
                      </div>
                      <button type="button" class="cancel" @click="fnDelFile('new', idx)"><b>✕</b></button>
                    </div>
                  </label>
                </div>
              </div>
            </li>
          </ul>
        </dd>
      </dl>
    </form>
    <div class="btn-group flex-center">
      <button type="button" class="cancel" @click="fnMoveTo('list')">취소</button>
      <button type="button" class="register" @click="submitForm">
        <span v-if="$isEmpty(pageId)">등록</span>
        <span v-else>수정</span>
      </button>
    </div>
  </div>
  <CategorySelectModal v-if="isModalOpen" :selectedCtgries="selectedCtgries" @toggleModal="fnToggleModal" @addCtgries="fnAddCtgries" />
</template>
<script>
import { DoubleLeftOutlined, LeftOutlined, RightOutlined, DoubleRightOutlined } from '@ant-design/icons-vue';
// COMPONENT
import EditorComponent from '../../../component/editor/EditorComponent.vue';
import CategorySelectModal from '../../../component/modal/CategorySelectModal.vue';
// API
import { findDcryProc, saveDcry, updateDcry } from '@/resources/api/dcry';

export default {
  components: {
    DoubleLeftOutlined,
    LeftOutlined,
    RightOutlined,
    DoubleRightOutlined,
    EditorComponent,
    CategorySelectModal,
  },

  data() {
    return {
      // 아이콘 경로
      homeicon: 'client/resources/images/icon/home.png',
      erroricon: 'client/resources/images/icon/error.png',
      righticon: 'client/resources/images/icon/right.png',
      fileicon: 'client/resources/images/icon/file.png',
      searchicon: 'client/resources/images/icon/search.png',

      pageId: null,

      isModalOpen: false,
      isDragging: false,

      fileNames: [],

      // 등록/수정 요청 객체
      requestDTO: {
        dcryId: null,
        sj: null,
        cn: null,
        adres: null,
        prdctnYear: null,
        ty: 'P',
        fileId: null,
        files: [],
        ctgryIds: [],
      },

      multipartFiles: [],
      selectedCtgries: [], // 카테고리 목록

      selectedThumb: null,
    };
  },

  created() {
    this.pageId = this.$route.query.id;
    if (!this.$isEmpty(this.pageId)) {
      this.fnFindDcry(); // 상세 조회
    }
  },

  methods: {
    // 상세 조회
    async fnFindDcry() {
      try {
        const response = await findDcryProc(this.pageId);

        if (response.data.data.dcry.ty !== 'P') {
          alert('올바른 접근이 아닙니다.');
          this.fnMoveTo('list'); // 목록으로 이동
        }

        this.copyToDcryReqDTO(response.data.data.dcry);
      } catch (error) {
        alert('조회중 오류가 발생했습니다.');
        this.fnMoveTo('list'); // 목록으로 이동

        if (error.response) {
          alert(error.response.data.message);
        }
        console.error(error.message);
      }
    },

    // dcry > requestDTO
    copyToDcryReqDTO(dcry) {
      const copyFields = Object.keys(this.requestDTO).filter(key => key !== 'dcryId' && key !== 'ty' && key !== 'files');
      copyFields.forEach(field => {
        this.requestDTO[field] = this.$isEmpty(dcry[field]) ? null : dcry[field];
      });

      this.requestDTO.ty = 'P'; // 사진기록물
      this.requestDTO.files = dcry.files.length > 0 ? dcry.files : []; // 기존 첨부파일

      this.multipartFiles = [];
      this.selectedCtgries = dcry.ctgrys.length > 0 ? dcry.ctgrys : [];

      // 썸네일
      const thumbFile = this.requestDTO.files.find(f => f.thumbAt === 'Y');
      if (thumbFile) {
        this.selectedThumb = thumbFile.fileNm;
      }

      console.log(this.requestDTO);
    },

    // 카테고리 모달 열기/닫기
    fnToggleModal() {
      this.isModalOpen = !this.isModalOpen;
    },

    // 카테고리 등록
    fnAddCtgries(selectedCtgries) {
      this.selectedCtgries = [...this.selectedCtgries, ...selectedCtgries];

      this.fnToggleModal(); // 카테고리 모달 닫기
    },

    // 카테고리 삭제
    fnDelCtgry(id) {
      this.selectedCtgries = this.selectedCtgries.filter(item => item.ctgryId !== id);
    },

    // 드래그 앤 드롭 이벤트 핸들러
    handleDragOver(event) {
      this.isDragging = true;
    },
    handleDragLeave(event) {
      this.isDragging = false;
    },
    handleDrop(event) {
      this.isDragging = false;

      const files = event.dataTransfer.files;
      if (files.length > 0) {
        this.processFiles(files);
      }
    },
    handleFileSelect(event) {
      const files = event.target.files;
      if (files.length > 0) {
        this.processFiles(files);
      }
    },

    // 파일 업로드 처리 함수
    processFiles(files) {
      const allowedTypes = ['jpg', 'jpeg', 'png', 'gif']; // 이미지 파일만 허용
      const maxSize = 10 * 1024 * 1024 * 1024; // 10GB

      // 중복 파일 확인을 위한 Map (키: 파일명+확장자(소문자), 값: 원본 파일명)
      const existingFilesMap = new Map();

      // 기존 업로드된 파일 정보 추가
      this.requestDTO.files.forEach(file => {
        const fullName = file.fileNm.toLowerCase();
        existingFilesMap.set(fullName, file.fileNm);
      });

      // 새로 추가된 파일 정보 추가
      this.multipartFiles.forEach(file => {
        existingFilesMap.set(file.name.toLowerCase(), file.name);
      });

      for (let file of files) {
        const fileNameLower = file.name.toLowerCase();
        const fileExtension = fileNameLower.split('.').pop();

        // 파일명+확장자 중복 검증 (대소문자 무시하고 비교)
        if (existingFilesMap.has(fileNameLower)) {
          alert("파일 목록에 이미 동일한 파일 명을 가진 파일이 있습니다. 동일한 이름을 가진 파일은 업로드할 수 없습니다.");
          continue;
        }

        // 파일 타입 검증
        if (!allowedTypes.includes(fileExtension)) {
          alert("이미지 파일(jpg, jpeg, png, gif)만 업로드 가능합니다.");
          continue;
        }

        // 파일 크기 제한 검증
        if (file.size > maxSize) {
          alert(`${file.name} 파일이 10GB를 초과합니다.`);
          continue;
        }

        this.multipartFiles.push(file);
        existingFilesMap.set(fileNameLower, file.name);

        // 최초 등록 시 썸네일로 설정
        if (this.requestDTO.files.length < 1 && this.multipartFiles.length > 0) {
          this.selectedThumb = this.multipartFiles[0].name;
        }
      }
    },

    // 파일 삭제
    fnDelFile(type, separator) {
      if (type === 'new') {
        this.multipartFiles.splice(separator, 1);
      } else if (type === 'old') {
        this.requestDTO.files = this.requestDTO.files.filter(item => item.fileOrdr !== separator);
      }

      // 썸네일 변경
      if (this.requestDTO.files.length < 1 && this.multipartFiles.length > 0) {
        this.selectedThumb = this.multipartFiles[0].name;
      }
    },

    // 등록
    async submitForm() {
      // 유효성 검사
      if (this.$isEmpty(this.requestDTO.sj)) {
        alert("제목을 입력해 주세요.");
        return;
      }
      if (!this.$isEmpty(this.requestDTO.prdctnYear)) {
        if (!/^\d+$/.test(this.requestDTO.prdctnYear)) {
          alert("생산연도는 숫자만 입력 가능합니다.");
          return;
        }
        if (this.requestDTO.prdctnYear.length !== 4) {
          alert("생산연도는 4자리로 입력해주세요.");
          return;
        }
      }

      let count = this.multipartFiles.length
      if (!this.$isEmpty(this.pageId)) {
        count += this.requestDTO.files.length
      }
      if (count == 0) {
        alert("파일을 1개 이상 첨부해 주세요.");
        return;
      }

      try {
        const formData = new FormData();

        // 텍스트 데이터 추가
        formData.append('sj', this.requestDTO.sj);
        formData.append('ty', this.requestDTO.ty);

        // 게시물 아이디
        if (!this.$isEmpty(this.pageId)) {
          formData.append('dcryId', this.pageId);
        }

        if (!this.$isEmpty(this.requestDTO.prdctnYear)) {
          formData.append('prdctnYear', this.requestDTO.prdctnYear);
        }

        if (!this.$isEmpty(this.requestDTO.adres)) {
          formData.append('adres', this.requestDTO.adres);
        }

        if (!this.$isEmpty(this.requestDTO.cn)) {
          formData.append('cn', this.requestDTO.cn);
        }

        // 파일 아이디
        if (!this.$isEmpty(this.requestDTO.fileId)) {
          formData.append('fileId', this.requestDTO.fileId);
        }

        // 카테고리 Ids 추가
        if (this.selectedCtgries && this.selectedCtgries.length > 0) {
          for (let ctgry of this.selectedCtgries) {
            formData.append("ctgryIds", ctgry.ctgryId);
          }
        }

        // 파일 추가
        if (this.multipartFiles.length > 0) {
          for (let file of this.multipartFiles) {
            formData.append("multipartFiles", file);
          }
        }

        // 기존파일 수정
        if (!this.$isEmpty(this.pageId) && this.requestDTO.files.length > 0) {
          for (let file of this.requestDTO.files) {
            formData.append("files", file.fileOrdr);
          }
        }

        // 썸네일 정보 추가
        if (this.selectedThumb !== null) {
          formData.append('selectedThumb', this.selectedThumb);
        }

        // API 통신
        const response = this.$isEmpty(this.pageId) ? await saveDcry(formData) : await updateDcry(formData);
        let id = response.data.data.dcryId;
        alert(this.$isEmpty(this.pageId) ? "등록되었습니다." : "수정되었습니다.");

        // 상세 페이지로 이동
        this.fnMoveTo('view', id);
      } catch (error) {
        if (error.response) {
          alert(error.response.data.message);
        } else {
          alert("에러가 발생했습니다.");
        }
        console.error(error.message);
      };
    },

    // 페이지 이동
    fnMoveTo(type, id) {
      const routes = {
        'list': { name: 'PicHistorySearch' },
        'view': { name: 'PicHistoryDetail', query: { id } },
        'edit': { name: 'PicHistoryInsert', query: this.$isEmpty(id) ? {} : { id } },
      };

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

    // 생산연도 입력 제한
    onlyNumberInput() {
      this.requestDTO.prdctnYear = this.requestDTO.prdctnYear.replace(/[^0-9]/g, '');
    }
  }
};
</script>
<style>
.file-label {
  border: 2px dashed #ddd;
  border-radius: 8px;
  padding: 20px;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s ease;
}

.file-label:hover {
  border-color: #aaa;
  background-color: #f9f9f9;
}

.file-label.drag-over {
  border-color: #1890ff;
  background-color: rgba(24, 144, 255, 0.1);
}
</style>