<template>
  <div class="loyalty-suite-form__section loyalty-suite-form__conditions">
    <div class="loyalty-suite-form__title">
      {{ postType === 'mission' ? $t('condition') : $t('conditions') }}
      <q-icon name="info_outline" size="18px" class="loyalty-suite-form__row-hint">
        <q-tooltip anchor="top right" self="top right">
          {{ $t(`use_conditions_${postType}`) }}
        </q-tooltip>
      </q-icon>
    </div>

    <div v-if="localConditions.length > 0" class="loyalty-suite-form-conditions-list">
      <div v-for="(item, index) in localConditions" :key="index" class="loyalty-suite-form-conditions-list-item">
        <div class="loyalty-suite-form-conditions-list-item__content">
          <template v-for="(condition, conditionIndex) in formatConditionValue(item, processedConditionsFields)"
            :key="conditionIndex">
            <div class="loyalty-suite-form-conditions-list-item__content-wrapper"
              v-if="conditionIndex === 0 || expandedConditions[index]">
              <div class="loyalty-suite-form-conditions-list-item__content-label">
                {{ condition.label }}
                <template v-if="postType !== 'mission' && conditionIndex === 0">
                  {{ '#' + (index + 1) }}
                </template>
              </div>
              <div class="loyalty-suite-form-conditions-list-item__content-value">
                <template v-if="condition.type === 'textarea'">
                  <textarea :id="conditionIndex" class="loyalty-suite-form-conditions-list-item__textarea" readonly
                    rows="8" resize="none">{{ condition.value }}</textarea>
                </template>
                <template
                  v-else-if="condition.type === 'goal' && ['purchase_amount'].includes(item.condition?.value)">
                  {{ formatCurrency(Number(condition.value), currency) }}
                </template>
                <template
                  v-else-if="condition.type === 'goal' && ['earned_units', 'units_spent'].includes(item.condition?.value)">
                  {{ formatCurrency(Number(condition.value), currency, true) }}
                </template>
                <template v-else>
                   {{ condition.value }}
                </template>
                <div v-if="conditionIndex === 0" class="loyalty-suite-form-conditions-list-item__action">
                  <div class="loyalty-suite-form-conditions-list-item__action-wrapper">
                    <q-btn
                      v-if="postType !== 'mission'"
                      icon="arrow_upward"
                      class="loyalty-suite-form-conditions-list-item__move"
                      color="primary"
                      :disable="index === 0 || changeLoading"
                      @click="moveConditionUp(index)"
                    />
                    <q-btn
                      v-if="postType !== 'mission'"
                      icon="arrow_downward"
                      class="loyalty-suite-form-conditions-list-item__move"
                      color="primary"
                      :disable="index === localConditions.length - 1 || changeLoading"
                      @click="moveConditionDown(index)"
                    />
                    <q-btn v-if="formatConditionValue(item, processedConditionsFields).length > 1"
                      class="loyalty-suite-form-conditions-list-item__toggle"
                      icon="notes" color="primary" @click="toggleConditions(index)" />
                    <q-btn icon="edit" class="loyalty-suite-form-conditions-list-item__edit" color="primary"
                      :loading="changeLoading" @click="openEditConditionModal(index)" />
                    <q-btn icon="delete" color="negative" :loading="changeLoading"
                      @click="openRemoveConditionModal(index)" />
                  </div>
                </div>
              </div>
            </div>
          </template>
        </div>
      </div>
    </div>

    <div v-if="!(postType === 'mission' && localConditions.length > 0)"
      class="loyalty-suite-form__row loyalty-suite-form__row_full-width loyalty-suite-form__row_align-left loyalty-suite-form__add-condition">
      <q-btn outline color="primary" icon="add" :label="$t('addCondition')" :loading="changeLoading"
        @click="openAddConditionModal"></q-btn>
    </div>

    <ConditionsFields v-model:conditionModal="conditionModal" :conditionsFields="processedConditionsFields"
      :requiredFields="requiredFields" :loading="changeLoading" :currency="currency"
      :initialData="editingConditionIndex !== null ? localConditions[editingConditionIndex] : null"
      @update-condition="updateCondition" @add-condition="addCondition" />

    <q-dialog v-model="confirmDeleteCondition">
      <q-card>
        <q-card-section>
          <span>{{ $t('conditionDelete') }}</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="removeCondition(conditionIndex)" />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <q-dialog v-model="showOnlyOneWarning">
      <q-card>
        <q-card-section>
          <div class="loyalty-suite-warning-text">{{ $t('conditionOnlyOne') }}</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 ConditionsFields from './ConditionsFields.vue';
import { formatCurrency } from '../utils/formatters';

export default defineComponent({
  components: { ConditionsFields },
  props: {
    modelValue: {
      type: Array as PropType<Record<string, any>[]>,
      required: true,
    },
    conditionsFields: {
      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 confirmDeleteCondition = ref(false);
    const conditionIndex = ref<number | null>(null);
    const expandedConditions = ref<Record<number, boolean>>({});
    const editingConditionIndex = ref<number | null>(null);
    const showOnlyOneWarning = ref(false);
    const conditionModal = ref(false);
    const requiredFields = ref<string[]>([]);
    const isPro = window.loyalty_suite_admin_data.isPro;
    const isWoo = window.loyalty_suite_admin_data.isWooEnabled;
    const processedConditionsFields = ref<Array<{
      key: string;
      type: string;
      options?: Array<{ value: string; label: string }>;
      dependency?: string[];
    }>>([]);

    const PRO_CONDITIONS = [
      'refer_for_purchase',
      'refer_for_signup',
      'add_reviews',
      'follow_us',
      'share_on',
      'publish_content',
      'units_spent',
    ];

    const addOrderToConditions = (conditions: any[]) => {
      return conditions.map((condition, index) => ({
        ...condition,
        order: index + 1,
      }));
    };
    const localConditions = ref(addOrderToConditions([...props.modelValue]));

    watch(
      [() => props.modelValue, () => processedConditionsFields.value],
      ([newConditions, newFields]) => {
        if (!newFields || newFields.length === 0) return;
        localConditions.value = addOrderToConditions(mapConditionLabels(newConditions, newFields));
      },
      { deep: true, immediate: true }
    );

    watch(
      () => props.conditionsFields,
      (newFields) => {
        processedConditionsFields.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 === 'condition') {

            if (!isPro) {
              const existing = new Set(fieldOptions.filter(o => !o.disabled).map(o => o.value));
              PRO_CONDITIONS.forEach(proKey => {
                if (!existing.has(proKey)) {
                  const label = t(proKey);
                  fieldOptions.push({
                    value: proKey,
                    label,
                    __pro: true,
                  } as any);
                }
              });
            }

            if (!isWoo) {
              const WOO_KEYS = new Set([
                'purchase_amount',
                'place_orders',
                'buy_products',
                'refer_for_purchase',
                'add_reviews',
              ]);
              fieldOptions = fieldOptions.map(opt => {
                if (!opt.disabled && WOO_KEYS.has(opt.value)) {
                  return { ...opt, __wc: true };
                }
                return opt;
              });
            }

            const GROUP_ORDER: Array<{ id: string; labelKey: string }> = [
              { id: 'activity',        labelKey: 'activity' },
              { id: 'woocommerce',     labelKey: 'WooCommerce' },
              { id: 'socialNetworks',  labelKey: 'socialNetworks' },
              { id: 'loyaltyProgram',  labelKey: 'loyaltyProgram' },
            ];

            const VALUE_TO_GROUP: Record<string, string> = {

              purchase_amount: 'woocommerce',
              place_orders: 'woocommerce',
              buy_products: 'woocommerce',
              refer_for_purchase: 'woocommerce',
              add_reviews: 'woocommerce',

              follow_us: 'socialNetworks',
              share_on: 'socialNetworks',
              publish_content: 'socialNetworks',

              earned_units: 'loyaltyProgram',
              units_spent: 'loyaltyProgram',

              refer_for_signup: 'activity',
              registration_exists: 'activity',
              new_registration: 'activity',
              add_comments: 'activity',
            };

            const grouped: Record<string, Array<{ value: string; label: string }>> = {};
            fieldOptions.forEach(opt => {
              const group = VALUE_TO_GROUP[opt.value] || 'activity';
              if (!grouped[group]) grouped[group] = [];
              grouped[group].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: t(g.labelKey),
                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 addCondition = (condition: Record<string, any>) => {
      if (props.postType === 'mission' && localConditions.value.length > 0) {
        showOnlyOneWarning.value = true;
        return;
      }

      localConditions.value.push(condition);
      localConditions.value = addOrderToConditions(localConditions.value);
      emit('update:modelValue', [...localConditions.value]);
    };

    const updateCondition = (updatedCondition: Record<string, any>) => {
      if (editingConditionIndex.value !== null) {
        localConditions.value[editingConditionIndex.value] = updatedCondition;
        localConditions.value = addOrderToConditions(localConditions.value);
        emit('update:modelValue', [...localConditions.value]);
        editingConditionIndex.value = null;
      }
    };

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

    const openRemoveConditionModal = (index: number) => {
      confirmDeleteCondition.value = true;
      conditionIndex.value = index;
    };

    const openEditConditionModal = (index: number) => {
      editingConditionIndex.value = index;
      conditionModal.value = false;
      nextTick(() => {
        conditionModal.value = true;
      });
    };

    const openAddConditionModal = async () => {
      editingConditionIndex.value = null;
      conditionModal.value = false;
      await nextTick();
      conditionModal.value = true;
    };

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

    const formatConditionValue = (condition: Record<string, any>, conditionsFields: any[]): { label: string; value: string, key: string, type: string }[] => {
      if (!condition || typeof condition !== 'object') return [];

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

          const label = props.postType === 'mission'
            ? `${t(`in_${field.key}`)}`
            : `${t(`in_${field.key}`)}`;

          let formattedValue = '';

          switch (field.type) {
            case 'primary':
              formattedValue = typeof value === 'object' && 'label' in value
                ? value.label
                : String(value);
              break;

            case 'goal':
              formattedValue = Number(condition.goal)
              break;

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

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

            case 'text_input':
              formattedValue = String(value);
              break;

            case 'single':
            default:
              formattedValue = typeof value === 'object' && 'label' in value
                ? value.label
                : String(value);
              break;
          }

          return {
            label,
            value: formattedValue,
            key: field.key,
            type: field.type,
          };
        })
        .filter((item): item is { label: string; value: string; key: string; type: string; prefix?: string } =>
          !!item && !!item.value);
    };

    const mapConditionLabels = (conditions: any[], conditionsFields: any[]): any[] => {
      if (!Array.isArray(conditionsFields)) return conditions;

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

      return conditions.map((condition) => {
        const updatedCondition = { ...condition };

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

        return updatedCondition;
      });
    };

    const moveConditionUp = (index: number) => {
      if (index <= 0) return;

      const temp = localConditions.value[index];

      localConditions.value[index] = localConditions.value[index - 1];
      localConditions.value[index - 1] = temp;
      localConditions.value = addOrderToConditions(localConditions.value);
      emit('update:modelValue', [...localConditions.value]);
    };

    const moveConditionDown = (index: number) => {
      if (index >= localConditions.value.length - 1) return;

      const temp = localConditions.value[index];
      localConditions.value[index] = localConditions.value[index + 1];
      localConditions.value[index + 1] = temp;
      localConditions.value = addOrderToConditions(localConditions.value);
      emit('update:modelValue', [...localConditions.value]);
    };

    return {
      confirmDeleteCondition,
      openRemoveConditionModal,
      openAddConditionModal,
      openEditConditionModal,
      conditionIndex,
      requiredFields,
      toggleConditions,
      expandedConditions,
      conditionModal,
      showOnlyOneWarning,
      editingConditionIndex,
      updateCondition,
      addCondition,
      removeCondition,
      formatConditionValue,
      processedConditionsFields,
      localConditions,
      formatCurrency,
      moveConditionUp,
      moveConditionDown,
      isWoo
    }
  }
})
</script>
