<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-rank">
          <div class="loyalty-suite-rank__breadcrumbs">
            {{ $t('ranks') }}
          </div>
          <div v-if="rankSet.show" class="loyalty-suite-rankset">
            <div class="loyalty-suite-rankset__title">
              {{ rankSet.name }}
            </div>
            <div v-if="rankSet.description.length" v-html="rankSet.description"
              class="loyalty-suite-rankset__description"></div>
          </div>
          <div class="loyalty-suite-loading-local" v-if="isCurrentLoading">
            <div class="loyalty-suite-spinner"></div>
          </div>
          <div v-else class="loyalty-suite-rank__wrapper">
            <div class="loyalty-suite-rank__choice">
              <Select v-model="selectedRank" :options="rankSet.ranks" :label-key="'name'" :value-key="'id'"
                :img-key="'icon'" :current-key="Number(rankSet.user_rank.id) ?? null" :label="$t('ranks')" />
            </div>
            <div v-if="rankSet.current.progress > 0" class="loyalty-suite-rank__progress">
              <div class="loyalty-suite-rank__progress-title">
                {{ $t('rankProgress') }}:
              </div>
              <div class="loyalty-suite-rank__progress-wrapper">
                <div class="loyalty-suite-rank__progress-bar" :style="{ width: rankSet.current.progress + '%' }"></div>
              </div>
              <div class="loyalty-suite-rank__progress-value">
                {{ rankSet.current.progress }}% {{ $t('complete') }}
              </div>
            </div>
            <div class="loyalty-suite-rank__tabs">
              <span v-for="tab in tabs" :key="tab.name" class="loyalty-suite-rank__tabs-button"
                :class="{ 'loyalty-suite-rank__tabs-button_active': activeTab === tab.name }"
                @click="activeTab = tab.name">
                {{ tab.label }}
              </span>
            </div>
            <div class="loyalty-suite-rank__panels">
              <div v-if="activeTab === 'conditions'" class="loyalty-suite-rank__panels-container">
                <div v-if="rankSet.current.reward_sources.length" class="loyalty-suite-rank__reward-sources">
                  <div
                    v-for="(reward, idx) in rankSet.current.reward_sources"
                    :key="idx"
                    class="loyalty-suite-rank__reward-sources-item"
                  >
                    <template v-if="reward.source === 'challenge'">
                      {{ $t('needChallengeCompleteRank') }}:
                      <router-link
                        :to="`/challenge/${reward.challenge_id}`"
                        class="loyalty-suite-rank__reward-sources-link"
                      >
                        {{ reward.challenge_name }}
                      </router-link>
                    </template>

                    <template v-else-if="reward.source === 'mission'">
                      {{ $t('needChallengeMissionCompleteRank') }}:
                      <router-link
                        :to="`/challenge/${reward.challenge_id}`"
                        class="loyalty-suite-rank__reward-sources-link"
                      >
                        {{ reward.challenge_name }}
                      </router-link>
                    </template>
                  </div>
                </div>
                <Conditions :conditions="rankSet.current.conditions" :order="rankSet.current.condition_order"
                  :currency="currency" :entityId="parseInt(route.params.id)" :entityType="'rank'" />
              </div>
              <div v-if="activeTab === 'rewards'" class="loyalty-suite-rank__panels-container">
                <div class="loyalty-suite-rank__rewards">
                  <Reward v-for="(reward, index) in rankSet.current.rewards" :key="reward.id || index" :reward="reward"
                    :status="rankSet.current.progress === 100 ? 'complete' : ''" />
                </div>
              </div>
            </div>
          </div>
        </div>
      </template>
    </template>
  </div>
</template>

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

export default defineComponent({
  components: { Conditions, Reward, Select },
  setup() {
    const loading = ref(true);
    const isCurrentLoading = ref(false);
    const error = ref<string | null>(null);
    const apiRoutes = window.loyalty_suite_account_data.apiRoutes;
    const nonce = window.loyalty_suite_account_data.nonce;
    const { t } = useI18n();
    const route = useRoute();
    const selectedRank = ref<number | null>(null);
    const activeTab = ref('conditions');
    const tabs = ref<{ name: string; label: string }[]>([]);
    const currency = ref({ symbol: '$' });
    const rankSet = ref([]);

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

    watch(selectedRank, async (newRankId) => {
      if (newRankId) {
        try {
          isCurrentLoading.value = true;

          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);
              }
            });
            return url.toString();
          };

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

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

          const data = await response.json();
          rankSet.value.current = data.rank_set.current;

          tabs.value = [];

          if (
            (rankSet.value.current.conditions && rankSet.value.current.conditions.length) ||
            (rankSet.value.current.reward_sources && rankSet.value.current.reward_sources.length)
          ) {
            const condCount = (rankSet.value.current.conditions?.length || 0) + (rankSet.value.current.reward_sources?.length || 0);
            const label = condCount === 1 ? t('condition') : t('conditions');
            tabs.value.push({ name: 'conditions', label });
          } else {
            activeTab.value = 'rewards';
          }

          if (rankSet.value.current.rewards.length) {
            const label = rankSet.value.current.rewards.length === 1 ? t('reward') : t('rewards');
            tabs.value.push({ name: 'rewards', label });
          }

        } catch (err: any) {
          error.value = err.message === '401' ? '401' : err.message || t('couldNotFetchData');
          console.error('API Error:', error.value);
        } finally {
          isCurrentLoading.value = false;
        }
      }
    });

    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(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 fetchRank = async () => {
      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);
            }
          });
          return url.toString();
        };

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

        const data = await response.json();

        rankSet.value = data.rank_set;
        selectedRank.value = data.rank_set.current.id;

        if (
            (rankSet.value.current.conditions && rankSet.value.current.conditions.length) ||
            (rankSet.value.current.reward_sources && rankSet.value.current.reward_sources.length)
          ) {
            const condCount = (rankSet.value.current.conditions?.length || 0) + (rankSet.value.current.reward_sources?.length || 0);
            const label = condCount === 1 ? t('condition') : t('conditions');
            tabs.value.push({ name: 'conditions', label });
          } else {
          activeTab.value = 'rewards';
        }

        if (rankSet.value.current.rewards.length) {
          const label = rankSet.value.current.rewards.length === 1 ? t('reward') : t('rewards');
          tabs.value.push({ name: 'rewards', label });
        }

      } 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([fetchRank(), fetchCurrency()]);
      } catch (err) {
        console.error('Api error:', err);
      } finally {
        loading.value = false;
      }
    });

    return { loading, error, errorMessage, isCurrentLoading, activeTab, tabs, selectedRank, rankSet, currency, route };
  },
});
</script>

<style lang="scss" scoped>
.loyalty-suite-rankset {
  display: flex;
  width: 100%;
  flex-direction: column;
  margin-bottom: 20px;

  &__title {
    display: flex;
    width: 100%;
    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;
    }
  }
}

.loyalty-suite-rank {
  display: flex;
  width: 100%;
  flex-direction: column;

  &__wrapper {
    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);
  }

  &__choice {
    display: flex;
    width: 100%;
  }

  &__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);
    }
  }

  &__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: .3s;
      text-decoration: none;

      &.loyalty-suite-rank__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;
    }
  }

  &__rewards {
    width: calc(100% + 20px);
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    margin: -5px -10px 0 -10px;
  }

  &__reward-sources {
    display: flex;
    width: 100%;
    flex-direction: column;
    margin-top: -10px;
    margin-bottom: 25px;
    &-item {
      display: flex;
      align-items: center;
      width: 100%;
      margin-bottom: 10px;
      &:last-child {
        margin-bottom: 0;
      }
    }
    a.loyalty-suite-rank__reward-sources-link {
      align-items: center;
      margin: 0;
      font-size: 14px;
      font-weight: 700;
      line-height: 1;
      color: var(--loyalty-suite-primary);
      transition: 0.3s;
      text-decoration: none !important;
      margin-left: 4px;
      &:hover {
        color: var(--loyalty-suite-primary-90);
      }
    }
  }
}
</style>
