<template>
    <div class="container-xxl flex-grow-1 container-p-y">
        <div class="card">
            <div class="pb-4 rounded-top">
                <div class="container py-12 px-xl-10 px-4" style="padding-bottom: 0px !important">
                    <h3 class="text-center mb-2 mt-4">글 수정</h3>
                </div>
            </div>

            <div class="col-xl-12">
                <div class="card-body">
                    <!-- 제목 입력 -->
                    <FormInput
                        title="제목"
                        name="title"
                        :is-essential="true"
                        :is-alert="titleAlert"
                        v-model="title"
                        @update:alert="titleAlert = $event"
                        @input.once="validateTitle"
                    />

                    <!-- 첨부파일 업로드 -->
                    <FormFile
                        title="첨부파일"
                        name="files"
                        :is-alert="attachFilesAlert"
                        @update:data="handleFileUpload"
                        @update:isValid="isFileValid = $event"
                    />

                    <!-- 실시간 반영된 파일 개수 표시 -->
                    <div>
                        <p class="text-muted mt-1">첨부파일: {{ fileCount }} / 5개</p>
                        <p v-if="fileError" class="text-danger">{{ fileError }}</p>

                        <ul class="list-group mb-2" v-if="attachFiles.length">
                            <li
                                v-for="(file, index) in attachFiles"
                                :key="index"
                                class="list-group-item d-flex justify-content-between align-items-center"
                            >
                                {{ file.name }}
                                <button class="close-btn" @click="removeFile(index, file)">✖</button>
                            </li>
                        </ul>
                    </div>

                    <!-- 내용 입력 -->
                    <div class="mb-4">
                        <label for="html5-tel-input" class="col-md-2 col-form-label">
                            내용
                            <span class="text-danger">*</span>
                        </label>
                        <div class="col-md-12">
                            <QEditor
                                v-if="contentLoaded"
                                @update:data="content = $event"
                                @update:imageUrls="imageUrls = $event"
                                @update:uploadedImgList="handleUpdateEditorImg"
                                @update:deleteImgIndexList="handleDeleteEditorImg"
                                :initialData="content"
                            />
                        </div>
                        <div v-if="contentAlert" class="invalid-feedback d-block">내용을 확인해주세요.</div>
                    </div>

                    <!-- 버튼 -->
                    <div class="mb-4 d-flex justify-content-end">
                        <button type="button" class="btn btn-info right" @click="goBack">
                            <i class="bx bx-left-arrow-alt"></i>
                        </button>
                        <button type="button" class="btn btn-primary ms-1" @click="updateBoard">
                            <i class="bx bx-check"></i>
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
    import QEditor from '@c/editor/QEditor.vue';
    import FormInput from '@c/input/FormInput.vue';
    import FormFile from '@c/input/FormFile.vue';
    import { ref, onMounted, computed, watch, inject } from 'vue';
    import { useRoute, useRouter } from 'vue-router';
    import { useToastStore } from '@s/toastStore';
    import { useBoardAccessStore } from '@s/useBoardAccessStore';
    import axios from '@api';

    // 공통
    const $common = inject('common');
    const toastStore = useToastStore();
    const accessStore = useBoardAccessStore();

    // 상태 변수
    const title = ref('');
    const content = ref('');

    // 경고 상태
    const titleAlert = ref(false);
    const contentAlert = ref(false);
    const contentLoaded = ref(false);

    // 라우터
    const router = useRouter();
    const route = useRoute();
    const currentBoardId = ref(route.params.id); // 라우트에서 ID 가져오기

    // 파일
    const maxFiles = 5;
    const maxSize = 10 * 1024 * 1024;
    const attachFiles = ref([]);
    const fileError = ref('');
    const attachFilesAlert = ref(false);
    const isFileValid = ref(true);
    const delFileIdx = ref([]); // 제외할 기존 첨부파일 ID
    const editorUploadedImgList = ref([]);
    const editorDeleteImgList = ref([]);

    // 게시물 데이터 로드
    const fetchBoardDetails = async () => {
        // 수정 데이터 전송
        let password = accessStore.password;
        const params = {
            password: `${password}` || '',
        };
        //const response = await axios.get(`board/${currentBoardId.value}`);
        const { data } = await axios.post(`board/${currentBoardId.value}`, params);

        if (data.code !== 200) {
            //toastStore.onToast(data.message, 'e');
            alert(data.message, 'e');
            router.back();
            return;
        }
        const boardData = data.data;
        // 기존 첨부파일 추가
        if (boardData.hasAttachment && boardData.attachments.length > 0) {
            attachFiles.value = addDisplayFileName([...boardData.attachments]);
        }

        // 데이터 설정
        title.value = boardData.title || '제목 없음';
        content.value = boardData.content || '내용 없음';
        contentLoaded.value = true;
    };

    const handleUpdateEditorImg = item => {
        editorUploadedImgList.value = item;
    };

    const handleDeleteEditorImg = item => {
        editorDeleteImgList.value = item;
    };

    // 기존 첨부파일명을 노출
    const addDisplayFileName = fileInfos =>
        fileInfos.map(file => ({
            ...file,
            name: `${file.originalName}.${file.extension}`,
        }));

    // 목록 페이지로 이동
    const goList = () => {
        accessStore.$reset();
        router.push('/board');
    };

    // 전 페이지로 이동
    const goBack = () => {
        accessStore.$reset();
        router.back();
    };

    // 유효성 확인
    const checkValidation = () => {
        contentAlert.value = $common.isNotValidContent(content);
        titleAlert.value = $common.isNotValidInput(title.value);

        if (titleAlert.value || contentAlert.value || !isFileValid.value) {
            if (titleAlert.value) {
                title.value = '';
            }
            return true;
        } else {
            return false;
        }
    };

    ////////////////// fileSection[S] ////////////////////
    const fileCount = computed(() => attachFiles.value.length);

    const handleFileUpload = files => {
        const validFiles = files.filter(file => file.size <= maxSize);

        if (files.some(file => file.size > maxSize)) {
            fileError.value = '파일 크기가 10MB를 초과할 수 없습니다.';
            return;
        }
        if (attachFiles.value.length + validFiles.length > maxFiles) {
            fileError.value = `최대 ${maxFiles}개의 파일만 업로드할 수 있습니다.`;
            return;
        }
        fileError.value = '';
        attachFiles.value = [...attachFiles.value, ...validFiles].slice(0, maxFiles);
    };

    const removeFile = (index, file) => {
        if (file.id) delFileIdx.value.push(file.id);

        attachFiles.value.splice(index, 1);
        if (attachFiles.value.length <= maxFiles) {
            fileError.value = '';
        }
    };

    watch(attachFiles, () => {
        isFileValid.value = attachFiles.value.length <= maxFiles;
    });

    const newFileFilter = attachFiles => {
        const copyFiles = [...attachFiles.value];
        return copyFiles.filter(item => !item.id);
    };
    ////////////////// fileSection[E] ////////////////////

    /** `content` 변경 감지하여 자동 유효성 검사 실행 */
    watch(content, () => {
        contentAlert.value = $common.isNotValidContent(content);
    });

    // 글 제목 유효성
    const validateTitle = () => {
        titleAlert.value = title.value.trim().length === 0;
    };

    // 게시물 수정
    const updateBoard = async () => {
        if (checkValidation()) return;

        // 수정 데이터 전송
        const boardData = {
            LOCBRDTTL: title.value.trim(),
            LOCBRDCON: JSON.stringify(content.value),
            LOCBRDSEQ: currentBoardId.value,
        };

        // 업로드 된 첨부파일의 삭제목록
        if (delFileIdx.value && delFileIdx.value.length > 0) {
            boardData.delFileIdx = [...delFileIdx.value];
        }

        // 에디터에 업로드 된 이미지 인덱스 목록
        if (editorUploadedImgList.value && editorUploadedImgList.value.length > 0) {
            boardData.editorUploadedImgList = [...editorUploadedImgList.value];
        }

        // 삭제할 에디터 이미지 인덱스
        if (editorDeleteImgList.value && editorDeleteImgList.value.length > 0) {
            boardData.editorDeleteImgList = [...editorDeleteImgList.value];
        }

        const fileArray = newFileFilter(attachFiles);
        const formData = new FormData();

        // formData에 boardData 추가
        Object.entries(boardData).forEach(([key, value]) => {
            formData.append(key, value);
        });

        // formData에 새로 추가한 파일 추가
        fileArray.forEach((file, idx) => {
            formData.append('files', file);
        });

        const { data } = await axios.put(`board/${currentBoardId.value}`, formData, { isFormData: true });
        if (data.code === 200) {
            toastStore.onToast('게시물이 수정되었습니다.', 's');
            goList();
        } else {
            toastStore.onToast('게시물 수정에 실패했습니다.', 'e');
        }
    };

    // 컴포넌트 마운트 시 데이터 로드
    onMounted(async () => {
        if (currentBoardId.value) {
            fetchBoardDetails();
        } else {
            console.error('잘못된 게시물 ID:', currentBoardId.value);
        }
    });
</script>
