<svelte:options runes={true} />

<script lang="ts">
  import { onMount } from 'svelte'
  import { searchAdapter, type SearchResult } from '$lib/api/adapters'
  import { getCharacterImage, getWeaponImage, getSummonImage, getPlaceholderImage } from '$lib/utils/images'

  interface Props {
    open?: boolean
    type: 'weapon' | 'character' | 'summon'
    onClose?: () => void
    onAddItems?: (items: SearchResult[]) => void
    canAddMore?: boolean
    requiredProficiencies?: number[]  // For mainhand: restricts to job's proficiencies
  }

  let {
    open = false,
    type = 'weapon',
    onClose = () => {},
    onAddItems = () => {},
    canAddMore = true,
    requiredProficiencies
  }: Props = $props()

  // Search state
  let searchQuery = $state('')
  let searchResults = $state<SearchResult[]>([])
  let isLoading = $state(false)
  let currentPage = $state(1)
  let totalPages = $state(1)
  let hasInitialLoad = $state(false)

  // Filter state
  let elementFilters = $state<number[]>([])
  let rarityFilters = $state<number[]>([])
  let proficiencyFilters = $state<number[]>([])

  // Refs
  let searchInput: HTMLInputElement
  let resultsContainer: HTMLDivElement

  // Constants
  const elements = [
    { value: 0, label: 'Null', color: '#888' },
    { value: 1, label: 'Wind', color: '#4A9B3F' },
    { value: 2, label: 'Fire', color: '#D94444' },
    { value: 3, label: 'Water', color: '#4A7FB8' },
    { value: 4, label: 'Earth', color: '#9B6E3F' },
    { value: 5, label: 'Dark', color: '#6B3E9B' },
    { value: 6, label: 'Light', color: '#F4B643' }
  ]

  const rarities = [
    { value: 1, label: 'R' },
    { value: 2, label: 'SR' },
    { value: 3, label: 'SSR' }
  ]

  const proficiencies = [
    { value: 1, label: 'Sabre' },
    { value: 2, label: 'Dagger' },
    { value: 3, label: 'Spear' },
    { value: 4, label: 'Axe' },
    { value: 5, label: 'Staff' },
    { value: 6, label: 'Gun' },
    { value: 7, label: 'Melee' },
    { value: 8, label: 'Bow' },
    { value: 9, label: 'Harp' },
    { value: 10, label: 'Katana' }
  ]

  // Focus search input and load recent items when opened
  $effect(() => {
    if (open && searchInput) {
      searchInput.focus()
    }
    // Load recent items when opening if we haven't already
    if (open && !hasInitialLoad) {
      hasInitialLoad = true
      performSearch()
    }
  })

  // Search when query or filters change
  $effect(() => {
    // Always search if we have filters or a search query
    // If no query and no filters, still search to show recent items
    if (searchQuery.length >= 2 || elementFilters.length > 0 || rarityFilters.length > 0 || proficiencyFilters.length > 0) {
      performSearch()
    } else if (searchQuery.length === 1) {
      // Don't search with just 1 character
      return
    } else if (searchQuery.length === 0 && elementFilters.length === 0 && rarityFilters.length === 0 && proficiencyFilters.length === 0) {
      // Load recent items when no search criteria
      if (hasInitialLoad) {
        performSearch()
      }
    }
  })

  async function performSearch() {
    isLoading = true

    try {
      const params: any = {
        page: currentPage,
        filters: {}
      }
      
      // Only add query if not empty
      if (searchQuery) {
        params.query = searchQuery
      }
      
      // Only add filters if they have values
      if (elementFilters.length > 0) {
        params.filters.element = elementFilters
      }
      if (rarityFilters.length > 0) {
        params.filters.rarity = rarityFilters
      }
      if (type === 'weapon') {
        // Use required proficiencies (for mainhand) if set, otherwise use user-selected filters
        const profs = requiredProficiencies ?? (proficiencyFilters.length > 0 ? proficiencyFilters : undefined)
        if (profs && profs.length > 0) {
          params.filters.proficiency1 = profs
        }
      }

      let response
      switch (type) {
        case 'weapon':
          response = await searchAdapter.searchWeapons(params)
          break
        case 'character':
          response = await searchAdapter.searchCharacters(params)
          break
        case 'summon':
          response = await searchAdapter.searchSummons(params)
          break
      }

      searchResults = response?.results ?? []
      totalPages = response?.totalPages ?? 1
    } catch (error) {
      console.error('Search failed:', error)
      searchResults = []
    } finally {
      isLoading = false
    }
  }

  function handleItemClick(item: SearchResult) {
    // Only add if we can add more items
    if (canAddMore) {
      onAddItems([item])
    }
  }

  function toggleElementFilter(element: number) {
    if (elementFilters.includes(element)) {
      elementFilters = elementFilters.filter(e => e !== element)
    } else {
      elementFilters = [...elementFilters, element]
    }
  }

  function toggleRarityFilter(rarity: number) {
    if (rarityFilters.includes(rarity)) {
      rarityFilters = rarityFilters.filter(r => r !== rarity)
    } else {
      rarityFilters = [...rarityFilters, rarity]
    }
  }

  function toggleProficiencyFilter(prof: number) {
    if (proficiencyFilters.includes(prof)) {
      proficiencyFilters = proficiencyFilters.filter(p => p !== prof)
    } else {
      proficiencyFilters = [...proficiencyFilters, prof]
    }
  }

  function handleKeyDown(e: KeyboardEvent) {
    if (e.key === 'Escape') {
      onClose()
    }
  }

  function getImageUrl(item: SearchResult): string {
    const id = item.granblueId
    if (!id) return getPlaceholderImage(type, 'grid')

    switch (type) {
      case 'character':
        return getCharacterImage(id, 'grid', '01')
      case 'weapon':
        return getWeaponImage(id, 'grid')
      case 'summon':
        return getSummonImage(id, 'grid')
      default:
        return getPlaceholderImage(type, 'grid')
    }
  }

  function getItemName(item: SearchResult): string {
    const name = item.name
    if (typeof name === 'string') return name
    return name?.en || name?.ja || 'Unknown'
  }
</script>

<aside
  class="sidebar"
  class:open={open}
  aria-hidden={!open}
  aria-label="Search {type}s"
  on:keydown={handleKeyDown}
>
  <header class="sidebar-header">
    <h2>Search {type}s</h2>
    <button class="close-btn" on:click={onClose} aria-label="Close">×</button>
  </header>

  <div class="search-section">
    <input
      bind:this={searchInput}
      bind:value={searchQuery}
      type="text"
      placeholder="Search by name..."
      aria-label="Search"
      class="search-input"
    />
  </div>

  <div class="filters-section">
    <!-- Element filters -->
    <div class="filter-group">
      <label class="filter-label">Element</label>
      <div class="filter-buttons">
        {#each elements as element}
          <button
            class="filter-btn element-btn"
            class:active={elementFilters.includes(element.value)}
            style="--element-color: {element.color}"
            on:click={() => toggleElementFilter(element.value)}
            aria-pressed={elementFilters.includes(element.value)}
          >
            {element.label}
          </button>
        {/each}
      </div>
    </div>

    <!-- Rarity filters -->
    <div class="filter-group">
      <label class="filter-label">Rarity</label>
      <div class="filter-buttons">
        {#each rarities as rarity}
          <button
            class="filter-btn rarity-btn"
            class:active={rarityFilters.includes(rarity.value)}
            on:click={() => toggleRarityFilter(rarity.value)}
            aria-pressed={rarityFilters.includes(rarity.value)}
          >
            {rarity.label}
          </button>
        {/each}
      </div>
    </div>

    <!-- Proficiency filters (weapons only, hidden when required proficiencies set) -->
    {#if type === 'weapon' && !requiredProficiencies}
      <div class="filter-group">
        <label class="filter-label">Proficiency</label>
        <div class="filter-buttons proficiency-grid">
          {#each proficiencies as prof}
            <button
              class="filter-btn prof-btn"
              class:active={proficiencyFilters.includes(prof.value)}
              on:click={() => toggleProficiencyFilter(prof.value)}
              aria-pressed={proficiencyFilters.includes(prof.value)}
            >
              {prof.label}
            </button>
          {/each}
        </div>
      </div>
    {/if}
  </div>

  <!-- Results -->
  <div class="results-section" bind:this={resultsContainer}>
    {#if isLoading}
      <div class="loading">Searching...</div>
    {:else if searchResults.length > 0}
      <ul class="results-list">
        {#each searchResults as item (item.id)}
          <li class="result-item">
            <button
              class="result-button"
              class:disabled={!canAddMore}
              on:click={() => handleItemClick(item)}
              aria-label="{canAddMore ? 'Add' : 'Grid full - cannot add'} {getItemName(item)}"
              disabled={!canAddMore}
            >
              <img
                src={getImageUrl(item)}
                alt={getItemName(item)}
                class="result-image"
              />
              <span class="result-name">{getItemName(item)}</span>
              {#if item.element !== undefined}
                <span
                  class="result-element"
                  style="color: {elements.find(e => e.value === item.element)?.color}"
                >
                  {elements.find(e => e.value === item.element)?.label}
                </span>
              {/if}
            </button>
          </li>
        {/each}
      </ul>

      {#if totalPages > 1}
        <div class="pagination">
          <button
            on:click={() => currentPage = Math.max(1, currentPage - 1)}
            disabled={currentPage === 1}
          >
            Previous
          </button>
          <span>Page {currentPage} of {totalPages}</span>
          <button
            on:click={() => currentPage = Math.min(totalPages, currentPage + 1)}
            disabled={currentPage === totalPages}
          >
            Next
          </button>
        </div>
      {/if}
    {:else if searchQuery.length > 0}
      <div class="no-results">No results found</div>
    {:else if !hasInitialLoad}
      <div class="empty-state">Loading recent items...</div>
    {:else}
      <div class="no-results">No items found</div>
    {/if}
  </div>
</aside>

<style lang="scss">
  .sidebar {
    width: 320px;
    height: 100vh;
    background: var(--app-bg, #fff);
    display: none;
    flex-direction: column;
    box-shadow: -2px 0 8px rgba(0,0,0,0.1);
    border-left: 1px solid #e0e0e0;
    position: sticky;
    top: 0;
    flex-shrink: 0;
  }

  .sidebar.open {
    display: flex;
  }

  .sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid #e0e0e0;
    background: #fafafa;

    h2 {
      margin: 0;
      font-size: 18px;
      font-weight: 600;
    }

    .close-btn {
      background: transparent;
      border: none;
      font-size: 24px;
      cursor: pointer;
      padding: 0;
      width: 32px;
      height: 32px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 4px;

      &:hover {
        background: rgba(0,0,0,0.05);
      }
    }
  }

  .search-section {
    padding: 12px;
    border-bottom: 1px solid #e0e0e0;

    .search-input {
      width: 100%;
      padding: 8px 12px;
      border: 1px solid #ddd;
      border-radius: 6px;
      font-size: 14px;

      &:focus {
        outline: none;
        border-color: #3366ff;
        box-shadow: 0 0 0 2px rgba(51, 102, 255, 0.1);
      }
    }
  }

  .filters-section {
    padding: 12px;
    border-bottom: 1px solid #e0e0e0;
    max-height: 280px;
    overflow-y: auto;

    .filter-group {
      margin-bottom: 12px;

      &:last-child {
        margin-bottom: 0;
      }
    }

    .filter-label {
      display: block;
      font-size: 12px;
      font-weight: 600;
      text-transform: uppercase;
      color: #666;
      margin-bottom: 6px;
    }

    .filter-buttons {
      display: flex;
      flex-wrap: wrap;
      gap: 4px;
    }

    .proficiency-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 4px;
    }

    .filter-btn {
      padding: 4px 8px;
      border: 1px solid #ddd;
      background: white;
      border-radius: 4px;
      font-size: 12px;
      cursor: pointer;
      transition: all 0.2s;

      &:hover {
        background: #f5f5f5;
      }

      &.active {
        background: #3366ff;
        color: white;
        border-color: #3366ff;
      }

      &.element-btn.active {
        background: var(--element-color);
        border-color: var(--element-color);
      }
    }
  }


  .results-section {
    flex: 1;
    overflow-y: auto;
    padding: 12px;

    .loading, .no-results, .empty-state {
      text-align: center;
      padding: 24px;
      color: #666;
      font-size: 14px;
    }

    .results-list {
      list-style: none;
      padding: 0;
      margin: 0;
    }

    .result-item {
      margin-bottom: 4px;

      .result-button {
        width: 100%;
        display: flex;
        align-items: center;
        padding: 8px;
        border: 1px solid transparent;
        border-radius: 6px;
        background: white;
        cursor: pointer;
        transition: all 0.2s;
        text-align: left;

        &:hover {
          background: #f5f5f5;
          border-color: #3366ff;
          box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        &:active:not(:disabled) {
          transform: scale(0.98);
        }

        &.disabled,
        &:disabled {
          opacity: 0.5;
          cursor: not-allowed;
          background: #f9f9f9;
          border-color: #ddd;

          &:hover {
            background: #f9f9f9;
            border-color: #ddd;
            box-shadow: none;
          }
        }
      }

      .result-image {
        width: 48px;
        height: 48px;
        object-fit: cover;
        border-radius: 4px;
        margin-right: 12px;
        border: 1px solid #e0e0e0;
      }

      .result-name {
        flex: 1;
        font-size: 14px;
        color: #333;
      }

      .result-element {
        font-size: 12px;
        font-weight: 600;
        margin-left: 8px;
      }
    }

    .pagination {
      display: flex;
      justify-content: center;
      align-items: center;
      gap: 12px;
      margin-top: 16px;
      padding-top: 12px;
      border-top: 1px solid #e0e0e0;

      button {
        padding: 4px 12px;
        border: 1px solid #ddd;
        background: white;
        border-radius: 4px;
        font-size: 13px;
        cursor: pointer;

        &:hover:not(:disabled) {
          background: #f0f0f0;
        }

        &:disabled {
          opacity: 0.5;
          cursor: not-allowed;
        }
      }

      span {
        font-size: 13px;
        color: #666;
      }
    }
  }
</style>
