<script>
  import { API_URL, WS_URL } from '$lib/api.js';
  import { apiFetch } from '$lib/api.js';
  import { goto } from '$app/navigation';
  import { onMount } from 'svelte';
  import Card from '$lib/Card.svelte';

  let allCards = $state([]);
  let loading = $state(true);
  const token = () => localStorage.getItem('token');

  // Sort
  let sortBy = $state('name');

  // Filters
  const RARITIES = ['common', 'uncommon', 'rare', 'super_rare', 'epic', 'legendary'];
  const TYPES = ['person', 'location', 'artwork', 'life_form', 'event', 'group', 'science_thing', 'vehicle', 'organization', 'other'];

  let selectedRarities = $state(new Set(RARITIES));
  let selectedTypes = $state(new Set(TYPES));

  let filtersOpen = $state(false);

  const RARITY_ORDER = Object.fromEntries(RARITIES.map((r, i) => [r, i]));

  function label(str) {
    return str.charAt(0).toUpperCase() + str.slice(1).replace(/_/g, ' ');
  }


  let sortAsc = $state(true);
  let costMin = $state(1);
  let costMax = $state(10);
  let searchQuery = $state('');

  let filtered = $derived.by(() => {
    const q = searchQuery.trim().toLowerCase();
    let result = allCards.filter(c =>
      selectedRarities.has(c.card_rarity) &&
      selectedTypes.has(c.card_type) &&
      c.cost >= costMin &&
      c.cost <= costMax &&
      (!q || c.name.toLowerCase().includes(q))
    );

    result = result.slice().sort((a, b) => {
      let cmp = 0;
      if (sortBy === 'name')    cmp = a.name.localeCompare(b.name);
      else if (sortBy === 'cost')    cmp = b.cost - a.cost   || a.name.localeCompare(b.name);
      else if (sortBy === 'attack')  cmp = b.attack - a.attack || a.name.localeCompare(b.name);
      else if (sortBy === 'defense') cmp = b.defense - a.defense || a.name.localeCompare(b.name);
      else if (sortBy === 'rarity')  cmp = RARITY_ORDER[b.card_rarity] - RARITY_ORDER[a.card_rarity] || a.name.localeCompare(b.name);
      return sortAsc ? cmp : -cmp;
    });

    return result;
  });

  function toggleSort(val) {
    if (sortBy === val) sortAsc = !sortAsc;
    else { sortBy = val; sortAsc = true; }
  }

  function toggleRarity(r) {
    const s = new Set(selectedRarities);
    s.has(r) ? s.delete(r) : s.add(r);
    selectedRarities = s;
  }

  function toggleType(t) {
    const s = new Set(selectedTypes);
    s.has(t) ? s.delete(t) : s.add(t);
    selectedTypes = s;
  }

  function allRaritiesSelected() { return selectedRarities.size === RARITIES.length; }
  function allTypesSelected() { return selectedTypes.size === TYPES.length; }

  function toggleAllRarities() {
    selectedRarities = allRaritiesSelected() ? new Set() : new Set(RARITIES);
  }

  function toggleAllTypes() {
    selectedTypes = allTypesSelected() ? new Set() : new Set(TYPES);
  }

  onMount(async () => {
    if (!token()) { goto('/auth'); return; }
    const res = await apiFetch(`${API_URL}/cards`);
    if (res.status === 401) { goto('/auth'); return; }
    allCards = await res.json();
    loading = false;
  });

  let selectedCard = $state(null);
  let refreshStatus = $state(null);
  let countdownDisplay = $state('');
  let countdownInterval = null;
  let reportLoading = $state(false);
  let refreshLoading = $state(false);
  let actionMessage = $state('');

  async function fetchRefreshStatus() {
    const res = await apiFetch(`${API_URL}/profile/refresh-status`);
    refreshStatus = await res.json();
    if (!refreshStatus.can_refresh && refreshStatus.next_refresh_at) {
      startRefreshCountdown(new Date(refreshStatus.next_refresh_at));
    }
  }

  function startRefreshCountdown(nextRefreshAt) {
    clearInterval(countdownInterval);
    countdownInterval = setInterval(() => {
      const diff = nextRefreshAt - Date.now();
      if (diff <= 0) {
        clearInterval(countdownInterval);
        refreshStatus = { can_refresh: true, next_refresh_at: null };
        countdownDisplay = '';
        return;
      }
      const h = Math.floor(diff / 3600000);
      const m = Math.floor((diff % 3600000) / 60000);
      const s = Math.floor((diff % 60000) / 1000);
      countdownDisplay = `${String(h).padStart(2,'0')}:${String(m).padStart(2,'0')}:${String(s).padStart(2,'0')}`;
    }, 1000);
  }

  function openCard(card) {
    selectedCard = card;
    actionMessage = '';
    fetchRefreshStatus();
  }

  function closeCard() {
    selectedCard = null;
    clearInterval(countdownInterval);
    countdownDisplay = '';
    actionMessage = '';
  }

  async function reportCard() {
    reportLoading = true;
    const res = await apiFetch(`${API_URL}/cards/${selectedCard.id}/report`, {
      method: 'POST'
    });
    reportLoading = false;
    if (res.ok) {
      selectedCard = { ...selectedCard, reported: true };
      allCards = allCards.map(c => c.id === selectedCard.id ? { ...c, reported: true } : c);
      actionMessage = 'Card reported. Thank you!';
    } else {
      actionMessage = 'Failed to report card.';
    }
  }

  async function refreshCard() {
    refreshLoading = true;
    actionMessage = '';
    const res = await apiFetch(`${API_URL}/cards/${selectedCard.id}/refresh`, {
      method: 'POST'
    });
    refreshLoading = false;
    if (res.ok) {
      const updated = await res.json();
      // Update card in allCards list
      allCards = allCards.map(c => c.id === updated.id ? updated : c);
      selectedCard = updated;
      refreshStatus = { can_refresh: false, next_refresh_at: null };
      await fetchRefreshStatus();
      actionMessage = 'Card refreshed!';
    } else {
      const err = await res.json();
      actionMessage = err.detail ?? 'Failed to refresh card.';
    }
  }
</script>

<main>
  <div class="toolbar">
    <div class="sort-row">
      <span class="toolbar-label">Sort by</span>
      {#each [['name','Name'],['cost','Cost'],['attack','Attack'],['defense','Defense'],['rarity','Rarity']] as [val, lbl]}
        <button
          class="sort-btn"
          class:active={sortBy === val}
          onclick={() => toggleSort(val)}
        >
          {lbl}
          {#if sortBy === val}
            <span class="sort-arrow">{sortAsc ? '↑' : '↓'}</span>
          {/if}
        </button>
      {/each}

      <input
        class="search-input"
        type="search"
        placeholder="Search by name…"
        bind:value={searchQuery}
      />

      <button class="filter-toggle" onclick={() => filtersOpen = !filtersOpen}>
        {filtersOpen ? 'Hide filters' : 'Filter'}
        {#if selectedRarities.size < RARITIES.length || selectedTypes.size < TYPES.length || costMin > 1 || costMax < 10}
          <span class="filter-dot"></span>
        {/if}
      </button>
    </div>

    {#if filtersOpen}
      <div class="filters">
        <div class="filter-group">
          <div class="filter-group-header">
            <span class="filter-group-label">Rarity</span>
            <button class="select-all" onclick={toggleAllRarities}>
              {allRaritiesSelected() ? 'Deselect all' : 'Select all'}
            </button>
          </div>
          <div class="checkboxes">
            {#each RARITIES as r}
              <label class="checkbox-label">
                <input type="checkbox" checked={selectedRarities.has(r)} onchange={() => toggleRarity(r)} />
                {label(r)}
              </label>
            {/each}
          </div>
        </div>

        <div class="filter-group">
          <div class="filter-group-header">
            <span class="filter-group-label">Type</span>
            <button class="select-all" onclick={toggleAllTypes}>
              {allTypesSelected() ? 'Deselect all' : 'Select all'}
            </button>
          </div>
          <div class="checkboxes">
            {#each TYPES as t}
              <label class="checkbox-label">
                <input type="checkbox" checked={selectedTypes.has(t)} onchange={() => toggleType(t)} />
                {label(t)}
              </label>
            {/each}
          </div>
        </div>

        <div class="filter-group">
          <div class="filter-group-header">
            <span class="filter-group-label">Cost</span>
            <button class="select-all" onclick={() => { costMin = 1; costMax = 10; }}>Reset</button>
          </div>
          <div class="cost-range">
            <span class="range-label">Min: {costMin}</span>
            <input type="range" min="1" max="10" bind:value={costMin}
              oninput={() => { if (costMin > costMax) costMax = costMin; }} />
            <span class="range-label">Max: {costMax}</span>
            <input type="range" min="1" max="10" bind:value={costMax}
              oninput={() => { if (costMax < costMin) costMin = costMax; }} />
          </div>
        </div>
      </div>
    {/if}
  </div>

  {#if loading}
    <p class="status">Loading your cards...</p>
  {:else if filtered.length === 0}
    <p class="status">No cards match your filters.</p>
  {:else}
    <p class="card-count">{filtered.length} card{filtered.length === 1 ? '' : 's'}</p>
    <div class="grid">
      {#each filtered as card (card.id)}
        <button class="card-btn" onclick={() => openCard(card)}>
          <Card {card} />
        </button>
      {/each}
    </div>
  {/if}
  {#if selectedCard}
    <div class="backdrop" onclick={closeCard}>
      <div class="card-popup" onclick={(e) => e.stopPropagation()}>
        <Card card={selectedCard} />
        <div class="popup-actions">
          <div class="action-col">
            <button
              class="report-btn"
              onclick={reportCard}
              disabled={reportLoading || selectedCard.reported}
            >
              {selectedCard.reported ? 'Already Reported' : reportLoading ? 'Reporting...' : 'Report Error'}
            </button>
          </div>
          <div class="action-col">
            <button
              class="refresh-btn"
              onclick={refreshCard}
              disabled={refreshLoading || (refreshStatus && !refreshStatus.can_refresh)}
            >
              {refreshLoading ? 'Refreshing...' : 'Refresh Card'}
            </button>
            <span class="refresh-countdown">
              {refreshStatus && !refreshStatus.can_refresh && countdownDisplay ? `${countdownDisplay} until next refresh` : ''}
            </span>
          </div>
        </div>
        <p class="action-message">{actionMessage}</p>
        <button class="close-btn" onclick={closeCard}>✕</button>
      </div>
    </div>
  {/if}
</main>

<style>
  @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700&family=Crimson+Text:ital,wght@0,400;0,600;1,400&display=swap');

  main {
    height: 100vh;
    overflow-y: auto;
    background: #0d0a04;
    padding: 0 2rem 2rem 2rem;
  }

  .toolbar {
    position: sticky;
    top: 0px;
    z-index: 50;
    background: #0d0a04;
    padding-bottom: 1rem;
    border-bottom: 1px solid rgba(107, 76, 30, 0.3);
    margin-bottom: 2rem;
    padding-top: 32px;
  }

  .sort-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
  }

  .search-input {
    font-family: 'Crimson Text', serif;
    font-size: 15px;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(107, 76, 30, 0.4);
    border-radius: 4px;
    color: #f0d080;
    padding: 5px 10px;
    outline: none;
    width: 220px;
    margin-left: auto;
    transition: border-color 0.15s;
  }
  .search-input:focus { border-color: #c8861a; }
  .search-input::placeholder { color: rgba(240, 180, 80, 0.3); }

  .toolbar-label {
    font-family: 'Cinzel', serif;
    font-size: 11px;
    color: rgba(240, 180, 80, 0.5);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin-right: 0.25rem;
  }

  .sort-btn {
    font-family: 'Cinzel', serif;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: none;
    border: 1px solid rgba(107, 76, 30, 0.4);
    border-radius: 4px;
    color: rgba(240, 180, 80, 0.6);
    padding: 4px 10px;
    cursor: pointer;
    transition: all 0.15s;
  }

  .sort-btn:hover {
    border-color: #c8861a;
    color: #f0d080;
  }

  .sort-btn.active {
    background: #3d2507;
    border-color: #c8861a;
    color: #f0d080;
  }

  .filter-toggle {
    font-family: 'Cinzel', serif;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: none;
    border: 1px solid rgba(107, 76, 30, 0.4);
    border-radius: 4px;
    color: rgba(240, 180, 80, 0.6);
    padding: 4px 10px;
    cursor: pointer;
    margin-left: 0.5rem;
    position: relative;
    transition: all 0.15s;
  }

  .filter-toggle:hover {
    border-color: #c8861a;
    color: #f0d080;
  }

  .filter-dot {
    position: absolute;
    top: -3px;
    right: -3px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #c8861a;
  }

  .filters {
    display: flex;
    gap: 3rem;
    padding-top: 1rem;
    flex-wrap: wrap;
  }

  .filter-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }

  .filter-group-header {
    display: flex;
    align-items: baseline;
    gap: 1rem;
  }

  .filter-group-label {
    font-family: 'Cinzel', serif;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(240, 180, 80, 0.5);
  }

  .select-all {
    font-family: 'Crimson Text', serif;
    font-size: 12px;
    font-style: italic;
    background: none;
    border: none;
    color: rgba(240, 180, 80, 0.5);
    cursor: pointer;
    padding: 0;
    text-decoration: underline;
    transition: color 0.15s;
  }

  .select-all:hover {
    color: #f0d080;
  }

  .checkboxes {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1rem;
  }

  .checkbox-label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-family: 'Crimson Text', serif;
    font-size: 14px;
    color: rgba(240, 180, 80, 0.8);
    cursor: pointer;
  }

  .checkbox-label input {
    accent-color: #c8861a;
    width: 14px;
    height: 14px;
    cursor: pointer;
  }

  .card-count {
    font-family: 'Crimson Text', serif;
    font-size: 16px;
    font-style: italic;
    color: rgba(240, 180, 80, 0.4);
    margin-bottom: 1.5rem;
  }

  .grid {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    justify-content: center;
    padding-bottom: 50px
  }

  .status {
    font-family: 'Crimson Text', serif;
    font-size: 16px;
    font-style: italic;
    color: rgba(240, 180, 80, 0.5);
    text-align: center;
    margin-top: 4rem;
  }

  .sort-arrow {
    font-size: 10px;
    margin-left: 3px;
  }

  .cost-range {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
  }

  .range-label {
    font-family: 'Cinzel', serif;
    font-size: 11px;
    color: rgba(240, 180, 80, 0.7);
    min-width: 60px;
  }

  input[type=range] {
    accent-color: #c8861a;
    width: 160px;
  }

  .card-btn {
    all: unset;
    cursor: pointer;
    display: block;
    border-radius: 12px;
    transition: transform 0.15s;
  }

  .card-btn:hover {
    transform: translateY(-4px);
  }

  .backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.8);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
    backdrop-filter: blur(6px);
  }

  .card-popup {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
  }

  .popup-actions {
    display: flex;
    gap: 1rem;
    justify-content: center;
  }

  .action-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    min-height: 60px;
  }

  .report-btn, .refresh-btn {
    font-family: 'Cinzel', serif;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border-radius: 4px;
    padding: 8px 18px;
    cursor: pointer;
    transition: background 0.15s;
  }

  .report-btn {
    background: rgba(180, 60, 60, 0.5);
    border: 1px solid rgba(240,250,240,0.8);
    color: white;
  }

  .report-btn:hover:not(:disabled) {
    /* border-color: #c84040; */
    color: #E0E0E0;
    background: rgba(180, 40, 40, 0.9);
  }

  .refresh-btn {
    background: #3d2507;
    border: 1px solid #c8861a;
    color: #f0d080;
  }

  .refresh-btn:hover:not(:disabled) {
    background: #5a3510;
  }

  .report-btn:disabled, .refresh-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
  }

  .refresh-countdown {
    font-family: 'Crimson Text', serif;
    font-size: 12px;
    font-style: italic;
    color: rgba(240, 180, 80, 0.5);
  }

  .action-message {
    font-family: 'Crimson Text', serif;
    font-size: 14px;
    font-style: italic;
    color: rgba(240, 180, 80, 0.7);
    margin: 0;
    min-height: 1.4em;
    text-align: center;
  }

  .close-btn {
    position: absolute;
    top: -12px;
    right: -12px;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: #1a1008;
    border: 1px solid #6b4c1e;
    color: rgba(240, 180, 80, 0.7);
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.15s;
  }

  .close-btn:hover {
    border-color: #c8861a;
    color: #f0d080;
  }
</style>