<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-wallets-page">
          <div class="loyalty-suite-wallets-page__breadcrumbs">
            {{ $t('myWallet') }}
          </div>
          <div class="loyalty-suite-wallets-page__wallet">
            <Wallet :wallet="wallet" :currency="currency" :transactions="false" />
          </div>
          <div class="loyalty-suite-wallets-page__transactions">
            {{ $t('transactions') }}
            <Datepicker v-model="date" />
          </div>
          <div class="loyalty-suite-wallets-page__table">
            <q-table class="loyalty-suite-table" flat bordered separator="cell" :rows="transactions" :columns="columns"
              row-key="id" :loading="loadingTable" :rows-per-page-options="[]"
              :no-data-label="$t('notFoundTransactions')" v-model:pagination="pagination"
              :loading-label="$t('tableLoading')" @request="fetchTransactions">
              <template v-slot:body-cell-value="props">
                <q-td :props="props">
                  {{ props.row.amount }}
                </q-td>
              </template>
              <template v-slot:body-cell-source_type="props">
                <q-td :props="props">
                  {{ $t(props.row.source_type + 'Transaction') }}
                </q-td>
              </template>
              <template v-slot:body-cell-source="props">
                <q-td :props="props">
                  <a v-if="props.row.source.url.length > 0" :href="props.row.source.url" class="loyalty-suite-wallets-page__table-link" target="_blank">
                    {{ $t(props.row.source.label + 'Transaction') + ' ' + props.row.source.number }}
                  </a>
                  <template v-if="props.row.source_type === 'reward'">
                    {{ props.row.source.label }}
                  </template>
                  <template v-if="props.row.source_type === 'refundReward'">
                    {{ props.row.source.label }}
                  </template>
                  <template v-if="props.row.source_type === 'admin'">
                    {{ $t('adminTransaction') }}
                  </template>
                </q-td>
              </template>
              <template v-slot:loading>
                <div class="loyalty-suite-loading-table">
                  <div class="loyalty-suite-spinner"></div>
                </div>
              </template>
            </q-table>
          </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 Wallet from '../components/Wallet.vue';
import Datepicker from '../components/Datepicker.vue';

export default defineComponent({
  components: {
    Wallet,
    Datepicker
  },
  setup() {
    const loading = ref(true);
    const loadingTable = 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 currency = ref({ symbol: '$' });
    const { t } = useI18n();
    const route = useRoute();
    const date = ref('');
    const wallet = ref([]);
    const transactions = ref([]);

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

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

    const columns = computed(() => [
      { name: 'date', label: t('date'), field: 'date', align: 'left', sortable: false, style: 'width: 15%', headerStyle: 'width: 15%;' },
      { name: 'source_type', label: t('transaction'), field: 'source_type', align: 'left', sortable: false, style: 'width: 35%', headerStyle: 'width: 35%;' },
      { name: 'source', label: t('sourceTransaction'), field: 'source', align: 'left', sortable: false, style: 'width: 35%', headerStyle: 'width: 35%;' },
      { name: 'amount', label: wallet.value?.units || t('amount'), field: 'amount', align: 'left', sortable: false, style: 'width: 15%', headerStyle: 'width: 15%;' },
    ]);

    watch(date, () => {
      fetchTransactions({ pagination: pagination.value });
    });

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

        const page = props?.pagination?.page || 1;
        const rowsPerPage = props?.pagination?.rowsPerPage || 10;
        const sortBy = props?.pagination?.sortBy || 'created_at';
        const descending = props?.pagination?.descending ? 'desc' : 'asc';

        const query = new URLSearchParams({
          id: String(route.params.id),
          page: String(page),
          per_page: String(rowsPerPage),
          order_by: sortBy,
          order: descending,
        });

        if (date.value?.from) {
          query.append('date_from', date.value.from);
        }
        if (date.value?.to) {
          query.append('date_to', date.value.to);
        }

        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.transactions, Object.fromEntries(query.entries())),
          {
            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();
        transactions.value = Array.isArray(data.transactions) ? data.transactions : [];
        pagination.value = {
          page,
          rowsPerPage,
          rowsNumber: data.total || 0,
          sortBy,
          descending: descending === 'desc',
        };
      } catch (err) {
        error.value = `Failed to load transactions: ${err.message}`;
        console.error('API Error:', err);
      } finally {
        loadingTable.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 fetchWallet = 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.wallet, {
            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();

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

    return {
      loading,
      loadingTable,
      error,
      errorMessage,
      wallet,
      currency,
      columns,
      pagination,
      transactions,
      fetchTransactions,
      date
    };
  },
});
</script>

<style lang="scss" scoped>
.loyalty-suite-wallets-page {
  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);
  }

  &__wallet {
    display: flex;
    width: 330px;
  }

  &__card {
    display: flex;
    width: 100%;
    max-width: 360px;
    min-width: 230px;

    &-icon {
      display: flex;
      z-index: 2;
      position: absolute;
      top: 9px;
      right: 15px;
      justify-content: center;

      .loyalty-suite-material-icons {
        color: var(--loyalty-suite-borders-60);
        font-size: 32px;
      }
    }

    &-wrapper {
      display: flex;
      width: 100%;
      height: 180px;
      flex-direction: column;
      background: var(--loyalty-suite-light);
      border-radius: 16px;
      border: 1px solid var(--loyalty-suite-borders-60);
      position: relative;
      overflow: hidden;
    }

    &-title {
      display: flex;
      padding: 20px 20px 25px 20px;
    }

    &-info {
      display: flex;
      padding: 0 20px;
      align-items: center;
    }

    &-balance {
      display: flex;
      flex-wrap: wrap;
      font-size: 18px;
      line-height: normal;
    }

    &-img {
      display: flex;
      flex-shrink: 0;
      width: 40px;
      height: 40px;
      object-fit: cover;
      margin-right: 10px;
    }

    &-details {
      display: flex;
      align-self: flex-start;
      color: var(--loyalty-suite-light);
      transition: 0.3s;
      text-transform: capitalize;

      &:hover {
        cursor: pointer;
        color: var(--loyalty-suite-light-90);
      }
    }

    &-actions {
      display: flex;
      justify-content: space-between;
      align-items: center;
      width: 100%;
      height: 47px;
      margin-top: auto;
      background: var(--loyalty-suite-primary);
      padding: 15px 20px;
    }
  }

  &__table {
    display: flex;
    width: 100%;
    max-width: 800px;
    flex-direction: column;
    margin: 20px 0;

    a.loyalty-suite-wallets-page__table-link {
      display: flex;
      font-weight: 400;
      text-decoration: none;
      transition: 0.3s;
      color: var(--loyalty-suite-primary);

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

  &__transactions {
    display: flex;
    flex-direction: column;
    width: 100%;
    margin-top: 25px;
    font-weight: 700;
    color: var(--loyalty-suite-primary);
  }
}

@media (max-width: 576px) {
  .loyalty-suite-wallets-page {
    &__wallet {
      width: 100%;
    }
  }
}
</style>
