<script lang="ts">
  import { onMount } from 'svelte';
  import { browser } from '$app/environment';
  import PlayerCard from '$lib/components/PlayerCard.svelte';
  import type { BeatLeaderPlayerProfile } from '$lib/utils/plebsaber-utils';

  export let playerA = '';
  export let playerB = '';
  export let loading = false;
  export let hasResults = false;
  export let oncompare: (() => void) | undefined = undefined;
  export let currentPlayer: BeatLeaderPlayerProfile | null = null;

  let initialized = false;

  // Local state for default player cards
  let hasCompared = false;
  let playerAProfile: BeatLeaderPlayerProfile | null = null;
  let playerBProfile: BeatLeaderPlayerProfile | null = null;

  // Preview profiles (loaded as user types)
  let previewAProfile: BeatLeaderPlayerProfile | null = null;
  let previewBProfile: BeatLeaderPlayerProfile | null = null;
  let loadingPreviewA = false;
  let loadingPreviewB = false;

  // Load from URL params on mount
  onMount(() => {
    if (browser) {
      const sp = new URLSearchParams(location.search);
      const urlA = sp.get('a');
      const urlB = sp.get('b');
      
      // Prefill playerA with current player if not in URL
      if (!urlA && !playerA && currentPlayer?.id) {
        playerA = currentPlayer.id;
      } else {
        playerA = urlA ?? playerA;
      }
      
      playerB = urlB ?? playerB;
      initialized = true;

      // Load initial previews if IDs are already present
      if (playerA.trim()) {
        void loadPreviewProfile('A', playerA.trim());
      }
      if (playerB.trim()) {
        void loadPreviewProfile('B', playerB.trim());
      }
    }
  });

  // Sync to URL params when values change
  $: if (browser && initialized) {
    const sp = new URLSearchParams(location.search);
    if (playerA.trim()) {
      sp.set('a', playerA.trim());
    } else {
      sp.delete('a');
    }
    if (playerB.trim()) {
      sp.set('b', playerB.trim());
    } else {
      sp.delete('b');
    }
    const qs = sp.toString();
    const url = location.pathname + (qs ? `?${qs}` : '');
    history.replaceState(null, '', url);
  }

  async function fetchPlayerProfile(playerId: string): Promise<BeatLeaderPlayerProfile | null> {
    try {
      const res = await fetch(`https://api.beatleader.xyz/player/${encodeURIComponent(playerId)}`);
      if (!res.ok) return null;
      return (await res.json()) as BeatLeaderPlayerProfile;
    } catch {
      return null;
    }
  }

  async function loadDefaultPlayerCards(a: string, b: string): Promise<void> {
    playerAProfile = null;
    playerBProfile = null;
    if (!a || !b) return;
    const [pa, pb] = await Promise.all([
      fetchPlayerProfile(a),
      fetchPlayerProfile(b)
    ]);
    playerAProfile = pa;
    playerBProfile = pb;
  }

  // Debounced preview loading
  let previewDebounceTimerA: ReturnType<typeof setTimeout> | null = null;
  let previewDebounceTimerB: ReturnType<typeof setTimeout> | null = null;

  async function loadPreviewProfile(player: 'A' | 'B', id: string): Promise<void> {
    if (!id || id.trim().length < 3) {
      if (player === 'A') previewAProfile = null;
      else previewBProfile = null;
      return;
    }

    const trimmed = id.trim();
    if (player === 'A') {
      loadingPreviewA = true;
    } else {
      loadingPreviewB = true;
    }

    try {
      const profile = await fetchPlayerProfile(trimmed);
      // Only update if this is still the current player ID
      const currentId = player === 'A' ? playerA.trim() : playerB.trim();
      if (currentId === trimmed) {
        if (player === 'A') {
          previewAProfile = profile;
        } else {
          previewBProfile = profile;
        }
      }
    } catch {
      // Silently fail - don't show errors for preview loading
      const currentId = player === 'A' ? playerA.trim() : playerB.trim();
      if (currentId === trimmed) {
        if (player === 'A') {
          previewAProfile = null;
        } else {
          previewBProfile = null;
        }
      }
    } finally {
      if (player === 'A') {
        loadingPreviewA = false;
      } else {
        loadingPreviewB = false;
      }
    }
  }

  // Watch for changes to playerA and debounce preview loading
  $: if (initialized && browser) {
    const trimmed = playerA.trim();
    if (previewDebounceTimerA) clearTimeout(previewDebounceTimerA);
    
    if (trimmed && trimmed.length >= 3) {
      previewDebounceTimerA = setTimeout(() => {
        void loadPreviewProfile('A', trimmed);
      }, 800);
    } else {
      previewAProfile = null;
    }
  }

  // Watch for changes to playerB and debounce preview loading
  $: if (initialized && browser) {
    const trimmed = playerB.trim();
    if (previewDebounceTimerB) clearTimeout(previewDebounceTimerB);
    
    if (trimmed && trimmed.length >= 3) {
      previewDebounceTimerB = setTimeout(() => {
        void loadPreviewProfile('B', trimmed);
      }, 800);
    } else {
      previewBProfile = null;
    }
  }

  // Computed: which profile to display (post-compare takes priority over preview)
  $: displayProfileA = hasCompared ? playerAProfile : previewAProfile;
  $: displayProfileB = hasCompared ? playerBProfile : previewBProfile;
  $: showCardA = !!(displayProfileA || (loadingPreviewA && playerA.trim().length >= 3));
  $: showCardB = !!(displayProfileB || (loadingPreviewB && playerB.trim().length >= 3));

  async function handleSubmit(e: Event) {
    e.preventDefault();
    hasCompared = true;
    const a = playerA.trim();
    const b = playerB.trim();
    // Fire and forget: show default cards irrespective of parent page implementation
    void loadDefaultPlayerCards(a, b);
    oncompare?.();
  }
</script>

<form class="mt-6" on:submit={handleSubmit}>
  <div class="form-grid">
    <div class="player-column">
      <div class="input-tile">
        <label class="block text-sm text-muted">Player A ID
          <input 
            class="mt-1 w-full rounded-md border bg-transparent px-3 py-2 text-sm outline-none {hasResults ? 'border-white/10' : 'neon-input'}" 
            bind:value={playerA} 
            placeholder="7656119... or BL ID" 
            required 
          />
        </label>
        {#if $$slots['player-a-card']}
          <slot name="player-a-card" />
        {:else if showCardA}
          <div class="player-card-wrapper">
            {#if displayProfileA}
              <PlayerCard
                name={displayProfileA.name ?? 'Player A'}
                avatar={displayProfileA.avatar ?? null}
                country={displayProfileA.country ?? null}
                rank={displayProfileA.rank ?? null}
                showRank={typeof displayProfileA.rank === 'number'}
                width="100%"
                avatarSize={56}
                techPp={displayProfileA.techPp}
                accPp={displayProfileA.accPp}
                passPp={displayProfileA.passPp}
                playerId={displayProfileA.id ?? null}
                gradientId="compare-player-a"
              />
            {:else if loadingPreviewA}
              <div class="loading-profile">Loading player...</div>
            {:else if hasCompared}
              <div class="empty-profile">Player A profile not found</div>
            {/if}
          </div>
        {/if}
      </div>
    </div>

    <div class="player-column">
      <div class="input-tile">
        <label class="block text-sm text-muted">Player B ID
          <input 
            class="mt-1 w-full rounded-md border bg-transparent px-3 py-2 text-sm outline-none {hasResults ? 'border-white/10' : 'neon-input'}" 
            bind:value={playerB} 
            placeholder="7656119... or BL ID" 
            required 
          />
        </label>
        {#if $$slots['player-b-card']}
          <slot name="player-b-card" />
        {:else if showCardB}
          <div class="player-card-wrapper">
            {#if displayProfileB}
              <PlayerCard
                name={displayProfileB.name ?? 'Player B'}
                avatar={displayProfileB.avatar ?? null}
                country={displayProfileB.country ?? null}
                rank={displayProfileB.rank ?? null}
                showRank={typeof displayProfileB.rank === 'number'}
                width="100%"
                avatarSize={56}
                techPp={displayProfileB.techPp}
                accPp={displayProfileB.accPp}
                passPp={displayProfileB.passPp}
                playerId={displayProfileB.id ?? null}
                gradientId="compare-player-b"
              />
            {:else if loadingPreviewB}
              <div class="loading-profile">Loading player...</div>
            {:else if hasCompared}
              <div class="empty-profile">Player B profile not found</div>
            {/if}
          </div>
        {/if}
      </div>
    </div>
  </div>

  <div class="button-row">
    <button class="btn-neon" type="submit" disabled={loading}>
      {#if loading}
        Loading...
      {:else}
        Compare
      {/if}
    </button>
    <slot name="extra-buttons" />
  </div>
</form>

<style>
  .form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
    margin-bottom: 1.5rem;
  }

  @media (max-width: 768px) {
    .form-grid {
      grid-template-columns: 1fr;
    }
  }

  .player-column {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  .input-tile {
    border: 1px solid rgba(148, 163, 184, 0.18);
    border-radius: 0.75rem;
    padding: 1.25rem;
    background: linear-gradient(160deg, rgba(15, 23, 42, 0.6), rgba(8, 12, 24, 0.85));
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    transition: border-color 0.2s ease;
  }

  .input-tile:hover {
    border-color: rgba(148, 163, 184, 0.3);
  }

  .button-row {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
  }

  .neon-input {
    border: 1px solid rgba(34, 211, 238, 0.3);
    background: linear-gradient(180deg, rgba(15,23,42,0.9), rgba(11,15,23,0.95));
    color: rgba(148, 163, 184, 1);
    transition: all 0.2s ease;
    box-shadow: 0 0 8px rgba(34, 211, 238, 0.15);
  }
  .neon-input:hover {
    border-color: rgba(34, 211, 238, 0.5);
    color: rgba(255, 255, 255, 0.9);
    box-shadow: 0 0 16px rgba(34, 211, 238, 0.25);
  }
  .neon-input:focus {
    outline: none;
    border-color: rgba(34, 211, 238, 0.7);
    box-shadow: 0 0 20px rgba(34, 211, 238, 0.35), 0 0 0 2px rgba(34, 211, 238, 0.1);
    color: rgba(255, 255, 255, 1);
  }

  .player-card-wrapper {
    margin-top: 1rem;
  }

  .empty-profile {
    padding: 2rem;
    text-align: center;
    color: rgba(148, 163, 184, 0.7);
    font-size: 0.9rem;
  }

  .loading-profile {
    padding: 2rem;
    text-align: center;
    color: rgba(148, 163, 184, 0.7);
    font-size: 0.9rem;
  }
</style>

