<script lang="ts">
  import {push} from 'svelte-spa-router'
  import {auth} from '../../lib/stores/auth.svelte'
  import {huntStatus, formatDateTime} from '../../lib/utils'
  import {
    apiCreateTeam,
    apiGetOngoingHunts,
    apiGetHunterTeam,
    apiGetUnstartedHunts,
    apiGetTeamHunters,
    apiJoinTeam,
    apiListTeams,
  } from '../../lib/api/index'
  import type {HuntResponse, HunterSummaryResponse, TeamResponse} from '../../lib/api/types'
  import StatusBadge from '../../lib/components/StatusBadge.svelte'
  import LoadingSpinner from '../../lib/components/LoadingSpinner.svelte'

  $effect(() => {
    if (!auth.isLoggedIn) push('/login')
    else if (auth.isAdmin) push('/admin')
  })

  let ongoing  = $state<HuntResponse[]>([])
  let upcoming = $state<HuntResponse[]>([])
  let loading  = $state(true)
  let error    = $state('')
  let tab      = $state<'active' | 'upcoming'>('active')

  // huntId → team the hunter has joined (null = not joined)
  let ongoingTeams  = $state<Record<string, TeamResponse | null>>({})
  let upcomingTeams = $state<Record<string, TeamResponse | null>>({})

  $effect(() => {
    Promise.all([
      apiGetOngoingHunts(),
      apiGetUnstartedHunts(),
    ]).then(async ([o, u]) => {
      ongoing  = o
      upcoming = u
      const [ongoingEntries, upcomingEntries] = await Promise.all([
        Promise.all(o.map(hunt =>
          apiGetHunterTeam(hunt.id)
            .then(t  => [hunt.id, t] as const)
            .catch(() => [hunt.id, null] as const)
        )),
        Promise.all(u.map(hunt =>
          apiGetHunterTeam(hunt.id)
            .then(t  => [hunt.id, t] as const)
            .catch(() => [hunt.id, null] as const)
        )),
      ])
      ongoingTeams  = Object.fromEntries(ongoingEntries)
      upcomingTeams = Object.fromEntries(upcomingEntries)
    }).catch(e => {
      error = e instanceof Error ? e.message : 'Failed to load hunts'
    }).finally(() => {
      loading = false
    })
  })

  // ── Hunt sheet (shared for active + upcoming) ─────────────────────────────────

  let sheetHunt     = $state<HuntResponse | null>(null)
  let sheetIsActive = $state(false)
  let sheetTeams    = $state<TeamResponse[]>([])
  let sheetMembers  = $state<HunterSummaryResponse[]>([])
  let sheetLoading  = $state(false)
  let newTeamName   = $state('')
  let creatingTeam  = $state(false)
  let joiningTeamId = $state<string | null>(null)
  let sheetError    = $state('')

  function currentTeam(hunt: HuntResponse) {
    return sheetIsActive ? ongoingTeams[hunt.id] : upcomingTeams[hunt.id]
  }

  async function openSheet(hunt: HuntResponse, isActive: boolean) {
    sheetHunt     = hunt
    sheetIsActive = isActive
    sheetError    = ''
    newTeamName   = ''
    sheetMembers  = []
    sheetLoading  = true
    try {
      const myTeam = currentTeam(hunt)
      if (myTeam) {
        const [teams, members] = await Promise.all([
          apiListTeams(hunt.id),
          apiGetTeamHunters(hunt.id, myTeam.id),
        ])
        sheetTeams   = teams
        sheetMembers = members
      } else {
        sheetTeams = await apiListTeams(hunt.id)
      }
    } catch (e: unknown) {
      sheetError = e instanceof Error ? e.message : 'Failed to load teams'
    } finally {
      sheetLoading = false
    }
  }

  function closeSheet() {
    sheetHunt  = null
    sheetTeams = []
  }

  async function createTeam() {
    if (!sheetHunt || !newTeamName.trim()) return
    creatingTeam = true
    sheetError   = ''
    try {
      await apiCreateTeam(sheetHunt.id, newTeamName.trim())
      sheetTeams = await apiListTeams(sheetHunt.id)
      const created = sheetTeams.find(t => t.name === newTeamName.trim())
      if (created) await joinTeam(created.id)
      else newTeamName = ''
    } catch (e: unknown) {
      sheetError = e instanceof Error ? e.message : 'Failed to create team'
    } finally {
      creatingTeam = false
    }
  }

  async function joinTeam(teamId: string) {
    if (!sheetHunt) return
    joiningTeamId = teamId
    sheetError    = ''
    try {
      await apiJoinTeam(sheetHunt.id, teamId)
      const team = sheetTeams.find(t => t.id === teamId) ?? null
      if (sheetIsActive) {
        ongoingTeams = { ...ongoingTeams, [sheetHunt.id]: team }
        push(`/hunt/${sheetHunt.id}`)
      } else {
        upcomingTeams = { ...upcomingTeams, [sheetHunt.id]: team }
        newTeamName   = ''
        closeSheet()
      }
    } catch (e: unknown) {
      sheetError = e instanceof Error ? e.message : 'Failed to join team'
    } finally {
      joiningTeamId = null
    }
  }
</script>

<div class="p-4 pb-20">
  <div class="tabs tabs-boxed bg-base-200 mb-4">
    <button
      class="tab flex-1 font-bold transition-all {tab === 'active' ? 'bg-primary text-primary-content rounded-lg' : 'text-base-content/40'}"
      onclick={() => tab = 'active'}
    >
      Active
      {#if ongoing.length > 0}<span class="badge badge-md ml-1 {tab === 'active' ? 'badge-outline' : 'badge-primary'}">{ongoing.length}</span>{/if}
    </button>
    <button
      class="tab flex-1 font-bold transition-all {tab === 'upcoming' ? 'bg-primary text-primary-content rounded-lg' : 'text-base-content/40'}"
      onclick={() => tab = 'upcoming'}
    >
      Upcoming
      {#if upcoming.length > 0}<span class="badge badge-md ml-1 {tab === 'upcoming' ? 'badge-outline' : 'badge-info'}">{upcoming.length}</span>{/if}
    </button>
  </div>

  {#if loading}
    <LoadingSpinner />
  {:else if error}
    <div class="alert alert-error">{error}</div>
  {:else}
    {#if tab === 'active'}
      {#if ongoing.length === 0}
        <div class="text-center py-16 text-base-content/50">
          <p class="text-4xl mb-3">🔍</p>
          <p class="font-medium">No active hunts right now</p>
        </div>
      {:else}
        <div class="flex flex-col gap-3">
          {#each ongoing as hunt}
            {@const myTeam = ongoingTeams[hunt.id]}
            <button
              class="card bg-base-100 shadow-sm border border-base-200 text-left w-full hover:border-primary hover:shadow-md transition-all"
              onclick={() => myTeam ? push(`/hunt/${hunt.id}`) : openSheet(hunt, true)}
            >
              <div class="card-body p-4 gap-2">
                <div class="flex items-start justify-between gap-2">
                  <h2 class="card-title text-base">{hunt.title}</h2>
                  <StatusBadge status={huntStatus(hunt)} />
                </div>
                <p class="text-xs text-base-content/50">
                  {formatDateTime(hunt.startDateTime)} – {formatDateTime(hunt.endDateTime)}
                </p>
                {#if myTeam}
                  <p class="text-sm font-medium text-primary">Team: {myTeam.name}</p>
                {:else}
                  <p class="text-sm font-medium text-secondary">Join to play →</p>
                {/if}
              </div>
            </button>
          {/each}
        </div>
      {/if}

    {:else}
      {#if upcoming.length === 0}
        <div class="text-center py-16 text-base-content/50">
          <p class="text-4xl mb-3">🔍</p>
          <p class="font-medium">No upcoming hunts</p>
        </div>
      {:else}
        <div class="flex flex-col gap-3">
          {#each upcoming as hunt}
            {@const myTeam = upcomingTeams[hunt.id]}
            <button
              class="card bg-base-100 shadow-sm border border-base-200 text-left w-full hover:border-primary hover:shadow-md transition-all"
              onclick={() => openSheet(hunt, false)}
            >
              <div class="card-body p-4 gap-2">
                <div class="flex items-start justify-between gap-2">
                  <h2 class="card-title text-base">{hunt.title}</h2>
                  <StatusBadge status={huntStatus(hunt)} />
                </div>
                <p class="text-xs text-base-content/50">
                  {formatDateTime(hunt.startDateTime)} – {formatDateTime(hunt.endDateTime)}
                </p>
                {#if myTeam}
                  <p class="text-sm font-medium text-primary">Team: {myTeam.name}</p>
                {:else}
                  <p class="text-sm font-medium text-secondary">Join a team →</p>
                {/if}
              </div>
            </button>
          {/each}
        </div>
      {/if}
    {/if}
  {/if}
</div>

<!-- Hunt sheet -->
{#if sheetHunt}
  {@const hunt = sheetHunt}
  {@const myTeam = sheetIsActive ? ongoingTeams[hunt.id] : upcomingTeams[hunt.id]}
  <div class="fixed inset-0 z-40" onclick={closeSheet} role="presentation"></div>
  <div class="fixed bottom-0 left-0 right-0 z-50 bg-base-200 rounded-t-2xl shadow-2xl max-h-[80vh] overflow-y-auto">
    <div class="p-4 border-b border-base-300 flex items-center justify-between sticky top-0 bg-base-200">
      <div>
        <h3 class="font-bold text-lg">{hunt.title}</h3>
        <p class="text-xs text-base-content/50">{formatDateTime(hunt.startDateTime)} – {formatDateTime(hunt.endDateTime)}</p>
      </div>
      <button class="btn btn-ghost btn-sm btn-circle" onclick={closeSheet}>✕</button>
    </div>

    <div class="p-4 flex flex-col gap-4">
      {#if sheetError}
        <div class="alert alert-error text-sm">{sheetError}</div>
      {/if}

      {#if sheetLoading}
        <LoadingSpinner />
      {:else if myTeam}
        <!-- Already on a team -->
        <div class="rounded-xl bg-base-100 border border-base-300 p-4 flex flex-col gap-3">
          <div>
            <p class="text-xs font-semibold uppercase tracking-wide text-base-content/40 mb-1">Your Team</p>
            <p class="text-lg font-bold">{myTeam.name}</p>
          </div>
          {#if sheetMembers.length > 0}
            <div>
              <p class="text-xs font-semibold uppercase tracking-wide text-base-content/40 mb-2">Members</p>
              <div class="flex flex-col gap-1">
                {#each sheetMembers as member}
                  <p class="text-sm font-medium">{member.name}</p>
                {/each}
              </div>
            </div>
          {/if}
        </div>
        {#if sheetIsActive}
          <button class="btn btn-primary w-full" onclick={() => push(`/hunt/${hunt.id}`)}>
            Play Now →
          </button>
        {/if}
      {:else}
        <!-- Join or create -->
        {#if sheetIsActive}
          <div class="alert alert-info text-sm">This hunt is already in progress — join a team to start playing!</div>
        {/if}
        <form onsubmit={(e) => { e.preventDefault(); createTeam() }} class="flex gap-2">
          <input
            type="text"
            placeholder="New team name"
            class="input input-bordered input-sm flex-1"
            bind:value={newTeamName}
            disabled={creatingTeam}
          />
          <button type="submit" class="btn btn-secondary btn-sm" disabled={creatingTeam || !newTeamName.trim()}>
            {#if creatingTeam}<span class="loading loading-spinner loading-xs"></span>{/if}
            Create
          </button>
        </form>

        {#if sheetTeams.length > 0}
          <div>
            <p class="text-xs font-semibold uppercase tracking-wide text-base-content/40 mb-2">Or join an existing team</p>
            <div class="flex flex-col gap-2">
              {#each sheetTeams as team}
                <button
                  class="card bg-base-100 shadow-sm border border-base-200 text-left w-full hover:border-primary transition-colors"
                  onclick={() => joinTeam(team.id)}
                  disabled={joiningTeamId !== null}
                >
                  <div class="card-body p-4 flex-row items-center justify-between">
                    <p class="font-semibold">{team.name}</p>
                    {#if joiningTeamId === team.id}
                      <span class="loading loading-spinner loading-xs"></span>
                    {/if}
                  </div>
                </button>
              {/each}
            </div>
          </div>
        {/if}
      {/if}
    </div>
  </div>
{/if}
