<template>
  <div class="mx-auto max-w-5xl w-full py-4 px-6 items-center">
    <div class="border-b border-gray-200 dark:border-gray-700 pb-8">
      <VeeForm @submit="handleUpload" v-slot="{ isSubmitting }">
        <div class="mx-auto mt-10 max-w-lg space-y-8">
          <!-- 1) 와디즈 결제 번호 -->
          <div>
            <label
              for="paymentId"
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              와디즈 결제 번호
            </label>
            <VeeField
              name="paymentId"
              id="paymentId"
              type="text"
              rules="required"
              v-model="boardsData.paymentId"
              class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border outline-1 outline-offset-1 outline-gray-300 dark:outline-gray-600 placeholder:text-gray-400 dark:placeholder:text-gray-500 focus:outline-2 focus:outline-indigo-600"
            />
            <VeeErrorMessage
              name="paymentId"
              class="text-red-500 text-sm mt-1"
            />
          </div>

          <!-- 2) 성함 -->
          <div>
            <label
              for="name"
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              성함
            </label>
            <VeeField
              name="name"
              id="name"
              type="text"
              rules="required"
              v-model="boardsData.name"
              class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border outline-1 outline-offset-1 outline-gray-300 dark:outline-gray-600 placeholder:text-gray-400 dark:placeholder:text-gray-500 focus:outline-2 focus:outline-indigo-600"
            />
            <VeeErrorMessage name="name" class="text-red-500 text-sm mt-1" />
          </div>

          <!-- 3) 주소 -->
          <div>
            <label
              for="address"
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              주소
            </label>
            <VeeField
              name="address"
              id="address"
              type="text"
              rules="required"
              v-model="boardsData.address"
              class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border outline-1 outline-offset-1 outline-gray-300 dark:outline-gray-600"
            />
            <VeeErrorMessage name="address" class="text-red-500 text-sm mt-1" />
          </div>

          <!-- 4) 메일 -->
          <div>
            <label
              for="email"
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              메일
            </label>
            <VeeField
              name="email"
              id="email"
              type="email"
              rules="required|email"
              v-model="boardsData.email"
              class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border outline-1 outline-offset-1 outline-gray-300 dark:outline-gray-600 placeholder:text-gray-400 dark:placeholder:text-gray-500 focus:outline-2 focus:outline-indigo-600"
            />
            <VeeErrorMessage name="email" class="text-red-500 text-sm mt-1" />
          </div>

          <!-- 5) 본인 연락처 -->
          <div>
            <label
              for="phone"
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              본인 연락처 (Your Phone)
            </label>
            <VeeField
              name="phone"
              id="phone"
              type="tel"
              rules="required"
              v-model="boardsData.phone"
              placeholder="010-1234-5678"
              class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border outline-1 outline-offset-1 outline-gray-300 dark:outline-gray-600 placeholder:text-gray-400 dark:placeholder:text-gray-500 focus:outline-2 focus:outline-indigo-600"
            />
            <VeeErrorMessage name="phone" class="text-red-500 text-sm mt-1" />
          </div>
          <!-- 6) 긴급 연락처 -->
          <div>
            <label
              for="emergencyPhone"
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              긴급 연락처 | 본인 외 제3자
            </label>
            <VeeField
              name="emergencyPhone"
              id="emergencyPhone"
              type="tel"
              rules="required"
              v-model="boardsData.emergencyPhone"
              placeholder="010-0000-0000"
              class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border outline-1 outline-offset-1 outline-gray-300 dark:outline-gray-600"
            />
            <VeeErrorMessage
              name="emergencyPhone"
              class="text-red-500 text-sm mt-1"
            />
          </div>

          <!-- 7) 예약 일정 선택 -->
          <div>
            <label
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              예약 일정 선택
            </label>
            <div class="mt-2 flex gap-4">
              <!-- 시작일 -->
              <div class="w-1/2">
                <label
                  for="scheduleStart"
                  class="mb-1 block text-sm text-gray-700 dark:text-gray-300"
                >
                  시작일
                </label>
                <Datepicker
                  v-model="scheduleStartDate"
                  :highlight="highlightedDates"
                  :allowed-dates="allowedDates"
                  :enable-time-picker="false"
                  auto-apply
                  id="scheduleStart"
                />
              </div>

              <!-- 종료일 -->
              <div class="w-1/2">
                <label
                  for="scheduleEnd"
                  class="mb-1 block text-sm text-gray-700 dark:text-gray-300"
                >
                  종료일
                </label>
                <input
                  v-model="boardsData.scheduleEnd"
                  id="scheduleEnd"
                  type="text"
                  disabled
                  placeholder="자동 계산 (1박 2일)"
                  class="w-full rounded-md bg-gray-100 dark:bg-gray-700 px-3 py-2 text-gray-400 dark:text-gray-400 border dark:border-gray-600"
                />
              </div>
            </div>
            <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
              예약불가 날짜: 2025년 10월 3일(금)~5일(일), 연박 불가 / 체류가능일
              : 금·토·일
            </p>
          </div>

          <!-- 8) 본인 참석 여부 -->
          <div>
            <span
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              본인 참석 여부 (Are you attending?)
            </span>
            <div class="mt-2 flex items-center gap-6">
              <label class="inline-flex items-center">
                <VeeField
                  name="attending"
                  type="radio"
                  :value="'yes'"
                  v-model="boardsData.attending"
                  class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500"
                />
                <span class="ml-2 text-gray-700 dark:text-gray-300"
                  >예 (Yes)</span
                >
              </label>
              <label class="inline-flex items-center">
                <VeeField
                  name="attending"
                  type="radio"
                  :value="'no'"
                  v-model="boardsData.attending"
                  class="h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500"
                />
                <span class="ml-2 text-gray-700 dark:text-gray-300"
                  >아니오 (No)</span
                >
              </label>
            </div>
            <VeeErrorMessage
              name="attending"
              class="text-red-500 text-sm mt-1"
            />
          </div>

          <!-- 8-2) If "아니오", show alternate attendee fields -->
          <div v-if="boardsData.attending === 'no'" class="space-y-4">
            <!-- 대리 참석자 성함 -->
            <div>
              <label
                for="altName"
                class="block text-sm font-medium text-gray-900 dark:text-gray-100"
              >
                대리 참석자 성함 (Alternate Attendee Name)
              </label>
              <VeeField
                name="altName"
                id="altName"
                type="text"
                v-model="boardsData.altName"
                class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border outline-1 outline-offset-1 outline-gray-300 dark:outline-gray-600 placeholder:text-gray-400 dark:placeholder:text-gray-500 focus:outline-2 focus:outline-indigo-600"
              />
              <VeeErrorMessage
                name="altName"
                class="text-red-500 text-sm mt-1"
              />
            </div>

            <!-- 대리 참석자 연락처 -->
            <div>
              <label
                for="altPhone"
                class="block text-sm font-medium text-gray-900 dark:text-gray-100"
              >
                대리 참석자 연락처 (Alternate Attendee Phone)
              </label>
              <VeeField
                name="altPhone"
                id="altPhone"
                type="tel"
                v-model="boardsData.altPhone"
                placeholder="010-1234-5678"
                class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border outline-1 outline-offset-1 outline-gray-300 dark:outline-gray-600 placeholder:text-gray-400 dark:placeholder:text-gray-500 focus:outline-2 focus:outline-indigo-600"
              />
              <VeeErrorMessage
                name="altPhone"
                class="text-red-500 text-sm mt-1"
              />
            </div>
          </div>

          <!-- 9) 참여 동반자 정보 -->
          <div>
            <label
              for="companions"
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              참여 동반자 정보 (선택)
            </label>
            <VeeField
              name="companions"
              id="companions"
              type="text"
              v-model="boardsData.companions"
              placeholder="동반자 성함 등"
              class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border dark:border-gray-600"
            />
            <VeeErrorMessage
              name="companions"
              class="text-red-500 text-sm mt-1"
            />
          </div>

          <!-- 10) 알레르기나 건강 특이사항 (선택) -->
          <div>
            <label
              for="healthNotes"
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              알레르기나 건강 특이사항 (선택)
            </label>
            <VeeField
              name="healthNotes"
              id="healthNotes"
              v-model="boardsData.healthNotes"
              as="textarea"
              rows="2"
              placeholder="예: 견과류 알레르기"
              class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border dark:border-gray-600"
            />
            <VeeErrorMessage
              name="healthNotes"
              class="text-red-500 text-sm mt-1"
            />
          </div>

          <!-- 11) 전달하고 싶은 말 (선택) -->
          <div>
            <label
              for="remarks"
              class="block text-sm font-medium text-gray-900 dark:text-gray-100"
            >
              전달하고 싶은 말 (선택)
            </label>
            <VeeField
              name="remarks"
              id="remarks"
              v-model="boardsData.remarks"
              as="textarea"
              rows="4"
              placeholder="예: 채팅으로 연락해주세요."
              class="mt-1 block w-full rounded-md bg-white dark:bg-gray-800 px-3.5 py-2 text-base text-gray-900 dark:text-gray-100 border dark:border-gray-600"
            />
            <VeeErrorMessage name="remarks" class="text-red-500 text-sm mt-1" />
          </div>
          <!-- 12) 개인정보 수집 및 이용 동의 -->
          <div>
            <label class="inline-flex items-start gap-2 cursor-pointer">
              <VeeField
                name="privacyAgreement"
                type="checkbox"
                rules="required"
                value="yes"
                class="mt-1"
              />
              <span class="text-sm text-gray-700 dark:text-gray-300">
                <span
                  class="text-indigo-600 dark:text-indigo-400 underline cursor-pointer"
                  @click.prevent="showPrivacyAgreement = !showPrivacyAgreement"
                >
                  개인정보 수집 및 이용에
                </span>
                동의합니다.
              </span>
            </label>
            <VeeErrorMessage
              name="privacyAgreement"
              class="text-red-500 text-sm mt-1"
            />
          </div>
          <div
            v-if="showPrivacyAgreement"
            class="mt-4 p-4 bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-md text-sm text-gray-700 dark:text-gray-300"
          >
            <h3 class="font-semibold mb-2">개인정보 수집 및 이용 동의서</h3>
            <p>
              <strong>[정선 백패킹 포레스트]</strong> 참가자 개인정보 수집 및
              이용에 대한 동의
            </p>
            <p class="mt-2">(주식회사 보부)</p>

            <ul class="mt-4 list-disc pl-4 space-y-2">
              <li>
                <strong>수집 항목:</strong>
                성명, 생년월일, 연락처, 이메일, 주소
              </li>
              <li>
                <strong>수집 및 이용 목적:</strong>
                프로그램 참가자 관리, 만족도 조사 및 서비스 개선, 여행자보험
                가입
              </li>
              <li>
                <strong>보유 및 이용 기간:</strong>
                수집일로부터 5년간 보관 후 파기 (관련 법령에 따라 별도 보관
                가능)
              </li>
              <li>
                <strong>동의 거부 시 안내:</strong>
                동의는 선택사항이나, 미동의 시 참가가 제한될 수 있습니다.
              </li>
            </ul>
          </div>
          <!-- Submit -->
          <button
            type="submit"
            class="block w-full bg-indigo-600 text-white py-3 px-3 rounded transition hover:bg-indigo-700 mt-12 font-semibold dark:bg-indigo-500 dark:hover:bg-indigo-600 disabled:opacity-50 dark:disabled:opacity-60"
            :disabled="in_submission"
          >
            <div
              v-if="show_alert"
              :class="[
                alert_variant, // Ensure this variable contains dark: variants
                'text-white text-center font-bold p-4 rounded mb-4',
              ]"
            >
              {{ alert_msg }}
            </div>
            <div v-show="!in_submission">
              {{ isEdit ? '수정하기' : '제출하기' }}
            </div>
            <div v-if="in_submission">
              <font-awesome-icon :icon="['fas', 'spinner']" spin />
            </div>
          </button>
        </div>
      </VeeForm>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  ref,
  onBeforeUnmount,
  onMounted,
  watch,
  reactive,
  computed,
} from 'vue';
import { useRouter } from 'vue-router';
import { fetchLatestDocumentNumber } from '@/utils/firebaseUtils';
import {
  resetFileSlots,
  getFilesFromUploads,
  createBoardsData,
  uploadFiles,
  handleUpdateBoard,
  handleCreateBoard,
  getDeleteFileIndexesFromUploads,
  createEmptyUploadFileData,
  getBoardDocRef,
} from '@/utils/boardUtils';
import {
  Form as VeeForm,
  Field as VeeField,
  ErrorMessage as VeeErrorMessage,
} from 'vee-validate';
import { syncBoardAndUploadsData } from '@/utils/boardUtils';
import { useUserStore } from '@/stores/user';
//types
import { UploadSettings } from '@/data/config';
import type {
  WadizBoard,
  BoardItem,
  ThumbnailData,
  FileItem,
  UploadFileData,
  UploadsData,
} from '@/types';
import type { Ref } from 'vue';

const props = defineProps({
  isEdit: { type: Boolean, default: false },
  board: { type: Object as PropType<BoardItem>, default: () => ({}) },
});
const emit = defineEmits(['update-success', 'success']);
const userStore = useUserStore();
const userId = computed(() => userStore.docId);

//customize
const { $firebase } = useNuxtApp();
const wadizesCollection = $firebase.wadizesCollection;
const currentCollection = wadizesCollection;
const currentBoard = 'wadiz';
const compData = {
  title: '공지사항 | NOTICE',
};
//loading Message
const loadingMessage = 'Uploading! 잠시만 기다려주세요...';
const isUploading = ref(false);
//alert
const { show_alert, alert_variant, alert_msg, showAlert } = useAlert();

// Validation
const validateInput = (): boolean => {
  if (!boardsData.value.paymentId.trim()) {
    showAlert('와디즈 결제 번호는 필수입니다!', 'bg-red-500', true);
    in_submission.value = false;
    return false;
  }
  return true;
};
//state
const showPrivacyAgreement = ref(false);
const in_submission = ref(false);
const isEdit = ref(props.isEdit ?? false);
const newBoard = ref(props.board);
const boardsData: Ref<WadizBoard> = ref({
  docId: '',
  userId: '',
  title: '',
  description: '',
  boardState: { state: 'processing' },
  announcement: false,
  created: '',
  files: [],
  //depreciated
  boards_number: 0,
  thumbnail: { name: '', url: '' } as FileItem,
  ishidden: false,
  //wadizes
  name: '',
  paymentId: '',
  email: '',
  phone: '',
  address: '',
  emergencyPhone: '',
  scheduleStart: '',
  scheduleEnd: '',
  attending: 'yes',
  altName: '',
  altPhone: '',
  companions: '',
  healthNotes: '',
  remarks: '',
});

const thumbnailInput = ref<HTMLInputElement | null>(null);
const thumbnail: ThumbnailData = {
  input: ref(null),
  preview: ref(''),
  deleteTrigger: ref(false),
  oldPreviewState: ref(false),
  uploadState: ref(false),
  previewState: ref(false),
  displayedName: ref(''),
};
const files = reactive<UploadFileData[]>([]);

const uploadsData: UploadsData = {
  thumbnail,
  files,
};
//FOR EDIT, Write

// firebase Upload
const handleUpload = async () => {
  in_submission.value = true;

  if (!validateInput()) {
    in_submission.value = false;
    return;
  }

  // ✅ Validate plain files (UploadFileData[])
  const rejectedFiles = uploadsData.files
    .map((fileData) => fileData?.input)
    .filter(
      (file) => file instanceof File && !UploadSettings.isValidFile(file)
    );

  if (rejectedFiles.length > 0) {
    const reason =
      rejectedFiles[0] instanceof File
        ? UploadSettings.getInvalidFileReasonKey(rejectedFiles[0])
        : null;
    const msg = UploadSettings.UploadErrorMessages[reason!];
    showAlert(msg ?? 'Invalid file', 'bg-red-500');
    in_submission.value = false;
    return;
  }

  try {
    const newBoardsNumber = await fetchLatestDocumentNumber(
      currentCollection,
      'boards_number'
    );

    let boardPayload: WadizBoard = createBoardsData(
      boardsData.value,
      newBoardsNumber
    ) as WadizBoard;

    // ✅ Collect valid files and thumbnail
    const { thumbnail, files } = getFilesFromUploads(uploadsData);

    if (isEdit.value) {
      if (!newBoard.value) {
        showAlert('기존 게시글 데이터를 찾을 수 없습니다.', 'bg-red-500');
        in_submission.value = false;
        return;
      }

      const oldFiles = newBoard.value.files ?? [];
      const oldThumbUrl = newBoard.value.thumbnail?.url ?? '';
      const deleteThumbnail = uploadsData.thumbnail.deleteTrigger.value;
      const deleteFileIndexes = getDeleteFileIndexesFromUploads(uploadsData);

      boardPayload = (await uploadFiles({
        newBoardData: boardPayload,
        newThumbnail: thumbnail instanceof File ? thumbnail : null,
        newFiles: files,
        oldThumbnailUrl: oldThumbUrl,
        oldFiles,
        deleteThumbnail,
        deleteFileIndexes,
        currentBoard,
      })) as WadizBoard;

      await handleUpdateBoard(boardPayload, currentCollection);
      showAlert('성공적으로 수정되었습니다', 'bg-green-800');
      emit('success');
    } else {
      const { docId: freshDocId } = getBoardDocRef(currentCollection);

      boardPayload = {
        ...boardPayload,
        docId: freshDocId,
        userId: userId.value,
        boardState: { state: 'processing' },
      };
      boardPayload = (await uploadFiles({
        newBoardData: boardPayload,
        newThumbnail: thumbnail,
        newFiles: files,
        currentBoard,
      })) as WadizBoard;

      if (boardPayload.scheduleStart instanceof Date) {
        boardPayload.scheduleStart = format(
          boardPayload.scheduleStart,
          'yyyy-MM-dd'
        );
      }
      if (boardPayload.scheduleEnd instanceof Date) {
        boardPayload.scheduleEnd = format(
          boardPayload.scheduleEnd,
          'yyyy-MM-dd'
        );
      }
      await handleCreateBoard(boardPayload, currentCollection);
      showAlert('성공적으로 생성되었습니다', 'bg-green-800', true);
      emit('success');
    }
  } catch (error) {
    console.error('업로드 중 에러 발생:', error);
    showAlert('업로드 실패: 파일 또는 데이터 에러', 'bg-red-500');
  } finally {
    in_submission.value = false;
  }
};

onMounted(() => {
  // if (uploadsData.files.length === 0) {
  //   addFileSlot(uploadsData.files);
  // }
  console.log('mounted', uploadsData);
});

watch(
  () => props.board,
  (newBoard) => {
    if (newBoard) {
      syncBoardAndUploadsData(
        newBoard,
        boardsData,
        uploadsData,
        createEmptyUploadFileData,
        resetFileSlots
      );
      console.log('newBoard', newBoard);
    }
  },
  { immediate: true }
);
//calender
import Datepicker from '@vuepic/vue-datepicker';
import '@vuepic/vue-datepicker/dist/main.css';
import { format, addDays } from 'date-fns';

// Blocked weekend range (연박 불가)
const blockedDates = ['2025-10-03', '2025-10-04', '2025-10-05'];

const allowedDates = computed(() => {
  const result: Date[] = [];
  const start = new Date('2025-06-13');
  const end = new Date('2025-10-31');

  for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
    const date = new Date(d);
    const day = date.getDay(); // 0: Sun, 5: Fri, 6: Sat
    const dateStr = format(date, 'yyyy-MM-dd');
    const isUnavailable =
      (dateStr >= '2025-10-03' && dateStr <= '2025-10-05') ||
      dateStr === '2025-06-13' ||
      dateStr === '2025-06-14';
    const isWeekend = [5, 6].includes(day);

    if (isWeekend && !isUnavailable) {
      result.push(date);
    }
  }

  return result;
});
// Optional: Highlight allowed dates with a class
const highlightedDates = computed(() => {
  const map: Partial<Record<number, string>> = {};
  allowedDates.value.forEach((date) => {
    map[date.getTime()] = 'dp-highlight-green';
  });
  return map;
});

// Auto-calculate end date
watch(
  () => boardsData.value.scheduleStart,
  (val) => {
    if (!val) return;
    const endDate = addDays(new Date(val as string), 1);
    boardsData.value.scheduleEnd = format(endDate, 'yyyy-MM-dd'); // ✅ Use ISO format
  }
);

// Two-way binding date model
const scheduleStartDate = computed({
  get: () =>
    boardsData.value.scheduleStart instanceof Date
      ? boardsData.value.scheduleStart
      : new Date(),
  set: (val: Date) => {
    boardsData.value.scheduleStart = val;
  },
});
</script>
<style>
.ck-editor__editable {
  min-height: 500px;
}
</style>
