<script>
  import { onMount } from 'svelte';
  import { get } from 'svelte/store';
  import Header from '$lib/layout/Header.svelte';
  import StatsCard from '$lib/components/StatsCard.svelte';
  import PaymentMenu from '$lib/components/wallet/PaymentMenu.svelte';
  import SellMenu from '$lib/components/wallet/SellMenu.svelte';
  import tokensIcon from '$lib/assets/icons/sidebar/tokens.svg?raw';
  import walletIcon from '$lib/assets/icons/sidebar/wallet.svg?raw';
  import { authToken } from '$lib/utils/stores';
  import ModalBase from '$lib/components/trading/ModalBase.svelte';

  const breadcrumb = [{ label: 'Início' }, { label: 'wallet', active: true }];
  const apiUrl = import.meta.env.VITE_API_URL;

  let walletTokens = [];
  let easyCoinBalance = 0;
  let tokensLoading = false;
  let tokensError = '';

  let isPaymentOpen = false;
  let isSellOpen = false;

  let rateBRLPerEasyCoin = 100;

  onMount(() => {
    void fetchWalletTokens();
  });

  let tokenDetailModalVisible = false;
  let tokenDetailSelected = null;
  let tokenDetailEntries = [];

  function openPayment() {
    isPaymentOpen = true;
  }
  function closePayment() {
    isPaymentOpen = false;
  }
  function confirmPayment(method) {
    isPaymentOpen = false;
  }

  function openSell() {
    isSellOpen = true;
  }
  function closeSell() {
    isSellOpen = false;
  }
  function confirmSell(e) {
    isSellOpen = false;
  }

  async function parseResponse(res) {
    const raw = await res.text();
    return raw ? JSON.parse(raw) : null;
  }

  async function fetchWalletTokens() {
    if (!apiUrl) return;
    tokensLoading = true;
    tokensError = '';
    try {
      const token = get(authToken);
      if (!token) {
        throw new Error('Sessão expirada. Faça login novamente.');
      }
      const res = await fetch(`${apiUrl}/wallet/tokens`, {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
          Authorization: `Bearer ${token}`
        }
      });
      const body = await parseResponse(res);
      if (!res.ok || body?.status !== 'ok') {
        throw new Error(body?.msg ?? 'Falha ao carregar tokens da wallet.');
      }
      const payload = body?.data ?? {};
      walletTokens = Array.isArray(payload?.tokens) ? payload.tokens : [];
      easyCoinBalance = resolveEasyCoinBalance(payload);
    } catch (err) {
      console.error('[Wallet] Erro ao buscar tokens:', err);
      walletTokens = [];
      easyCoinBalance = 0;
      tokensError = err?.message ?? 'Não foi possível carregar os tokens.';
    } finally {
      tokensLoading = false;
    }
  }

  function resolveEasyCoinBalance(payload) {
    const candidates = [
      payload?.wallet?.easycoin_balance,
      payload?.wallet?.easyCoinBalance,
      payload?.wallet?.balance,
      payload?.easycoin_balance,
      payload?.easyCoinBalance,
      payload?.easycoin,
      payload?.balance
    ];
    const firstValue = candidates.find((value) => value !== undefined && value !== null && value !== '');
    return Number(firstValue ?? 0);
  }

  function formatToken(n) {
    return new Intl.NumberFormat('pt-BR', { minimumFractionDigits: 0, maximumFractionDigits: 6 }).format(Number(n || 0));
  }
  function formatCoin(n) {
    return new Intl.NumberFormat('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(Number(n || 0));
  }

  function formatCurrencyBRL(n) {
    return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(Number(n || 0));
  }

  function tokenCardLabel(token) {
    return token?.cpr_product_name ?? token?.token_content ?? token?.token_external_id ?? token?.token_id ?? 'EasyToken';
  }

  function tokenCardSubtitle(token) {
    if (token?.token_city && token?.token_uf) {
      return `${token.token_city}/${token.token_uf}`;
    }
    if (token?.token_external_id) {
      return `ID ${token.token_external_id}`;
    }
    return 'Saldo atual';
  }

  function tokenAmount(token) {
    const candidates = [
      token?.token_commodities_amount,
      token?.token_amount,
      token?.token_balance,
      token?.balance,
      token?.amount
    ];
    const value = candidates.find((item) => item !== undefined && item !== null && item !== '');
    return Number(value ?? 0);
  }

  function formatTokenDetailKey(key = '') {
    return key
      .replace(/_/g, ' ')
      .replace(/([a-z])([A-Z])/g, '$1 $2')
      .replace(/\s+/g, ' ')
      .trim()
      .replace(/^./, (c) => c.toUpperCase());
  }

  const hiddenTokenDetailKeys = new Set([
    'token_id',
    'token_external_id',
    'token_commodities_amount',
    'token_commodities_value',
    'token_uf',
    'token_city',
    'token_content',
    'wallet_id',
    'chain_id',
    'commodities_id'
  ]);

  const tokenDetailFieldConfig = [
    { key: 'cpr_product_name', label: 'Produto' },
    {
      key: 'cpr_product_quantity',
      label: 'Quantidade do Produto',
      formatter: (value, token) => {
        const formattedQuantity = formatToken(value);
        const unit = token?.cpr_measure_unit_name ?? token?.cpr_packaging_way_name;
        return unit ? `${formattedQuantity} ${unit}` : formattedQuantity;
      }
    },
    { key: 'cpr_packaging_way_name', label: 'Forma de Embalagem' },
    { key: 'cpr_measure_unit_name', label: 'Unidade de Medida' },
    {
      key: 'cpr_issue_value',
      label: 'Valor da Emissão',
      formatter: (value) => formatCurrencyBRL(value)
    },
    { key: 'cpr_delivery_place_city_name', label: 'Cidade de Entrega' },
    { key: 'cpr_delivery_place_state_acronym', label: 'Estado de Entrega' },
    { key: 'cpr_production_place_name', label: 'Local de Produção' },
    { key: 'cpr_id', label: 'Número da CPR' },
    { key: 'user_id', label: 'Código do Usuário' }
  ];

  const tokenDetailKeyTranslations = tokenDetailFieldConfig.reduce((acc, field) => {
    if (field.key) {
      acc[field.key] = field.label;
    }
    return acc;
  }, {});

  function buildTokenDetailEntries(token = {}) {
    if (!token || typeof token !== 'object') return [];

    const entries = [];
    const usedKeys = new Set();

    for (const field of tokenDetailFieldConfig) {
      const rawValue = token?.[field.key];
      if (rawValue === null || rawValue === undefined || rawValue === '') continue;
      usedKeys.add(field.key);
      const formattedValue = field.formatter
        ? field.formatter(rawValue, token)
        : typeof rawValue === 'number'
          ? formatToken(rawValue)
          : Array.isArray(rawValue)
            ? rawValue.join(', ')
            : String(rawValue);
      entries.push({ key: field.key, label: field.label, value: formattedValue });
    }

    Object.entries(token)
      .filter(([key, value]) => !hiddenTokenDetailKeys.has(key) && !usedKeys.has(key) && value !== null && value !== undefined && value !== '')
      .forEach(([key, value]) => {
        const formattedValue = typeof value === 'number'
          ? formatToken(value)
          : Array.isArray(value)
            ? value.join(', ')
            : String(value);
        const label = tokenDetailKeyTranslations[key] ?? formatTokenDetailKey(key);
        entries.push({ key, label, value: formattedValue });
      });

    return entries;
  }

  function openTokenDetailModal(token) {
    if (!token) return;
    tokenDetailSelected = token;
    tokenDetailEntries = buildTokenDetailEntries(token);
    tokenDetailModalVisible = true;
  }

  function closeTokenDetailModal() {
    tokenDetailModalVisible = false;
    tokenDetailSelected = null;
    tokenDetailEntries = [];
  }
</script>

<div>
  <Header title="Wallet" subtitle="Saldos e operações" breadcrumb={breadcrumb} />

  <div class="p-4 space-y-6">
    {#if tokensError}
      <div class="rounded border border-red-200 bg-red-50 text-red-700 px-3 py-2 text-sm">{tokensError}</div>
    {/if}

    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
      {#if tokensLoading && !walletTokens.length}
        <div class="rounded-lg border border-dashed border-gray-300 dark:border-gray-600 bg-white/60 dark:bg-gray-800/60 p-4 text-center text-sm text-gray-500">
          Carregando tokens...
        </div>
      {:else if walletTokens.length}
        {#each walletTokens as token (token?.token_external_id ?? token?.token_id ?? token?.cpr_id ?? token)}
          <div class="rounded-lg overflow-hidden">
            <button
              type="button"
              class="block w-full text-left focus:outline-none"
              on:click={() => openTokenDetailModal(token)}
            >
              <StatsCard
                title={tokenCardLabel(token)}
                value={formatToken(tokenAmount(token))}
                change={tokenCardSubtitle(token)}
                iconSvg={tokensIcon}
              />
            </button>
          </div>
        {/each}
      {:else}
        <div class="rounded-lg border border-dashed border-gray-300 dark:border-gray-600 bg-white/60 dark:bg-gray-800/60 p-4 text-center text-sm text-gray-500">
          Nenhum token encontrado para sua conta.
        </div>
      {/if}
      <div class="rounded-lg overflow-hidden">
        <StatsCard
          title="EasyCoin"
          value={formatCoin(easyCoinBalance)}
          change={tokensLoading ? 'Atualizando...' : 'Saldo atual'}
          iconSvg={walletIcon}
        />
      </div>
    </div>

    <div class="flex gap-3">
      <button
        class="inline-flex items-center gap-2 px-4 py-2 rounded-md bg-blue-600 hover:bg-blue-700 text-white shadow"
        on:click={openPayment}
      >
        Comprar BRLA
      </button>

      <button
        class="inline-flex items-center gap-2 px-4 py-2 rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-800 dark:text-gray-100"
        on:click={openSell}
      >
        Vender BRLA
      </button>
    </div>
  </div>

  <PaymentMenu
    isOpen={isPaymentOpen}
    onClose={closePayment}
    onConfirm={confirmPayment}
  />

  <SellMenu
    isOpen={isSellOpen}
    onClose={closeSell}
    onConfirm={(e) => confirmSell(e.detail || e)}
    rateBRLPerEasyCoin={rateBRLPerEasyCoin}
  />

  <ModalBase
    title="Detalhes do token"
    visible={tokenDetailModalVisible}
    onClose={closeTokenDetailModal}
  >
    {#if tokenDetailSelected}
      <div class="space-y-4 text-sm text-gray-800 dark:text-gray-100">
        <div class="rounded border border-gray-200 dark:border-gray-700 p-3 space-y-2 bg-gray-50 dark:bg-gray-800/60">
          <div class="text-base font-semibold">{tokenCardLabel(tokenDetailSelected)}</div>
          <div class="flex justify-between">
            <span>Quantidade</span>
            <span>{formatToken(tokenAmount(tokenDetailSelected))}</span>
          </div>
          <div class="flex justify-between text-xs text-gray-500 dark:text-gray-400">
            <span>Local</span>
            <span>
              {#if tokenDetailSelected?.token_city || tokenDetailSelected?.token_uf}
                {tokenDetailSelected?.token_city ?? '—'}/{tokenDetailSelected?.token_uf ?? '—'}
              {:else}
                Não informado
              {/if}
            </span>
          </div>
        </div>

        <div class="max-h-64 overflow-y-auto pr-1 space-y-1">
          {#if tokenDetailEntries.length === 0}
            <p class="text-xs text-gray-500">Sem dados adicionais para este token.</p>
          {:else}
            <dl class="divide-y divide-gray-200 dark:divide-gray-700 border border-gray-200 dark:border-gray-700 rounded">
              {#each tokenDetailEntries as entry}
                <div class="flex items-start justify-between px-3 py-2">
                  <dt class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400 w-1/2 pr-2">{entry.label}</dt>
                  <dd class="text-sm text-gray-900 dark:text-gray-100 w-1/2 text-right break-words">{entry.value}</dd>
                </div>
              {/each}
            </dl>
          {/if}
        </div>
      </div>
    {:else}
      <p class="text-sm text-gray-500">Selecione um token para ver detalhes.</p>
    {/if}
  </ModalBase>
</div>