<template>
  <q-scroll-area class="loyalty-suite-wrapper">
    <q-inner-loading :showing="loading">
      <q-spinner color="primary" size="70px" />
    </q-inner-loading>

    <template v-if="!loading">
      <div v-if="error" class="loyalty-suite-api-error-message">
        <q-icon name="error_outline" color="negative" size="md" />
        <span>{{ error }}</span>
      </div>

      <template v-else>
        <div class="loyalty-suite-challenge">
          <div class="loyalty-suite-challenge__title">
            <q-btn icon="arrow_back" color="primary" class="loyalty-suite-form__back" @click="goBack" />
            <h1 class="loyalty-suite-challenge__title-text">
              {{ isEditing ? $t('challengeEdit') : $t('challengeAdd') }}
            </h1>
          </div>

          <q-form class="loyalty-suite-form" @submit.prevent="submitForm">
            <div class="loyalty-suite-form__section">
              <div class="loyalty-suite-form__title">{{ $t('challengeSettings') }}</div>

              <div class="loyalty-suite-form__row">
                <span class="loyalty-suite-form__row-label">
                  {{ $t('name') }}
                  <span class="loyalty-suite-form__row-label-required">*</span>
                  <q-icon name="info_outline" size="18px" class="loyalty-suite-form__row-hint">
                    <q-tooltip anchor="top right" self="top right">
                      {{ $t('challengeNameHint') }}
                    </q-tooltip>
                  </q-icon>
                </span>
                <q-input v-model="challenge.name" outlined required
                  :rules="[val => val && val.length > 0 || $t('requiredField')]" />
              </div>

              <div class="loyalty-suite-form__row">
                <span class="loyalty-suite-form__row-label">
                  {{ $t('challengeStartDate') }}
                  <q-icon name="info_outline" size="18px" class="loyalty-suite-form__row-hint">
                    <q-tooltip anchor="top right" self="top right">
                      {{ $t('challengeStartDateHint') }}
                    </q-tooltip>
                  </q-icon>
                </span>
                <q-input v-model="formattedStartDate" outlined readonly :placeholder="$t('selectValue')"
                  class="loyalty-suite-form__datepicker" @click="openDatePicker('start_date')">
                  <template v-slot:append>
                    <div v-if="formattedStartDate" class="loyalty-suite-form__datepicker-clear">
                      <q-icon name="close" class="cursor-pointer" @click.prevent="clearDate('start_date')" />
                    </div>
                    <q-icon name="event" data-datepicker="start_date" class="cursor-pointer">
                      <q-popup-proxy v-model="datePickerStartVisible" cover transition-show="scale"
                        transition-hide="scale">
                        <q-date v-model="challenge.start_date" :mask="dateMask" :locale="datePickerLocale"
                          :first-day-of-week="wpStartOfWeek" :options="disablePastDates"
                          @update:model-value="updateFormattedStartDate">
                          <div class="row items-center justify-end">
                            <q-btn v-close-popup :label="$t('close')" color="primary" />
                          </div>
                        </q-date>
                      </q-popup-proxy>
                    </q-icon>
                  </template>
                </q-input>
              </div>

              <div class="loyalty-suite-form__row">
                <span class="loyalty-suite-form__row-label">
                  {{ $t('challengeEndDate') }}
                  <q-icon name="info_outline" size="18px" class="loyalty-suite-form__row-hint">
                    <q-tooltip anchor="top right" self="top right">
                      {{ $t('challengeEndDateHint') }}
                    </q-tooltip>
                  </q-icon>
                </span>
                <q-input v-model="formattedEndDate" outlined readonly :placeholder="$t('selectValue')"
                  class="loyalty-suite-form__datepicker" @click="openDatePicker('end_date')" :error="!!endDateError"
                  :error-message="endDateError ?? ''">
                  <template v-slot:append>
                    <div v-if="formattedEndDate" class="loyalty-suite-form__datepicker-clear">
                      <q-icon name="close" class="cursor-pointer" @click.prevent="clearDate('end_date')" />
                    </div>
                    <q-icon name="event" data-datepicker="end_date" class="cursor-pointer">
                      <q-popup-proxy v-model="datePickerEndVisible" cover transition-show="scale"
                        transition-hide="scale">
                        <q-date v-model="challenge.end_date" :mask="dateMask" :locale="datePickerLocale"
                          :options="disablePastDates" :first-day-of-week="wpStartOfWeek"
                          @update:model-value="validateEndDate">
                          <div class="row items-center justify-end">
                            <q-btn v-close-popup :label="$t('close')" color="primary" />
                          </div>
                        </q-date>
                      </q-popup-proxy>
                    </q-icon>
                  </template>
                </q-input>
              </div>

              <div class="loyalty-suite-form__row">
                <span class="loyalty-suite-form__row-label">
                  {{ $t('missionCompletionOrder') }}
                  <q-icon name="info_outline" size="18px" class="loyalty-suite-form__row-hint">
                    <q-tooltip anchor="top right" self="top right">
                      {{ $t('challengeComplitionOrderHint') }}
                    </q-tooltip>
                  </q-icon>
                </span>
                <q-select v-model="challenge.condition_order" :options="missionOrderOptions" emit-value map-options
                  fill-input input-debounce="0" outlined>
                  <template v-slot:no-option>
                    <q-item>
                      <q-item-section class="text-grey">{{ $t('noResultsFound') }}</q-item-section>
                    </q-item>
                  </template>

                  <template v-slot:option="scope">
                    <q-item v-bind="scope.itemProps">
                      <q-item-section>
                        <q-item-label>{{ scope.opt.label }}</q-item-label>
                      </q-item-section>
                      <q-item-section side>
                        <q-icon name="info_outline" class="loyalty-suite-form__select-info" size="18px">
                          <q-tooltip anchor="top right" self="top right">
                            {{ $t(`opt_missions_${scope.opt.value}`) }}
                          </q-tooltip>
                        </q-icon>
                      </q-item-section>
                    </q-item>
                  </template>
                </q-select>
              </div>

              <div class="loyalty-suite-form__row">
                <span class="loyalty-suite-form__row-label">
                  {{ $t('imageType') }}
                  <q-icon name="info_outline" size="18px" class="loyalty-suite-form__row-hint">
                    <q-tooltip anchor="top right" self="top right">
                      {{ $t('imageTypeHint') }}
                    </q-tooltip>
                  </q-icon>
                </span>
                <q-select v-model="selectedImageType" :options="imageTypeOptions" fill-input input-debounce="0"
                  :rules="[() => !!selectedImageType || $t('requiredField')]" outlined>
                </q-select>
              </div>

              <div v-if="challenge.image_type === 'icon'" class="loyalty-suite-form__row">
                <span class="loyalty-suite-form__row-label">
                  {{ $t('icon') }}
                  <q-icon name="info_outline" size="18px" class="loyalty-suite-form__row-hint">
                    <q-tooltip anchor="top right" self="top right">
                      {{ $t('iconHint') }}
                    </q-tooltip>
                  </q-icon>
                </span>
                <div class="loyalty-suite-form__preview"
                  :class="{ 'loyalty-suite-form__preview_empty': !challenge.icon }" @click="openLibrary">
                  <div class="loyalty-suite-form__preview-container">
                    <img v-if="previewUrl" :src="previewUrl" class="loyalty-suite-form__preview-img" />
                    <q-btn v-if="challenge.icon" icon="close" color="negative" @click.stop="removeIcon"
                      class="loyalty-suite-form__preview-remove" />
                    <q-icon v-else name="file_upload" class="loyalty-suite-form__preview-icon" />
                    <span v-if="previewName" class="loyalty-suite-form__preview-name">
                      {{ previewName }}
                    </span>
                    <span v-else class="loyalty-suite-form__preview-label">
                      {{ $t('fileUpload') }}
                    </span>
                  </div>
                </div>
              </div>

              <div v-if="challenge.image_type === 'image'" class="loyalty-suite-form__row">
                <span class="loyalty-suite-form__row-label">
                  {{ $t('image') }}
                  <q-icon name="info_outline" size="18px" class="loyalty-suite-form__row-hint">
                    <q-tooltip anchor="top right" self="top right">
                      {{ $t('imageHint') }}
                    </q-tooltip>
                  </q-icon>
                </span>
                <WpMediaUploader v-model="challenge.image" @update:modelValue="setImage" />
              </div>

              <Library v-model="challenge.icon" v-model:showLibrary="showLibrary" v-model:selectedTab="currentTab"
                @update:modelValue="setIcon" />

              <div class="loyalty-suite-form__row loyalty-suite-form__row_full-width">
                <span class="loyalty-suite-form__row-label">
                  {{ $t('description') }}
                  <q-icon name="info_outline" size="18px" class="loyalty-suite-form__row-hint">
                    <q-tooltip anchor="top right" self="top right">
                      {{ $t('challengeDescriptionHint') }}
                    </q-tooltip>
                  </q-icon>
                </span>
                <Editor v-model="challenge.description" />
              </div>

              <div class="loyalty-suite-form__row loyalty-suite-form__row_toggler">
                <q-toggle v-model="challenge.active" :label="challenge.active ? $t('enabledChallenge') : $t('disabledChallenge')"
                  @update:model-value="confirmDeactivation" />
              </div>
            </div>

            <Rewards v-model="challenge.rewards" :changeLoading="changeLoading" :rewardsFields="rewardsFields"
              :postType="'challenge'" :currency="currency" />

            <div class="loyalty-suite-form__section loyalty-suite-form__section_tabs">
              <div class="loyalty-suite-form__section__tabs">
                <div class="loyalty-suite-form__section__tabs-wrapper">
                  <q-tabs v-model="activeTab" align="left">
                    <q-tab v-for="(mission, index) in challenge.missions" :key="index" :name="index"
                      :label="`${$t('mission')} #${index + 1}`" />
                  </q-tabs>
                </div>
                <div class="loyalty-suite-form__section__tabs-button">
                  <q-btn color="primary" icon="add" @click="addMission" />
                </div>
              </div>

              <q-tab-panels v-model="activeTab">
                <q-tab-panel v-for="(mission, index) in challenge.missions" :key="index" :name="index">

                  <Conditions v-model="mission.conditions" :changeLoading="changeLoading"
                    :conditionsFields="conditionsFields" :postType="'mission'" :currency="currency" />

                  <Rewards v-model="mission.rewards" :changeLoading="changeLoading" :rewardsFields="rewardsFields"
                    :postType="'mission'" :currency="currency" />

                  <div v-if="challenge.missions.length > 1"
                    class="loyalty-suite-form__row loyalty-suite-form__row_tab-action">
                    <q-btn color="negative" :loading="changeLoading" @click="deleteIndex(index)">
                      {{ $t('deleteMission') }}
                    </q-btn>
                  </div>
                </q-tab-panel>
              </q-tab-panels>
            </div>

            <div class="loyalty-suite-form__action">
              <q-btn v-if="isEditing" class="loyalty-suite-form__action-delete" :label="$t('deleteChallenge')"
                @click="confirmDelete = true" color="negative" :loading="changeLoading" />
              <q-btn type="submit" :label="isEditing ? $t('saveChallenge') : $t('addChallenge')"
                :loading="changeLoading" color="primary" />
            </div>

            <div v-if="addError" class="loyalty-suite-form__action-error">{{ $t(addError) }}</div>

            <q-dialog v-model="deactivate">
              <q-card>
                <q-card-section>
                  <span>{{ $t('challengeDeactivation') }}</span>
                </q-card-section>
                <q-card-actions align="center">
                  <q-btn :label="$t('ok')" color="primary" :loading="changeLoading" v-close-popup />
                </q-card-actions>
              </q-card>
            </q-dialog>

            <q-dialog v-model="confirmDelete">
              <q-card>
                <q-card-section>
                  <span>{{ $t('challengeDelete') }}</span>
                  <span>{{ $t('affectMembers') }}</span>
                </q-card-section>
                <q-card-actions align="center">
                  <q-btn :label="$t('cancel')" color="negative" v-close-popup />
                  <q-btn :label="$t('delete')" color="primary" v-close-popup @click="deleteChallenge" />
                </q-card-actions>
              </q-card>
            </q-dialog>

            <q-dialog v-model="confirmDeleteMission">
              <q-card>
                <q-card-section>
                  <span>{{ $t('missionDelete') }}</span>
                  <span>{{ $t('affectMembers') }}</span>
                </q-card-section>
                <q-card-actions align="center">
                  <q-btn :label="$t('cancel')" color="negative" v-close-popup />
                  <q-btn :label="$t('delete')" color="primary" v-close-popup @click="removeMission()" />
                </q-card-actions>
              </q-card>
            </q-dialog>

            <q-dialog v-model="confirmLeave">
              <q-card>
                <q-card-section>
                  <span>{{ $t('unsavedChanges') }}</span>
                </q-card-section>
                <q-card-actions align="center">
                  <q-btn :label="$t('cancel')" color="negative" v-close-popup />
                  <q-btn :label="$t('discardChanges')" color="primary" v-close-popup @click="navigateBack" />
                </q-card-actions>
              </q-card>
            </q-dialog>

            <q-dialog v-model="missionsLimitDialog">
              <q-card>
                <q-card-section>
                  <span>{{ $t('missionsLimitTitle') }}</span>
                </q-card-section>
                <q-card-actions align="center">
                  <q-btn :label="$t('ok')" color="primary" v-close-popup />
                  <q-btn color="positive" :label="$t('getPRO')" :href="getProLink" target="_blank" v-close-popup />
                </q-card-actions>
              </q-card>
            </q-dialog>
          </q-form>
        </div>
      </template>
    </template>
  </q-scroll-area>
</template>

<script lang="ts">
import { defineComponent, ref, onBeforeMount, computed, watch, nextTick } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import Conditions from '../../components/Conditions.vue';
import Rewards from '../../components/Rewards.vue';
import Library from '../../components/Library.vue';
import WpMediaUploader from '../../components/WpMediaUploader.vue';
import Editor from '../../components/Editor.vue';

export default defineComponent({
  components: { Conditions, Rewards, Library, Editor, WpMediaUploader },
  setup() {
    const route = useRoute();
    const router = useRouter();
    const changeLoading = ref(false);
    const originalChallenge = ref<string | null>(null);
    const confirmLeave = ref(false);
    const activeTab = ref(0);
    const isEditing = computed(() => !!route.params.id);
    const loading = ref(true);
    const apiRoutes = window.loyalty_suite_admin_data.apiRoutes;
    const nonce = window.loyalty_suite_admin_data.nonce;
    const confirmDelete = ref(false);
    const confirmDeleteMission = ref(false);
    const missionToDelete = ref<number | null>(null);
    const deactivate = ref(false);
    const error = ref<string | null>(null);
    const addError = ref<string | null>(null);
    const endDateError = ref<string | null>(null);
    const wpDateFormat = ref<string>(window.loyalty_suite_admin_data?.dateFormat || 'Y-m-d');
    const formattedStartDate = ref<string | null>(null);
    const formattedEndDate = ref<string | null>(null);
    const wpStartOfWeek = window.loyalty_suite_admin_data?.startOfWeek ?? 1;
    const datePickerStartVisible = ref(false);
    const datePickerEndVisible = ref(false);
    const { t } = useI18n();
    const fileError = ref<boolean | null>(null);
    const previewUrl = ref<string | null>(null);
    const previewName = ref<string | null>(null);
    const isPro = window.loyalty_suite_admin_data.isPro;
    const getProLink = window.loyalty_suite_admin_data.getProLink;
    const missionsLimitDialog = ref(false);
    const showLibrary = ref(false);
    const currentTab = ref('challenges');
    const currency = ref({ symbol: '$' });
    const dateMask = 'YYYY-MM-DD';

    const conditionsFields = ref<Array<{
      key: string;
      type: string;
      options?: Array<{ value: string; label: string }>;
      dependency?: string[];
    }>>([]);

    const rewardsFields = ref<Array<{
      key: string;
      type: string;
      options?: Array<{ value: string; label: string }>;
      dependency?: string[];
    }>>([]);

    const missionOrderOptions = ref([
      { value: 'sequential', label: t('sequentialOrder') },
      { value: 'any', label: t('anyOrder') },
    ]);

    const challenge = ref<{
      id: Number | null,
      name: string;
      start_date: string;
      end_date: string;
      condition_order: string;
      image_type: string;
      image: number | null;
      icon: File | null;
      description: string;
      active: boolean;
      rewards: Array<Record<string, any>>;
      missions: {
        id: Number | null;
        conditions: Array<Record<string, any>>;
        rewards: Array<Record<string, any>>;
      }[];
    }>({
      id: !isNaN(Number(route.params.id)) ? Number(route.params.id) : null,
      name: '',
      start_date: '',
      end_date: '',
      condition_order: 'sequential',
      image_type: 'icon',
      image: null,
      icon: null,
      description: '',
      active: true,
      rewards: [],
      missions: [
        {
          id: null,
          conditions: [],
          rewards: [],
        }
      ]
    });

    const datePickerLocale = {
      days: [
        t('Sunday'), t('Monday'), t('Tuesday'), t('Wednesday'), t('Thursday'), t('Friday'), t('Saturday')
      ],
      daysShort: [
        t('Sun'), t('Mon'), t('Tue'), t('Wed'), t('Thu'), t('Fri'), t('Sat')
      ],
      months: [
        t('January'), t('February'), t('March'), t('April'), t('May'), t('June'),
        t('July'), t('August'), t('September'), t('October'), t('November'), t('December')
      ],
      monthsShort: [
        t('Jan'), t('Feb'), t('Mar'), t('Apr'), t('MayShort'), t('Jun'),
        t('Jul'), t('Aug'), t('Sep'), t('Oct'), t('Nov'), t('Dec')
      ]
    };

    const normalizeApiDateToYmd = (value: string | null | undefined): string => {
      if (!value) return '';
      // Поддерживаем и `Y-m-d`, и `Y-m-d H:i:s`
      const safe = value.includes('T') || !value.includes(' ')
        ? value
        : value.replace(' ', 'T');
      const d = new Date(safe);
      if (Number.isNaN(d.getTime())) return '';
      const y = d.getFullYear();
      const m = String(d.getMonth() + 1).padStart(2, '0');
      const day = String(d.getDate()).padStart(2, '0');
      return `${y}-${m}-${day}`;
    };

    const formatDateLabel = (dateStr: string): string => {
      if (!dateStr) return '';
      const parts = dateStr.split('-');
      if (parts.length !== 3) return dateStr;

      const year = Number(parts[0]);
      const monthIndex = Number(parts[1]) - 1;
      const day = Number(parts[2]);

      if (!year || monthIndex < 0 || monthIndex > 11 || !day) {
        return dateStr;
      }

      const monthName = datePickerLocale.months[monthIndex] ?? '';

      switch (wpDateFormat.value) {
        case 'F j, Y':
          return `${monthName} ${day}, ${year}`;
        case 'Y-m-d':
          return `${year}-${String(monthIndex + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
        case 'm/d/Y':
          return `${String(monthIndex + 1).padStart(2, '0')}/${String(day).padStart(2, '0')}/${year}`;
        case 'd/m/Y':
          return `${String(day).padStart(2, '0')}/${String(monthIndex + 1).padStart(2, '0')}/${year}`;
        case 'Y/m/d':
          return `${year}/${String(monthIndex + 1).padStart(2, '0')}/${String(day).padStart(2, '0')}`;
        case 'd.m.Y':
          return `${String(day).padStart(2, '0')}.${String(monthIndex + 1).padStart(2, '0')}.${year}`;
        case 'j. F Y':
          return `${day}. ${monthName} ${year}`;
        case 'j F Y':
          return `${day} ${monthName} ${year}`;
        default:
          return `${year}-${String(monthIndex + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
      }
    };

    const clearDate = (key: string) => {
      if (key === 'start_date') {
        challenge.value.start_date = '';
        formattedStartDate.value = '';
      } else if (key === 'end_date') {
        challenge.value.end_date = '';
        formattedEndDate.value = '';
        endDateError.value = null;
      }
    };

    const updateFormattedStartDate = (date: string) => {
      challenge.value.start_date = date;
      formattedStartDate.value = formatDateLabel(date);
      datePickerStartVisible.value = false;
    };

    const validateEndDate = (date: string) => {
      if (challenge.value.start_date && date) {
        const startDate = new Date(challenge.value.start_date);
        const endDate = new Date(date);

        if (endDate < startDate) {
          endDateError.value = t('endDateCannotBeEarlier');
          formattedEndDate.value = '';
          challenge.value.end_date = '';
          datePickerEndVisible.value = false;
          return;
        }
      }

      endDateError.value = null;
      challenge.value.end_date = date;
      formattedEndDate.value = formatDateLabel(date);
      datePickerEndVisible.value = false;
    };

    const openDatePicker = (key: string) => {
      nextTick(() => {
        const popup = document.querySelector(`[data-datepicker="${key}"]`);
        if (popup) {
          (popup as HTMLElement).click();
        }
      });
    };

    const disablePastDates = (date: string) => {
      const today = new Date();
      today.setHours(0, 0, 0, 0);
      const selectedDate = new Date(date);

      return selectedDate >= today;
    };

    const setImage = (id: number) => {
      challenge.value.image = id;
    };

    const imageTypeOptions = ref([
      { value: 'icon', label: t('icon') },
      { value: 'image', label: t('image') },
    ]);

    const selectedImageType = computed({
      get: () => {
        return (
          imageTypeOptions.value.find(option => option.value === challenge.value.image_type) ||
          imageTypeOptions.value[0]
        );
      },
      set: (newValue) => {
        challenge.value.image_type = newValue?.value || 'icon';
      }
    });

    const removeIcon = () => {
      challenge.value.icon = null;
      previewUrl.value = null;
      previewName.value = null;
    };

    const openLibrary = () => {
      showLibrary.value = true;
    };

    const setIcon = (icon: File) => {
      challenge.value.icon = icon;
      previewUrl.value = URL.createObjectURL(icon);
      previewName.value = icon.name;
    };

    const goBack = () => {
      if (isDirty.value) {
        confirmLeave.value = true;
        return;
      }

      navigateBack();
    };

    const navigateBack = () => {
      if (window.history.length > 1) {
        router.back();
      } else {
        router.push('/missions/list');
      }
    };

    const isDirty = computed(() => {
      return JSON.stringify(challenge.value) !== originalChallenge.value;
    });

    const confirmDeactivation = (value: boolean) => {
      if (!value) {
        deactivate.value = true;
      }
    };

    const deleteIndex = (index: number) => {
      missionToDelete.value = index;
      confirmDeleteMission.value = true;
    };

    const addMission = () => {
      if (!isPro && challenge.value.missions.length >= 3) {
        missionsLimitDialog.value = true;
        return;
      }

      challenge.value.missions.push({
        id: null,
        conditions: [],
        rewards: [],
      });
      activeTab.value = challenge.value.missions.length - 1;
      addError.value = null;
    };

    const removeMission = () => {
      if (missionToDelete.value !== null) {
        challenge.value.missions.splice(missionToDelete.value, 1);
        activeTab.value = Math.max(0, activeTab.value - 1);
        missionToDelete.value = null;
      }
    };

    const validateForm = (): boolean => {
      const currentTabIndex = activeTab.value;

      if (challenge.value.start_date && challenge.value.end_date) {
        const startDate = new Date(challenge.value.start_date);
        const endDate = new Date(challenge.value.end_date);

        if (endDate < startDate) {
          endDateError.value = t('endDateCannotBeEarlier');
          return false;
        }
      }

      if (!isTabValid(currentTabIndex)) return false;

      for (let i = 0; i < challenge.value.missions.length; i++) {
        if (!isTabValid(i)) {
          activeTab.value = i;
          return false;
        }
      }

      return true;
    };

    const isTabValid = (index: number): boolean => {
      const mission = challenge.value.missions[index];

      if (mission.conditions.length === 0) {
        addError.value = 'noConditions';
        return false;
      }

      return true;
    };

    const fetchChallenge = async () => {
      if (!isEditing.value) return;

      try {
        const buildApiUrl = (base, params = {}) => {
          const url = new URL(base, window.location.origin);
          Object.entries(params).forEach(([key, value]) => {
            if (value !== undefined && value !== null && value !== '') {
              url.searchParams.set(key, value as string);
            }
          });
          return url.toString();
        };

        const response = await fetch(
          buildApiUrl(apiRoutes.admin.challenge, {
            id: Number(route.params.id),
          }),
          {
            method: 'GET',
            headers: {
              'X-WP-Nonce': nonce,
              'Content-Type': 'application/json',
            },
            credentials: 'same-origin',
          }
        );

        if (!response.ok) {
          throw new Error(`API Error: ${response.status} ${response.statusText}`);
        }

        const data = await response.json().catch(() => null);

        const rawStart = data.challenge.start_date;
        const rawEnd = data.challenge.end_date;

        challenge.value.id = Number(route.params.id) ?? null;
        challenge.value.name = data.challenge.name;
        challenge.value.start_date = normalizeApiDateToYmd(rawStart);
        challenge.value.end_date = normalizeApiDateToYmd(rawEnd);
        challenge.value.condition_order = data.challenge.condition_order ?? 'sequential';
        challenge.value.icon = data.challenge.icon || null;
        challenge.value.image_type = data.challenge.image_type || 'icon';
        challenge.value.image = Number(data.challenge.image) || null;
        challenge.value.description = data.challenge.description;
        challenge.value.active = data.challenge.active;
        challenge.value.rewards = Array.isArray(data.challenge.rewards)
          ? data.challenge.rewards
          : [];
        challenge.value.missions = Array.isArray(data.challenge?.missions)
          ? data.challenge.missions.map((mission: any) => ({
            id: mission.id,
            name: mission.name,
            conditions: Array.isArray(mission.conditions) ? mission.conditions : [],
            rewards: Array.isArray(mission.rewards) ? mission.rewards : [],
          }))
          : [];

        if (challenge.value.start_date) {
          formattedStartDate.value = formatDateLabel(challenge.value.start_date);
        }

        if (challenge.value.end_date) {
          validateEndDate(challenge.value.end_date);
        }

        previewUrl.value = data.challenge.icon_preview;
        previewName.value = data.challenge.icon_filename;
      } catch (err) {
        error.value = err instanceof Error ? err.message : t('couldNotFetchData');
        console.error('API Error:', error.value);
      }
    };

    const deleteChallenge = async () => {
      try {
        changeLoading.value = true;

        const response = await fetch(apiRoutes.admin.challenge_delete, {
          method: 'DELETE',
          headers: {
            'Content-Type': 'application/json',
            'X-WP-Nonce': nonce
          },
          body: JSON.stringify({ id: Number(route.params.id) })
        });

        const data = await response.json().catch(() => null);

        if (!response.ok) {
          addError.value = data?.error || 'unknownError';
          return;
        }

        router.push('/challenges/list');
      } catch (err) {
        error.value = err instanceof Error ? err.message : 'Error deleting challenge';
      } finally {
        changeLoading.value = false;
      }
    };

    const submitForm = async () => {
      if (!validateForm()) {
        changeLoading.value = false;
        return;
      }

      try {
        changeLoading.value = true;
        const formData = new FormData();

        if (challenge.value.id !== null) {
          formData.append('id', String(challenge.value.id));
        }
        formData.append('name', challenge.value.name);
        formData.append('start_date', challenge.value.start_date || '');
        formData.append('end_date', challenge.value.end_date || '');
        formData.append('condition_order', challenge.value.condition_order);
        formData.append('image_type', challenge.value.image_type);
        formData.append('image', String(challenge.value.image ?? ''));
        if (challenge.value.icon) {
          formData.append('icon', challenge.value.icon);
        }
        formData.append('description', challenge.value.description);
        formData.append('active', String(challenge.value.active));
        formData.append('rewards', JSON.stringify(challenge.value.rewards));

        challenge.value.missions.forEach((mission, i) => {
          formData.append(`missions[${i}][id]`, String(mission.id ?? ''));
          formData.append(`missions[${i}][conditions]`, JSON.stringify(mission.conditions));
          formData.append(`missions[${i}][rewards]`, JSON.stringify(mission.rewards));
        });

        const response = await fetch(apiRoutes.admin.challenge_save, {
          method: 'POST',
          headers: { 'X-WP-Nonce': nonce },
          body: formData
        });

        const data = await response.json().catch(() => null);

        if (data?.error) {
          addError.value = data.error;
          return;
        }

        router.push('/challenges/list');
      } catch (err) {
        error.value = err instanceof Error ? err.message : 'Error submitting data';
      } finally {
        changeLoading.value = false;
      }
    };

    const fetchConditions = async () => {
      try {
        const response = await fetch(apiRoutes.admin.conditions, {
          method: 'GET',
          headers: {
            'X-WP-Nonce': nonce,
            'Content-Type': 'application/json',
          },
        });

        if (!response.ok) {
          throw new Error(`API Error: ${response.status} ${response.statusText}`);
        }

        const data = await response.json();
        conditionsFields.value = Array.isArray(data) ? data : [];
      } catch (err) {
        error.value = err instanceof Error ? err.message : t('couldNotFetchData');
        console.error('API Error:', error.value);
      }
    };

    const fetchRewards = async () => {
      try {
        const response = await fetch(apiRoutes.admin.rewards, {
          method: 'GET',
          headers: {
            'X-WP-Nonce': nonce,
            'Content-Type': 'application/json',
          },
        });

        if (!response.ok) {
          throw new Error(`API Error: ${response.status} ${response.statusText}`);
        }

        const data = await response.json();
        rewardsFields.value = Array.isArray(data) ? data : [];
      } catch (err) {
        error.value = err instanceof Error ? err.message : t('couldNotFetchData');
        console.error('API Error:', error.value);
      }
    };

    const fetchCurrency = async () => {
      try {
        const response = await fetch(apiRoutes.admin.currency, {
          method: 'GET',
          headers: {
            'X-WP-Nonce': nonce,
            'Content-Type': 'application/json',
          }
        });

        if (!response.ok) {
          throw new Error(`API Error: ${response.status} ${response.statusText}`);
        }

        const data = await response.json();
        currency.value = data;
      } catch (err) {
        error.value = err instanceof Error ? err.message : t('couldNotFetchData');
        console.error('API Error:', error.value);
      }
    };

    onBeforeMount(async () => {
      try {
        await Promise.all([fetchConditions(), fetchRewards(), fetchChallenge(), fetchCurrency()]);
      } catch (err) {
        console.error('Api error:', err);
      } finally {
        loading.value = false;
      }

      watch(challenge, (newVal) => {
        if (originalChallenge.value === null) {
          originalChallenge.value = isEditing.value
            ? JSON.stringify(newVal)
            : JSON.stringify({
              id: Number(route.params.id) ?? null,
              name: '',
              start_date: '',
              end_date: '',
              condition_order: 'sequential',
              image_type: 'icon',
              image: null,
              icon: null,
              description: '',
              active: true,
              rewards: [],
              missions: [
                {
                  id: null,
                  conditions: [],
                  rewards: [],
                }
              ]
            });
        }
      }, { deep: true, immediate: true });
    });

    return {
      challenge,
      activeTab,
      error,
      addError,
      confirmLeave,
      navigateBack,
      confirmDelete,
      confirmDeleteMission,
      deactivate,
      confirmDeactivation,
      isEditing,
      loading,
      changeLoading,
      openDatePicker,
      clearDate,
      datePickerLocale,
      wpStartOfWeek,
      disablePastDates,
      datePickerStartVisible,
      datePickerEndVisible,
      updateFormattedStartDate,
      validateEndDate,
      formattedStartDate,
      formattedEndDate,
      endDateError,
      goBack,
      addMission,
      deleteChallenge,
      deleteIndex,
      removeMission,
      submitForm,
      conditionsFields,
      rewardsFields,
      missionOrderOptions,
      fileError,
      previewUrl,
      previewName,
      removeIcon,
      showLibrary,
      openLibrary,
      currentTab,
      setIcon,
      currency,
      setImage,
      selectedImageType,
      imageTypeOptions,
      isPro,
      missionsLimitDialog,
      getProLink,
      dateMask,
    };
  }
});
</script>

<style lang="scss" scoped>
.loyalty-suite-challenge {
  display: flex;
  flex-wrap: wrap;
  width: 100%;

  &__title {
    display: flex;
    align-items: center;
    width: 100%;
    margin-bottom: 25px;

    &-text {
      display: flex;
      font-size: 22px;
    }
  }

  .loyalty-suite-form {
    width: 700px;

    .loyalty-suite-form__section_tabs {
      .loyalty-suite-form__conditions {
        padding: 0;
        margin: 10px 0 0 0;
        border-radius: 0;
        box-shadow: none;
      }

      .loyalty-suite-form__rewards {
        padding: 0;
        margin: 10px 0 0 0;
        border-radius: 0;
        box-shadow: none;
      }
    }
  }
}
</style>
