<template>
  <q-scroll-area class="loyalty-suite-wrapper">
    <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-user-rewards">
        <h1 class="loyalty-suite-user-rewards__title">{{ $t('userRewardsListMenu') }}</h1>
        <div class="loyalty-suite-list__input-wrapper">
          <input
            v-model="searchQuery"
            :placeholder="$t('searchUser')"
            class="loyalty-suite-list__input"
            @update:model-value="onSearchChange"
          />
          <span v-if="searchQuery.length > 0" @click="clearQuery" class="loyalty-suite-list__input-clear">&times</span>
        </div>
      </div>
      <div class="loyalty-suite-user-rewards__table">
        <q-table flat bordered separator="cell" :rows="rewards" :columns="columns" row-key="id" :loading="loading"
          :rows-per-page-options="[10, 20, 50]" :rows-per-page-label="$t('recordsPerPage')"
          :no-data-label="$t('userRewardsTable.notFoundRewards')" v-model:pagination="pagination"
          :loading-label="$t('tableLoading')" @request="fetchUserRewards">
          <template v-slot:body-cell-orders_quota="props">
            <q-td :props="props">
              {{ props.row.orders_quota === 'infinity' ? '∞' : props.row.orders_quota }}
            </q-td>
          </template>
          <template v-slot:body-cell-orders_remaining="props">
            <q-td :props="props">
              {{ props.row.orders_remaining === 'infinity' ? '∞' : props.row.orders_remaining }}
            </q-td>
          </template>
          <template v-slot:body-cell-received="props">
            <q-td :props="props">
              {{ props.row.received === null ? '' : props.row.received }}
            </q-td>
          </template>
          <template v-slot:body-cell-expired="props">
            <q-td :props="props">
              {{ props.row.expired === null ? $t('never') : props.row.expired }}
            </q-td>
          </template>
          <template v-slot:body-cell-status="props">
            <q-td :props="props">
              <q-badge
                :color="props.row.status === 'active' || props.row.status === 'received'
                  ? 'green'
                  : 'red'"
                rounded
              >
                {{ $t(props.row.status) }}
              </q-badge>
            </q-td>
          </template>
          <template v-slot:loading>
            <q-inner-loading showing color="primary" />
          </template>
        </q-table>
      </div>
    </template>
  </q-scroll-area>
</template>

<script lang="ts">
import { defineComponent, ref, computed, onBeforeMount } from 'vue';
import { useI18n } from 'vue-i18n';

export default defineComponent({
  setup() {
    const loading = ref(true);
    const error = ref<string | null>(null);
    const apiRoutes = window.loyalty_suite_admin_data.apiRoutes;
    const nonce = window.loyalty_suite_admin_data.nonce;
    const { t } = useI18n();
    const rewards = ref([]);
    const searchQuery = ref('');

    const pagination = ref({
      page: 1,
      rowsPerPage: 10,
      rowsNumber: 0,
      sortBy: 'received_at',
      descending: true,
    });

    const columns = computed(() => [
      { name: 'user', label: t('user'), field: 'user', align: 'left', sortable: false, style: 'width: 20%', headerStyle: 'width: 20%;' },
      { name: 'reward', label: t('reward'), field: 'reward', align: 'left', sortable: false, style: 'width: 20%', headerStyle: 'width: 20%;' },
      { name: 'orders_quota', label: t('rewardOrdersQuota'), field: 'orders_quota', align: 'left', sortable: false, style: 'width: 10%', headerStyle: 'width: 10%;' },
      { name: 'orders_remaining', label: t('rewardOrdersRemaining'), field: 'orders_remaining', align: 'left', sortable: false, style: 'width: 10%', headerStyle: 'width: 10%;' },
      { name: 'received', label: t('rewardReceivedAt'), field: 'received', align: 'left', sortable: true, style: 'width: 15%', headerStyle: 'width: 15%;' },
      { name: 'expired', label: t('rewardExpiredAt'), field: 'expired', align: 'left', sortable: false, style: 'width: 15%', headerStyle: 'width: 15%;' },
      { name: 'status', label: t('rewardStatus'), field: 'status', align: 'left', sortable: false, style: 'width: 10%', headerStyle: 'width: 10%;' }
    ]);

    const fetchUserRewards = async (props?: any) => {
      try {
        loading.value = true;
        error.value = null;

        const page = props?.pagination?.page || 1;
        const rowsPerPage = props?.pagination?.rowsPerPage || 10;
        const sortBy = props?.pagination?.sortBy || 'received_at';
        const descending = props?.pagination?.descending ? 'desc' : 'asc';
        const search = encodeURIComponent(searchQuery.value || '');

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

        const response = await fetch(
          buildApiUrl(apiRoutes.admin.user_rewards, {
            page,
            per_page: rowsPerPage,
            order_by: sortBy,
            order: descending,
            search,
          }),
          {
            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();
        rewards.value = Array.isArray(data.rewards) ? data.rewards : [];
        pagination.value = {
          page,
          rowsPerPage,
          rowsNumber: data.total || 0,
          sortBy,
          descending: descending === 'desc',
        };
      } catch (err) {
        error.value = `Failed to load rewards: ${err.message}`;
        console.error('API Error:', err);
      } finally {
        loading.value = false;
      }
    };

    const onSearchChange = () => {
      const query = searchQuery.value || '';

      if (query.length >= 2 || query.length === 0) {
        fetchUserRewards({ pagination: { ...pagination.value, page: 1 } });
      }
    };

    const clearQuery = () => {
      searchQuery.value = '';
      fetchUserRewards({ pagination: { ...pagination.value, page: 1 } });
    };

    onBeforeMount(async () => {
      fetchUserRewards({ pagination: pagination.value })
    });

    return {
      loading,
      error,
      columns,
      pagination,
      rewards,
      fetchUserRewards,
      searchQuery,
      onSearchChange,
      clearQuery
    };
  },
});
</script>

<style lang="scss" scoped>
.loyalty-suite-user-rewards {
  display: flex;
  width: 100%;
  align-items: center;

  &__title {
    display: flex;
    font-size: 22px;
    margin-right: 20px;
  }

  .q-btn {
    margin-left: 20px;
    text-transform: uppercase;
    :deep(.q-btn__content) {
      flex-wrap: nowrap;
      white-space: nowrap;
    }
  }

  &__table {
    display: flex;
    width: 100%;
    flex-direction: column;
    margin-top: 25px;

    a.loyalty-suite-user-rewards__table-link {
      display: flex;
      font-weight: 400;
      text-decoration: none;
      color: $primary;
      &:hover {
        color: $primary;
      }
    }
  }
}
</style>
