<template>
  <div class="loyalty-suite-wrapper">
    <div class="loyalty-suite-loading" v-if="loading">
      <div class="loyalty-suite-spinner"></div>
    </div>

    <template v-else>
      <div v-if="errorMessage" class="loyalty-suite-api-error-message">
        <span>{{ errorMessage }}</span>
      </div>
      <template v-if="!error">
        <div class="loyalty-suite-challenge">
          <div class="loyalty-suite-challenge__breadcrumbs">
            {{ $t('challenge') }}
          </div>

          <div class="loyalty-suite-challenge__header">
            <img
              v-if="challenge.image_type === 'icon' && challenge.icon"
              :src="challenge.icon"
              class="loyalty-suite-challenge__icon"
            >
            <img
              v-if="challenge.image_type === 'image' && challenge.image"
              :src="challenge.image"
              class="loyalty-suite-challenge__image"
            >
            <div class="loyalty-suite-challenge__title">
              {{ challenge.name }}
            </div>
          </div>

          <div
            v-if="challenge.description && challenge.description.length"
            v-html="challenge.description"
            class="loyalty-suite-challenge__description"
          />

          <div
            v-if="(challenge.start_date && isFuture(challenge.start_date_raw)) || challenge.end_date"
            class="loyalty-suite-challenge__date"
          >
            <div
              v-if="challenge.start_date && isFuture(challenge.start_date_raw)"
              class="loyalty-suite-challenge__date-start"
            >
              {{ $t('startsOn') }}: {{ challenge.start_date }}
            </div>

            <div
              v-if="challenge.end_date"
              class="loyalty-suite-challenge__date-expired"
            >
              {{
                isPast(challenge.end_date_raw)
                  ? $t('challengeExpiredOn')
                  : $t('availableUntilChallenge')
              }}: {{ challenge.end_date }}
            </div>
          </div>

          <div
            v-if="challenge.progress > 0"
            class="loyalty-suite-challenge__progress"
          >
            <div class="loyalty-suite-challenge__progress-title">
              {{ $t('challengeProgress') }}:
            </div>
            <div class="loyalty-suite-challenge__progress-wrapper">
              <div
                class="loyalty-suite-challenge__progress-bar"
                :style="{ width: challenge.progress + '%' }"
              />
            </div>
            <div class="loyalty-suite-challenge__progress-value">
              {{ challenge.progress }}% {{ $t('complete') }}
            </div>
          </div>

          <div class="loyalty-suite-challenge__tabs">
            <span
              v-for="tab in tabs"
              :key="tab.name"
              class="loyalty-suite-challenge__tabs-button"
              :class="{
                'loyalty-suite-challenge__tabs-button_active':
                  activeTab === tab.name
              }"
              @click="activeTab = tab.name"
            >
              {{ tab.label }}
            </span>
          </div>

          <div class="loyalty-suite-challenge__panels">
            <div
              v-if="activeTab === 'missions'"
              class="loyalty-suite-challenge__panels-container"
            >
              <Conditions
                :conditions="challengeConditions"
                :order="challenge.condition_order"
                :currency="currency"
                :entity-id="parseInt(route.params.id as string, 10)"
                entity-type="challenge"
              />
            </div>

            <div
              v-if="activeTab === 'rewards'"
              class="loyalty-suite-challenge__panels-container"
            >
              <ChallengeRewards
                :missions="challenge.missions"
                :rewards="challenge.rewards"
                :order="challenge.condition_order"
                :status="challenge.progress === 100 ? 'complete' : ''"
                :disable-all="challenge.disable_all"
              />
            </div>
          </div>
        </div>
      </template>
    </template>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onBeforeMount, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import Conditions from '../components/Conditions.vue';
import ChallengeRewards from '../components/ChallengeRewards.vue';
import { DateTime } from 'luxon';

export default defineComponent({
  components: { Conditions, ChallengeRewards },
  setup() {
    const loading = ref(true);
    const error = ref<string | null>(null);
    const apiRoutes = window.loyalty_suite_account_data.apiRoutes;
    const nonce = window.loyalty_suite_account_data.nonce;
    const timezone =
      window.loyalty_suite_account_data?.timezone || 'UTC';
    const { t } = useI18n();
    const route = useRoute();
    const activeTab = ref<'missions' | 'rewards'>('missions');
    const challenge = ref<any>({});
    const tabs = ref<{ name: 'missions' | 'rewards'; label: string }[]>([]);
    const currency = ref<{ symbol: string }>({ symbol: '$' });

    const errorMessage = computed(() => {
      if (error.value === '401') {
        return;
      }
      return null;
    });

    const challengeConditions = computed(() => {
      if (!Array.isArray(challenge.value?.missions)) return [];

      return challenge.value.missions
        .map((mission: any, index: number) => {
          if (!mission || !mission.condition) return null;

          return {
            ...mission.condition,
            order: index + 1,
          };
        })
        .filter(Boolean);
    });

    const parseRawDate = (raw?: string | null): DateTime | null => {
      if (!raw) return null;

      let dt: DateTime;

      if (raw.includes('T')) {
        dt = DateTime.fromISO(raw, { zone: 'utc' });
      } else if (raw.includes(':')) {
        dt = DateTime.fromSQL(raw, { zone: 'utc' });
      } else {
        dt = DateTime.fromFormat(raw, 'yyyy-LL-dd', {
          zone: 'utc',
        });
      }

      if (!dt.isValid) {
        return null;
      }

      return dt.setZone(timezone).startOf('day');
    };

    const isPast = (raw: string): boolean => {
      const end = parseRawDate(raw);
      if (!end) return false;

      const now = DateTime.now()
        .setZone(timezone)
        .startOf('day');

      return now > end;
    };

    const isFuture = (raw: string): boolean => {
      const start = parseRawDate(raw);
      if (!start) return false;

      const now = DateTime.now()
        .setZone(timezone)
        .startOf('day');

      return start > now;
    };

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

        if (!response.ok) {
          throw new Error(String(response.status));
        }

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

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

        const response = await fetch(
          buildApiUrl(apiRoutes.account.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(String(response.status));
        }

        const data = await response.json();

        challenge.value = data.challenge || {};

        const missions = Array.isArray(challenge.value.missions)
          ? challenge.value.missions
          : [];
        const rewards = Array.isArray(challenge.value.rewards)
          ? challenge.value.rewards
          : [];

        const hasMissions = missions.length > 0;
        const hasMissionRewards = missions.some(
          (mission: any) =>
            Array.isArray(mission.reward) &&
            mission.reward.length > 0,
        );
        const hasChallengeRewards = rewards.length > 0;

        tabs.value = [];

        if (hasMissions) {
          const label =
            missions.length === 1
              ? t('condition')
              : t('conditions');
          tabs.value.push({ name: 'missions', label });
          activeTab.value = 'missions';
        }

        if (hasChallengeRewards || hasMissionRewards) {
          tabs.value.push({
            name: 'rewards',
            label: t('rewards'),
          });

          if (!hasMissions) {
            activeTab.value = 'rewards';
          }
        }
      } catch (err: any) {
        error.value =
          err.message === '401'
            ? '401'
            : err.message || t('couldNotFetchData');
        console.error('API Error:', error.value);
      }
    };

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

    return {
      loading,
      error,
      errorMessage,
      challenge,
      activeTab,
      tabs,
      currency,
      challengeConditions,
      isPast,
      isFuture,
      route,
    };
  },
});
</script>

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

  &__breadcrumbs {
    display: flex;
    width: 100%;
    font-weight: 700;
    margin-top: 5px;
    margin-bottom: 20px;
    color: var(--loyalty-suite-primary);
  }

  &__header {
    display: flex;
    width: 100%;
    flex-direction: column;
  }

  &__progress {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 400px;
    margin-top: 20px;

    &-title {
      display: flex;
      font-size: 14px;
      font-weight: 700;
      margin-bottom: 7px;
    }

    &-value {
      display: flex;
      font-size: 14px;
      text-transform: lowercase;
    }

    &-wrapper {
      display: flex;
      width: 100%;
      height: 4px;
      border-radius: 8px;
      background: var(--loyalty-suite-borders-40);
      position: relative;
      margin: 0 0 7px 0;
    }

    &-bar {
      display: flex;
      position: absolute;
      left: 0;
      top: 0;
      height: 4px;
      border-radius: 8px;
      background: var(--loyalty-suite-positive);
    }
  }

  &__date {
    display: flex;
    flex-direction: column;
    width: 100%;
    margin-top: 20px;
    border-top: 1px solid var(--loyalty-suite-borders-60);
    border-bottom: 1px solid var(--loyalty-suite-borders-60);
    padding: 10px 0;

    &-start {
      display: flex;
      width: 100%;
      margin: 5px 0;
      font-weight: 700;
      color: var(--loyalty-suite-primary);
    }

    &-expired {
      display: flex;
      width: 100%;
      font-weight: 700;
      margin: 5px 0;
      color: var(--loyalty-suite-primary);
    }
  }

  &__icon {
    display: flex;
    width: 70px;
    height: 70px;
    object-fit: cover;
    margin-bottom: 20px;
  }

  &__image {
    display: flex;
    width: 360px;
    height: 200px;
    object-fit: cover;
    border-radius: 8px;
    margin-bottom: 20px;
  }

  &__title {
    display: flex;
    font-size: 16px;
    font-weight: 700;
    line-height: normal;
  }

  &__description {
    width: 100%;
    margin-top: 20px;

    :deep(p) {
      max-width: 100%;
      font-size: 14px;
      font-style: normal;
      line-height: normal;
      margin-bottom: 16px !important;

      &:last-child {
        margin-bottom: 0 !important;
      }
    }

    :deep(h1),
    :deep(h2),
    :deep(h3),
    :deep(h4),
    :deep(h5),
    :deep(h6) {
      margin-bottom: 16px !important;

      &:last-child {
        margin-bottom: 0 !important;
      }
    }

    :deep(ul),
    :deep(ol) {
      max-width: 100%;
      margin-bottom: 16px;

      &:last-child {
        margin-bottom: 0 !important;
      }

      :deep(li) {
        font-size: 14px;
        font-style: normal;
        line-height: normal;
      }

      &:last-child {
        margin-bottom: 0;
      }
    }

    :deep(a) {
      color: var(--loyalty-suite-primary);
      text-decoration: none;
      transition: 0.3s;

      &:hover {
        color: var(--loyalty-suite-primary-90);
      }
    }

    :deep(iframe),
    :deep(table),
    :deep(video) {
      max-width: 100%;
    }

    :deep(img) {
      max-width: 100%;
      object-fit: cover;
    }
  }

  &__tabs {
    display: flex;
    width: 100%;
    flex-wrap: wrap;
    margin-top: 25px;
    margin-bottom: 15px;

    &-button {
      display: flex;
      margin: 0 10px 10px 0;
      padding: 8px 12px 7px 12px;
      font-size: 14px;
      line-height: normal;
      border-radius: 4px;
      background: var(--loyalty-suite-light);
      outline: 1px solid var(--loyalty-suite-borders-60);
      color: var(--loyalty-suite-dark);
      transition: 0.3s;
      text-decoration: none;

      &.loyalty-suite-challenge__tabs-button_active {
        color: var(--loyalty-suite-primary);
        outline-color: var(--loyalty-suite-primary);

        &:hover {
          cursor: default;
        }
      }

      &:hover {
        cursor: pointer;
        color: var(--loyalty-suite-primary);
        outline-color: var(--loyalty-suite-primary);
      }

      &:last-child {
        margin-right: 0;
      }
    }
  }

  &__panels {
    display: flex;
    width: 100%;
    margin-bottom: 25px;

    &-container {
      display: flex;
      width: 100%;
      flex-direction: column;
    }
  }

  &__order {
    display: flex;
    width: 100%;
    margin-bottom: 20px;
  }
}

@media (max-width: 576px) {
  .loyalty-suite-challenge {
    &__header {
      align-items: center;
    }

    &__image {
      width: 100%;
    }
  }
}
</style>
