<script lang="ts">
  import { onMount } from 'svelte';
  import { fade, fly } from 'svelte/transition';
  import type { Encounter, GameState, PicletInstance } from '$lib/db/schema';
  import { EncounterType } from '$lib/db/schema';
  import { EncounterService } from '$lib/db/encounterService';
  import { getOrCreateGameState, incrementCounter, addProgressPoints } from '$lib/db/gameState';
  import { calculateStat, calculateHp } from '$lib/services/levelingService';
  import { db } from '$lib/db';
  import { uiStore } from '$lib/stores/ui';
  import Battle from './Battle.svelte';
  import PullToRefresh from '../UI/PullToRefresh.svelte';
  import NewlyCaughtPicletDetail from '../Piclets/NewlyCaughtPicletDetail.svelte';
  
  let encounters: Encounter[] = [];
  let isLoading = true;
  let isRefreshing = false;
  let monsterImages: Map<string, string> = new Map();
  
  // Battle state
  let showBattle = false;
  let battlePlayerPiclet: PicletInstance | null = null;
  let battleEnemyPiclet: PicletInstance | null = null;
  let battleIsWild = true;
  let battleRosterPiclets: PicletInstance[] = [];
  
  // Newly caught Piclet state
  let showNewlyCaught = false;
  let newlyCaughtPiclet: PicletInstance | null = null;
  
  onMount(async () => {
    await loadEncounters();
  });
  
  async function loadEncounters() {
    isLoading = true;
    try {
      // Check if we have any piclet instances
      const playerPiclets = await db.picletInstances.toArray();
      
      if (playerPiclets.length === 0) {
        // No piclets discovered/caught - show empty state
        encounters = [];
        isLoading = false;
        return;
      }
      
      // Player has piclets - always generate fresh encounters with wild piclets
      console.log('Player has piclets - generating fresh encounters with wild piclets');
      await EncounterService.forceEncounterRefresh();
      encounters = await EncounterService.generateEncounters();
      
      console.log('Final encounters:', encounters.map(e => ({ type: e.type, title: e.title })));
      
      // Load piclet images for wild encounters
      await loadPicletImages();
    } catch (error) {
      console.error('Error loading encounters:', error);
    }
    isLoading = false;
  }
  
  async function loadPicletImages() {
    const picletEncounters = encounters.filter(e => 
      (e.type === EncounterType.WILD_PICLET || e.type === EncounterType.FIRST_PICLET) && e.picletTypeId
    );
    
    for (const encounter of picletEncounters) {
      if (!encounter.picletTypeId) continue;
      
      // Find a piclet instance with this typeId
      const piclet = await db.picletInstances
        .where('typeId')
        .equals(encounter.picletTypeId)
        .first();
      
      if (piclet && piclet.imageData) {
        monsterImages.set(encounter.picletTypeId, piclet.imageData);
      }
    }
    // Trigger reactive update
    monsterImages = monsterImages;
  }
  
  async function handleRefresh() {
    isRefreshing = true;
    try {
      // Force refresh encounters
      console.log('Force refreshing encounters...');
      encounters = await EncounterService.generateEncounters();
      
      // Load piclet images for new encounters
      await loadPicletImages();
      
      // Update game state with new refresh time
      const gameState = await getOrCreateGameState();
      await db.gameState.update(gameState.id!, {
        lastEncounterRefresh: new Date()
      });
    } catch (error) {
      console.error('Error refreshing encounters:', error);
    }
    isRefreshing = false;
  }
  
  async function handleEncounterTap(encounter: Encounter) {
    if (encounter.type === EncounterType.FIRST_PICLET) {
      // First piclet encounter - direct catch
      await handleFirstPicletEncounter(encounter);
    } else if (encounter.type === EncounterType.WILD_PICLET && encounter.picletTypeId) {
      // Regular wild encounter - start battle
      await startBattle(encounter);
    } else if (encounter.type === EncounterType.SHOP) {
      await handleShopEncounter();
    } else if (encounter.type === EncounterType.HEALTH_CENTER) {
      await handleHealthCenterEncounter();
    } else if (encounter.type === EncounterType.TRAINER_BATTLE) {
      alert('Trainer battles coming soon!');
    }
  }
  
  async function handleShopEncounter() {
    alert('Shop features coming soon!');
    await forceEncounterRefresh();
  }
  
  async function handleHealthCenterEncounter() {
    try {
      // Heal all piclets
      const piclets = await db.picletInstances.toArray();
      for (const piclet of piclets) {
        await db.picletInstances.update(piclet.id!, {
          currentHp: piclet.maxHp
        });
      }
      
      alert('All your piclets have been healed to full health!');
      await forceEncounterRefresh();
    } catch (error) {
      console.error('Error at health center:', error);
    }
  }

  async function handleFirstPicletEncounter(encounter: Encounter) {
    try {
      if (!encounter.picletInstanceId) {
        throw new Error('No piclet instance specified for first piclet encounter');
      }

      // Get the specific piclet instance
      const picletInstance = await db.picletInstances.get(encounter.picletInstanceId);
      if (!picletInstance) {
        throw new Error('Piclet instance not found');
      }

      // Mark the piclet as caught and set it as the first roster piclet
      await db.picletInstances.update(encounter.picletInstanceId, {
        caught: true,
        caughtAt: new Date(),
        isInRoster: true,
        rosterPosition: 0,
        level: 3
      });

      // Get the updated piclet instance
      const caughtPiclet = await db.picletInstances.get(encounter.picletInstanceId);
      
      // Show the newly caught piclet detail page
      newlyCaughtPiclet = caughtPiclet!;
      showNewlyCaught = true;
      
      // Update counters and progress
      incrementCounter('picletsCapured');
      addProgressPoints(100);
      
      // Force refresh encounters to remove the first piclet encounter
      await forceEncounterRefresh();
    } catch (error) {
      console.error('Error handling first piclet encounter:', error);
      alert('Something went wrong. Please try again.');
    }
  }
  
  async function forceEncounterRefresh() {
    isRefreshing = true;
    try {
      await EncounterService.forceEncounterRefresh();
      encounters = await EncounterService.generateEncounters();
      await loadPicletImages();
    } catch (error) {
      console.error('Error refreshing encounters:', error);
    }
    isRefreshing = false;
  }
  
  function getEncounterIcon(encounter: Encounter): string {
    switch (encounter.type) {
      case EncounterType.SHOP:
        return '🛍️';
      case EncounterType.HEALTH_CENTER:
        return '❤️';
      case EncounterType.TRAINER_BATTLE:
        return '🏆';
      case EncounterType.FIRST_PICLET:
        return '✨';
      case EncounterType.WILD_PICLET:
      default:
        return '⚔️';
    }
  }
  
  function getEncounterColor(encounter: Encounter): string {
    switch (encounter.type) {
      case EncounterType.WILD_PICLET:
        return '#4caf50';
      case EncounterType.FIRST_PICLET:
        return '#ffd700';
      case EncounterType.TRAINER_BATTLE:
        return '#ff9800';
      case EncounterType.SHOP:
        return '#2196f3';
      case EncounterType.HEALTH_CENTER:
        return '#9c27b0';
      default:
        return '#607d8b';
    }
  }
  
  async function startBattle(encounter: Encounter) {
    try {
      // Get all piclet instances
      const allPiclets = await db.picletInstances.toArray();
      
      // Filter piclets that have a roster position (0-5)
      const rosterPiclets = allPiclets.filter(p => 
        p.rosterPosition !== undefined && 
        p.rosterPosition !== null && 
        p.rosterPosition >= 0 && 
        p.rosterPosition <= 5
      );
      
      // Sort by roster position
      rosterPiclets.sort((a, b) => (a.rosterPosition ?? 0) - (b.rosterPosition ?? 0));
      
      // Get healthy piclets
      const healthyPiclets = rosterPiclets.filter(p => p.currentHp > 0);
      
      if (healthyPiclets.length === 0) {
        alert('You need at least one healthy piclet in your roster to battle!');
        return;
      }
      
      // Check if there's at least one piclet in position 0
      const hasPosition0 = rosterPiclets.some(p => p.rosterPosition === 0);
      if (!hasPosition0) {
        alert('You need a piclet in the first roster slot (position 0) to battle!');
        return;
      }
      
      // Generate enemy piclet for battle
      const enemyPiclet = await generateEnemyPiclet(encounter);
      if (!enemyPiclet) return;
      
      // Set up battle
      battlePlayerPiclet = healthyPiclets[0];
      battleEnemyPiclet = enemyPiclet;
      battleIsWild = true;
      battleRosterPiclets = rosterPiclets; // Pass all roster piclets
      showBattle = true;
      uiStore.enterBattle();
    } catch (error) {
      console.error('Error starting battle:', error);
    }
  }
  
  async function generateEnemyPiclet(encounter: Encounter): Promise<PicletInstance | null> {
    if (!encounter.picletTypeId || !encounter.enemyLevel) return null;
    
    // Get a piclet instance with this typeId to use as a template
    const templatePiclet = await db.picletInstances
      .where('typeId')
      .equals(encounter.picletTypeId)
      .first();
    
    if (!templatePiclet) {
      console.error('Piclet template not found for typeId:', encounter.picletTypeId);
      return null;
    }
    
    // Calculate stats based on template's base stats and encounter level
    const level = encounter.enemyLevel;
    
    // Calculate current stats based on level (using template's base stats)
    
    const maxHp = calculateHp(templatePiclet.baseHp, level);
    
    // Create enemy piclet instance based on template
    const enemyPiclet: PicletInstance = {
      ...templatePiclet,
      id: -1, // Temporary ID for enemy
      
      level: level,
      xp: 0,
      currentHp: maxHp,
      maxHp: maxHp,
      attack: calculateStat(templatePiclet.baseAttack, level),
      defense: calculateStat(templatePiclet.baseDefense, level),
      fieldAttack: calculateStat(templatePiclet.baseFieldAttack, level),
      fieldDefense: calculateStat(templatePiclet.baseFieldDefense, level),
      speed: calculateStat(templatePiclet.baseSpeed, level),
      
      // Reset move PP to full
      moves: templatePiclet.moves.map(move => ({
        ...move,
        currentPp: move.pp
      })),
      
      isInRoster: false,
      caughtAt: new Date()
    };
    
    return enemyPiclet;
  }
  
  function handleBattleEnd(result: any) {
    showBattle = false;
    uiStore.exitBattle();
    
    if (result === true) {
      // Victory
      console.log('Battle won!');
    } else if (result === false) {
      // Defeat or ran away
      console.log('Battle lost or fled');
    } else if (result && result.id) {
      // Caught a piclet
      console.log('Piclet caught!', result);
      incrementCounter('picletsCapured');
      addProgressPoints(100);
    }
    
    // Force refresh encounters after battle
    forceEncounterRefresh();
  }
</script>

{#if showBattle && battlePlayerPiclet && battleEnemyPiclet}
  <Battle 
    playerPiclet={battlePlayerPiclet}
    enemyPiclet={battleEnemyPiclet}
    isWildBattle={battleIsWild}
    rosterPiclets={battleRosterPiclets}
    onBattleEnd={handleBattleEnd}
  />
{:else}
<div class="encounters-page">
  <PullToRefresh onRefresh={handleRefresh}>
    {#if isLoading}
      <div class="loading">
        <div class="spinner"></div>
        <p>Loading encounters...</p>
      </div>
    {:else if encounters.length === 0}
      <div class="empty-state">
        <div class="empty-icon">📸</div>
        <h2>No Piclets Discovered</h2>
        <p>To start your adventure, select the Snap logo image:</p>
        <div class="logo-instruction">
          <img src="/assets/snap_logo.png" alt="Snap Logo" class="snap-logo-preview" />
          <p class="instruction-text">↑ Select this image in the scanner</p>
        </div>
      </div>
    {:else}
      <div class="encounters-list">
      {#each encounters as encounter, index (encounter.id)}
        <button
          class="encounter-card"
          style="border-color: {getEncounterColor(encounter)}30"
          on:click={() => handleEncounterTap(encounter)}
          in:fly={{ y: 20, delay: index * 50 }}
          disabled={isRefreshing}
        >
          <div class="encounter-icon">
            {#if (encounter.type === EncounterType.WILD_PICLET || encounter.type === EncounterType.FIRST_PICLET) && encounter.picletTypeId}
              {#if monsterImages.has(encounter.picletTypeId)}
                <img 
                  src={monsterImages.get(encounter.picletTypeId)}
                  alt="Piclet"
                />
              {:else}
                <div class="fallback-icon">{getEncounterIcon(encounter)}</div>
              {/if}
            {:else}
              <span class="type-icon">{getEncounterIcon(encounter)}</span>
            {/if}
          </div>
          
          <div class="encounter-info">
            <h3>{encounter.title}</h3>
            <p>{encounter.description}</p>
          </div>
          
          <div class="encounter-arrow">›</div>
        </button>
      {/each}
    </div>
  {/if}
  </PullToRefresh>
</div>
{/if}

<!-- Newly Caught Piclet Dialog -->
{#if showNewlyCaught && newlyCaughtPiclet}
  <NewlyCaughtPicletDetail 
    instance={newlyCaughtPiclet}
    onClose={() => {
      showNewlyCaught = false;
      newlyCaughtPiclet = null;
    }}
  />
{/if}

<style>
  .encounters-page {
    height: 100%;
    overflow: hidden; /* PullToRefresh handles scrolling */
  }
  
  .loading, .empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 60vh;
    text-align: center;
    padding: 1rem;
  }
  
  .spinner {
    width: 48px;
    height: 48px;
    border: 4px solid #f0f0f0;
    border-top-color: #4caf50;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin-bottom: 1rem;
  }
  
  @keyframes spin {
    to { transform: rotate(360deg); }
  }
  
  .empty-icon {
    font-size: 4rem;
    margin-bottom: 1rem;
  }
  
  .empty-state h2 {
    margin: 0 0 0.5rem;
    font-size: 1.25rem;
    color: #333;
  }
  
  .empty-state p {
    color: #666;
    font-size: 0.9rem;
  }
  
  .encounters-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem;
    padding-bottom: 5rem;
  }
  
  .encounter-card {
    display: flex;
    align-items: center;
    gap: 1rem;
    background: #fff;
    border: 2px solid;
    border-radius: 12px;
    padding: 1rem;
    box-shadow: 0 2px 8px rgba(0,0,0,0.08);
    transition: all 0.2s ease;
    cursor: pointer;
    width: 100%;
    text-align: left;
  }
  
  .encounter-card:hover:not(:disabled) {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);
  }
  
  .encounter-card:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
  
  .encounter-icon {
    width: 60px;
    height: 60px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  .encounter-icon img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 8px;
  }
  
  
  
  
  .type-icon, .fallback-icon {
    font-size: 2rem;
  }
  
  .encounter-info {
    flex: 1;
  }
  
  .encounter-info h3 {
    margin: 0 0 0.25rem;
    font-size: 1.1rem;
    font-weight: 600;
    color: #1a1a1a;
  }
  
  .encounter-info p {
    margin: 0;
    font-size: 0.875rem;
    color: #666;
  }
  
  .encounter-arrow {
    font-size: 1.5rem;
    color: #999;
  }
  
  .logo-instruction {
    margin-top: 1.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
  }
  
  .snap-logo-preview {
    width: 120px;
    height: 120px;
    object-fit: contain;
    border: 2px dashed #007bff;
    border-radius: 12px;
    padding: 1rem;
    background: #f0f7ff;
  }
  
  .instruction-text {
    font-size: 0.875rem;
    color: #007bff;
    font-weight: 500;
    margin: 0;
  }

</style>