<template>
  <div class="loyalty-suite-form__section loyalty-suite-form__rewards">
    <div class="loyalty-suite-form__title">
      {{ postType === 'challenge' ? $t('challengeRewards') : $t('rewards') }}
      <q-icon name="info_outline" size="18px" class="loyalty-suite-form__row-hint">
        <q-tooltip anchor="top right" self="top right">
          {{ $t(`use_rewards_${postType}`) }}
        </q-tooltip>
      </q-icon>
    </div>

    <div v-if="localRewards.length > 0" class="loyalty-suite-form-rewards-list">
      <div v-for="(item, index) in localRewards" :key="index" class="loyalty-suite-form-rewards-list-item">
        <div class="loyalty-suite-form-rewards-list-item__content">
          <template v-for="(reward, rewardIndex) in formatRewardValue(item, processedRewardsFields)" :key="rewardIndex">
            <div class="loyalty-suite-form-rewards-list-item__content-wrapper"
              v-if="rewardIndex === 0 || expandedRewards[index]">
              <div class="loyalty-suite-form-rewards-list-item__content-label">
                {{ reward.label }}
              </div>
              <div class="loyalty-suite-form-rewards-list-item__content-value">
                <template v-if="['fixed_discount_value'].includes(reward.key)">
                  {{ formatCurrency(Number(reward.value), currency) }}
                </template>
                <template v-else-if="['units_value'].includes(reward.key)">
                  {{ formatCurrency(Number(reward.value), currency, true) }}
                </template>
                <template v-else>
                  {{ reward.value }}
                </template>
                <span v-if="['percentage_discount_value'].includes(reward.key)">%</span>
                <div v-if="rewardIndex === 0" class="loyalty-suite-form-rewards-list-item__action">
                  <div class="loyalty-suite-form-conditions-list-item__action-wrapper">
                    <q-btn v-if="formatRewardValue(item, processedRewardsFields).length > 1"
                      class="loyalty-suite-form-rewards-list-item__toggle"
                      icon="notes" color="primary" @click="toggleRewards(index)" />
                    <q-btn icon="edit" class="loyalty-suite-form-rewards-list-item__edit" color="primary"
                      :loading="changeLoading" @click="openEditRewardModal(index)" />
                    <q-btn icon="delete" color="negative" :loading="changeLoading"
                      @click="openRemoveRewardModal(index)" />
                  </div>
                </div>
              </div>
            </div>
          </template>
        </div>
      </div>
    </div>

    <div
      class="loyalty-suite-form__row loyalty-suite-form__row_full-width loyalty-suite-form__row_align-left loyalty-suite-form__add-reward">
      <q-btn outline color="primary" icon="add" :label="$t('addReward')" :loading="changeLoading"
        @click="openAddRewardModal"></q-btn>
    </div>

    <RewardsFields v-model:rewardModal="rewardModal" :rewardsFields="processedRewardsFields"
      :requiredFields="requiredFields" :loading="changeLoading" :currency="currency"
      :initialData="editingRewardIndex !== null ? localRewards[editingRewardIndex] : null" @update-reward="updateReward"
      @add-reward="addReward" />

    <q-dialog v-model="confirmDeleteReward">
      <q-card>
        <q-card-section>
          <span>{{ $t('rewardDelete') }}</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="removeReward(rewardIndex)" />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <q-dialog v-model="showDuplicateWarning">
      <q-card>
        <q-card-section>
          <div class="loyalty-suite-warning-text">{{ $t('rewardAlreadyExists') }}</div>
        </q-card-section>
        <q-card-actions align="center">
          <q-btn :label="$t('ok')" color="primary" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, nextTick, watch, PropType } from 'vue';
import { useI18n } from 'vue-i18n';
import RewardsFields from './RewardsFields.vue';
import { formatCurrency } from '../utils/formatters';

export default defineComponent({
  components: { RewardsFields },
  props: {
    modelValue: {
      type: Array as PropType<Record<string, any>[]>,
      required: true,
    },
    rewardsFields: {
      type: Array as PropType<Record<string, any>[]>,
      required: true,
    },
    changeLoading: {
      type: Boolean,
      required: true,
    },
    postType: {
      type: String,
      required: true,
    },
    currency: {
      type: Array,
      required: true,
    },
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const { t } = useI18n();
    const confirmDeleteReward = ref(false);
    const rewardIndex = ref<number | null>(null);
    const expandedRewards = ref<Record<number, boolean>>({});
    const editingRewardIndex = ref<number | null>(null);
    const showDuplicateWarning = ref(false);
    const rewardModal = ref(false);
    const requiredFields = ref<string[]>([]);
    const localRewards = ref([...props.modelValue]);
    const isPro = window.loyalty_suite_admin_data.isPro;
    const isWoo = window.loyalty_suite_admin_data.isWooEnabled;
    const processedRewardsFields = ref<Array<{
      key: string;
      type: string;
      options?: Array<{ value: string; label: string }>;
      dependency?: string[];
    }>>([]);

    const PRO_REWARDS = [
      'rewards_fixed_discount',
      'rewards_percentage_discount',
      'rewards_rank',
      'rewards_achievement',
    ];

    watch(
      [() => props.modelValue, () => processedRewardsFields.value],
      ([newRewards, newFields]) => {
        if (!newFields || newFields.length === 0) return;
        localRewards.value = mapRewardLabels(newRewards, newFields);
      },
      { deep: true, immediate: true }
    );

    watch(
      () => props.rewardsFields,
      (newFields) => {

        processedRewardsFields.value = (newFields || []).map((field: any) => {
          if (field.required) {
            requiredFields.value.push(field.key);
          }

          let fieldOptions: { value: string; label: string; disabled?: boolean; __pro?: boolean }[] = [];

          if (Array.isArray(field.options)) {
            fieldOptions = field.options.map((value: string) => ({
              value,
              label: t(value),
            }));
          } else if (field.options && typeof field.options === 'object') {
            fieldOptions = Object.entries(field.options as Record<string, string>).map(
              ([key, label]) => ({
                value: key,
                label: t(label),
              })
            );
          }

          if (field.key === 'reward') {
            let options = fieldOptions.slice();

            if (!isPro) {
              const have = new Set(options.map(o => o.value));
              PRO_REWARDS.forEach(k => {
                if (!have.has(k)) {
                  options.push({ value: k, label: t(k), __pro: true });
                }
              });
            }

            if (!isWoo) {
              const WOO_REWARDS = new Set([
                'rewards_coupon',
                'rewards_fixed_discount',
                'rewards_percentage_discount',
              ]);
              options = options.map(opt => {
                if (!opt.disabled && WOO_REWARDS.has(opt.value)) {
                  return { ...opt, __wc: true };
                }
                return opt;
              });
            }

            if (props.postType === 'rank' || props.postType === 'achievement') {
              options = options.filter(o => o.value !== 'rewards_rank' && o.value !== 'rewards_achievement');
            }

            const GROUP_ORDER: Array<{ id: string; label: string }> = [
              { id: 'woocommerce',    label: 'WooCommerce' },
              { id: 'loyaltyProgram', label: t('loyaltyProgram') },
            ];

            const VALUE_TO_GROUP: Record<string, string> = {
              rewards_coupon: 'woocommerce',
              rewards_fixed_discount: 'woocommerce',
              rewards_percentage_discount: 'woocommerce',

              rewards_units: 'loyaltyProgram',
              rewards_rank: 'loyaltyProgram',
              rewards_achievement: 'loyaltyProgram',
            };

            const grouped: Record<string, Array<{ value: string; label: string }>> = {};
            options.forEach(opt => {
              const g = VALUE_TO_GROUP[opt.value];
              (grouped[g] ||= []).push(opt);
            });

            const finalOptions: Array<{ value: string; label: string; disabled?: boolean }> = [];
            GROUP_ORDER.forEach(g => {
              const items = grouped[g.id] || [];
              if (items.length === 0) return;
              finalOptions.push({ value: g.id, label: g.label, disabled: true });
              finalOptions.push(...items);
            });

            fieldOptions = finalOptions;
          }

          return {
            key: field.key,
            type: field.type || 'single',
            options: fieldOptions,
            dependency: field.dependency,
            default: field.default || null,
          };
        });
      },
      { deep: true, immediate: true }
    );

    const addReward = (reward: Record<string, any>) => {
      const keyToAdd = dedupeKey(reward);
      console.log('Adding reward with key:', keyToAdd);

      const isDuplicate = localRewards.value.some(existing => dedupeKey(existing) === keyToAdd);

      if (isDuplicate) {
        showDuplicateWarning.value = true;
        return;
      }

      localRewards.value.push(reward);
      emit('update:modelValue', [...localRewards.value]);
    };

    const updateReward = (updatedReward: Record<string, any>) => {
      if (editingRewardIndex.value !== null) {
        const keyUpdated = dedupeKey(updatedReward);
        const duplicate = localRewards.value.some((reward, index) =>
          index !== editingRewardIndex.value && dedupeKey(reward) === keyUpdated
        );

        if (duplicate) {
          showDuplicateWarning.value = true;
          return;
        }

        localRewards.value[editingRewardIndex.value] = updatedReward;
        emit('update:modelValue', [...localRewards.value]);
        editingRewardIndex.value = null;
      }
    };

    const removeReward = (index: number | null) => {
      if (index !== null) {
        localRewards.value.splice(index, 1);
        emit('update:modelValue', [...localRewards.value]);
      }
    };

    const openRemoveRewardModal = (index: number) => {
      confirmDeleteReward.value = true;
      rewardIndex.value = index;
    };

    const openEditRewardModal = (index: number) => {
      editingRewardIndex.value = index;
      rewardModal.value = false;
      nextTick(() => {
        rewardModal.value = true;
      });
    };

    const openAddRewardModal = async () => {
      editingRewardIndex.value = null;
      rewardModal.value = false;
      await nextTick();
      rewardModal.value = true;
    };

    const toggleRewards = (index: number) => {
      expandedRewards.value[index] = !expandedRewards.value[index];
    };

    const formatRewardValue = (reward: Record<string, any>, rewardsFields: any[]): { label: string; value: string, key: string }[] => {
      if (!reward || typeof reward !== 'object') return [];

      return rewardsFields
        .map((field) => {
          const value = reward[field.key];
          if (!value || (Array.isArray(value) && value.length === 0)) return null;

          return {
            label: `${t(`in_${field.key}`)}`,
            value: (() => {
              switch (field.type) {
                case 'primary':
                  return typeof value === 'object' && 'label' in value ? value.label : String(value);

                case 'api_multiselect':
                  return Array.isArray(value) ? value.map((item: any) => item.label || item.value).join(', ') : '';

                case 'datepicker':
                  return typeof value === 'object' && 'from' in value && 'to' in value
                    ? `${value.from} - ${value.to}`
                    : String(value);

                case 'number':
                  return Number(value);

                case 'percent':
                  return Number(value);

                case 'single':
                default:
                  return typeof value === 'object' && 'label' in value ? value.label : String(value);
              }
            })(),
            key: field.key,
          };
        })
        .filter((item): item is { label: string; value: string, key: string } => !!item && !!item.value);
    };

    const mapRewardLabels = (rewards: any[], rewardsFields: any[]): any[] => {
      if (!Array.isArray(rewardsFields)) return rewards;

      const getUpdatedLabel = (fieldKey: string, value: any) => {
        const field = rewardsFields.find((f) => f.key === fieldKey);
        return field?.options?.find((opt: any) => opt.value === value)?.label || null;
      };

      return rewards.map((reward) => {
        const updatedReward = { ...reward };

        if (reward.reward?.value) {
          const newLabel = getUpdatedLabel('reward', reward.reward.value);
          if (newLabel) updatedReward.reward.label = newLabel;
        }

        return updatedReward;
      });
    };

    const walletId = (r: Record<string, any>) => (r?.rewards_wallet?.value ?? null);

    const dedupeKey = (r: Record<string, any>) => {
      const type = String(r?.reward?.value || '');
      if (type === 'rewards_units') {
        const id = walletId(r);
        return `rewards_units:${id === null ? 'none' : String(id)}`;
      }
      return type;
    };

    return {
      confirmDeleteReward,
      openRemoveRewardModal,
      openAddRewardModal,
      openEditRewardModal,
      rewardIndex,
      requiredFields,
      toggleRewards,
      expandedRewards,
      rewardModal,
      showDuplicateWarning,
      editingRewardIndex,
      updateReward,
      addReward,
      removeReward,
      formatRewardValue,
      processedRewardsFields,
      localRewards,
      formatCurrency,
      isWoo
    }
  }
})
</script>
