<script setup lang="ts">
import { ref, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import type { SbaPlayer, LineupPlayerRequest, SubmitLineupsRequest } from '~/types'
import ActionButton from '~/components/UI/ActionButton.vue'

const route = useRoute()
const router = useRouter()
const config = useRuntimeConfig()

// Game and team data
const gameId = ref(route.params.id as string)
const homeTeamId = ref<number | null>(null)
const awayTeamId = ref<number | null>(null)
const season = ref(3)

// Active tab (home or away)
type TeamTab = 'home' | 'away'
const activeTab = ref<TeamTab>('away') // Away bats first

// Roster data
const homeRoster = ref<SbaPlayer[]>([])
const awayRoster = ref<SbaPlayer[]>([])
const loadingRoster = ref(false)
const submittingLineups = ref(false)

// Lineup state - 10 slots each (1-9 batting, 10 pitcher)
interface LineupSlot {
  player: SbaPlayer | null
  position: string | null
  battingOrder: number | null // 1-9 for batters, null for pitcher
}

const homeLineup = ref<LineupSlot[]>(Array(10).fill(null).map((_, i) => ({
  player: null,
  position: null,
  battingOrder: i < 9 ? i + 1 : null // Slots 0-8 are batting order 1-9, slot 9 is pitcher
})))

const awayLineup = ref<LineupSlot[]>(Array(10).fill(null).map((_, i) => ({
  player: null,
  position: null,
  battingOrder: i < 9 ? i + 1 : null
})))

// Available roster for dragging (players not in lineup)
const availableHomeRoster = computed(() => {
  const usedPlayerIds = new Set(homeLineup.value.filter(s => s.player).map(s => s.player!.id))
  return homeRoster.value.filter(p => !usedPlayerIds.has(p.id))
})

const availableAwayRoster = computed(() => {
  const usedPlayerIds = new Set(awayLineup.value.filter(s => s.player).map(s => s.player!.id))
  return awayRoster.value.filter(p => !usedPlayerIds.has(p.id))
})

// Current lineup based on active tab
const currentLineup = computed(() => activeTab.value === 'home' ? homeLineup.value : awayLineup.value)
const currentRoster = computed(() => activeTab.value === 'home' ? availableHomeRoster.value : availableAwayRoster.value)

// Slot 10 (pitcher) should be disabled if P is selected in batting order
const pitcherSlotDisabled = computed(() => {
  const lineup = currentLineup.value
  return lineup.slice(0, 9).some(slot => slot.position === 'P')
})

// Validation
const duplicatePositions = computed(() => {
  const lineup = currentLineup.value
  const positionCounts = new Map<string, number>()

  lineup.forEach(slot => {
    if (slot.player && slot.position) {
      positionCounts.set(slot.position, (positionCounts.get(slot.position) || 0) + 1)
    }
  })

  return Array.from(positionCounts.entries())
    .filter(([_, count]) => count > 1)
    .map(([pos, _]) => pos)
})

const validationErrors = computed(() => {
  const errors: string[] = []

  // Check both lineups
  const homeErrors = validateLineup(homeLineup.value, 'Home')
  const awayErrors = validateLineup(awayLineup.value, 'Away')

  return [...homeErrors, ...awayErrors]
})

function validateLineup(lineup: LineupSlot[], teamName: string): string[] {
  const errors: string[] = []

  // Check if P is in batting order
  const pitcherInBattingOrder = lineup.slice(0, 9).some(s => s.position === 'P')
  const requiredSlots = pitcherInBattingOrder ? 9 : 10

  // Check if all slots filled
  const filledSlots = lineup.filter(s => s.player).length
  if (filledSlots < requiredSlots) {
    errors.push(`${teamName}: Fill all ${requiredSlots} lineup slots`)
  }

  // Check for missing positions
  const missingPositions = lineup.filter(s => s.player && !s.position).length
  if (missingPositions > 0) {
    errors.push(`${teamName}: ${missingPositions} player${missingPositions > 1 ? 's' : ''} missing position`)
  }

  // Check for duplicate positions
  const positionCounts = new Map<string, number>()
  lineup.forEach(slot => {
    if (slot.player && slot.position) {
      positionCounts.set(slot.position, (positionCounts.get(slot.position) || 0) + 1)
    }
  })

  const duplicates = Array.from(positionCounts.entries())
    .filter(([_, count]) => count > 1)
    .map(([pos, _]) => pos)

  if (duplicates.length > 0) {
    errors.push(`${teamName}: Duplicate positions - ${duplicates.join(', ')}`)
  }

  return errors
}

const canSubmit = computed(() => {
  return validationErrors.value.length === 0
})

// Get player's available positions
function getPlayerPositions(player: SbaPlayer): string[] {
  const positions: string[] = []
  for (let i = 1; i <= 8; i++) {
    const pos = player[`pos_${i}` as keyof SbaPlayer]
    if (pos && typeof pos === 'string') {
      positions.push(pos)
    }
  }
  // Always add DH as an option for all players
  if (!positions.includes('DH')) {
    positions.push('DH')
  }
  return positions
}

// Drag handlers
function handleRosterDrag(player: SbaPlayer, toSlotIndex: number, fromSlotIndex?: number) {
  const lineup = activeTab.value === 'home' ? homeLineup.value : awayLineup.value

  // If dragging from another slot, swap or move
  if (fromSlotIndex !== undefined && fromSlotIndex !== toSlotIndex) {
    const fromSlot = lineup[fromSlotIndex]
    const toSlot = lineup[toSlotIndex]

    // Swap players
    const tempPlayer = toSlot.player
    const tempPosition = toSlot.position

    toSlot.player = fromSlot.player
    toSlot.position = fromSlot.position

    fromSlot.player = tempPlayer
    fromSlot.position = tempPosition
  } else if (fromSlotIndex === undefined) {
    // Adding from roster pool
    lineup[toSlotIndex].player = player

    // For pitcher slot (index 9), always use 'P'
    if (toSlotIndex === 9) {
      lineup[toSlotIndex].position = 'P'
    } else {
      // Auto-suggest first available position
      const availablePositions = getPlayerPositions(player)
      if (availablePositions.length > 0) {
        lineup[toSlotIndex].position = availablePositions[0]
      }
    }
  }
}

function removePlayer(slotIndex: number) {
  const lineup = activeTab.value === 'home' ? homeLineup.value : awayLineup.value
  lineup[slotIndex].player = null
  lineup[slotIndex].position = null
}

// Fetch game data
async function fetchGameData() {
  try {
    const response = await fetch(`${config.public.apiUrl}/api/games/${gameId.value}`)
    const data = await response.json()
    homeTeamId.value = data.home_team_id
    awayTeamId.value = data.away_team_id
  } catch (error) {
    console.error('Failed to fetch game data:', error)
  }
}

// Fetch roster for a team
async function fetchRoster(teamId: number) {
  try {
    loadingRoster.value = true
    const response = await fetch(`${config.public.apiUrl}/api/teams/${teamId}/roster?season=${season.value}`)
    const data = await response.json()
    return data.players as SbaPlayer[]
  } catch (error) {
    console.error(`Failed to fetch roster for team ${teamId}:`, error)
    return []
  } finally {
    loadingRoster.value = false
  }
}

// Submit lineups
async function submitLineups() {
  if (!canSubmit.value || submittingLineups.value) return

  submittingLineups.value = true

  // Build request
  const homeLineupRequest: LineupPlayerRequest[] = homeLineup.value
    .filter(s => s.player)
    .map(s => ({
      player_id: s.player!.id,
      position: s.position!,
      batting_order: s.battingOrder
    }))

  const awayLineupRequest: LineupPlayerRequest[] = awayLineup.value
    .filter(s => s.player)
    .map(s => ({
      player_id: s.player!.id,
      position: s.position!,
      batting_order: s.battingOrder
    }))

  const request: SubmitLineupsRequest = {
    home_lineup: homeLineupRequest,
    away_lineup: awayLineupRequest
  }

  console.log('Submitting lineup request:', JSON.stringify(request, null, 2))

  try {
    const response = await fetch(`${config.public.apiUrl}/api/games/${gameId.value}/lineups`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(request)
    })

    if (!response.ok) {
      const error = await response.json()
      console.error('Lineup submission error:', error)

      // Handle Pydantic validation errors
      if (error.detail && Array.isArray(error.detail)) {
        const messages = error.detail.map((err: any) => {
          if (err.loc) {
            const location = err.loc.join(' → ')
            return `${location}: ${err.msg}`
          }
          return err.msg || JSON.stringify(err)
        })
        throw new Error(`Validation errors:\n${messages.join('\n')}`)
      }

      throw new Error(typeof error.detail === 'string' ? error.detail : JSON.stringify(error.detail))
    }

    const result = await response.json()
    console.log('Lineups submitted:', result)

    // Redirect to game page
    router.push(`/games/${gameId.value}`)
  } catch (error) {
    console.error('Failed to submit lineups:', error)
    alert(error instanceof Error ? error.message : 'Failed to submit lineups')
  } finally {
    submittingLineups.value = false
  }
}

// Initialize
onMounted(async () => {
  await fetchGameData()

  if (homeTeamId.value) {
    homeRoster.value = await fetchRoster(homeTeamId.value)
  }
  if (awayTeamId.value) {
    awayRoster.value = await fetchRoster(awayTeamId.value)
  }
})
</script>

<template>
  <div class="min-h-screen bg-gray-900 text-white p-4">
    <div class="max-w-6xl mx-auto">
      <!-- Header -->
      <div class="mb-6">
        <h1 class="text-3xl font-bold mb-2">Build Your Lineup</h1>
        <p class="text-gray-400">Drag players from the roster to the lineup slots</p>
      </div>

      <!-- Tabs -->
      <div class="flex gap-2 mb-6 border-b border-gray-700">
        <button
          @click="activeTab = 'away'"
          :class="[
            'px-6 py-3 font-semibold transition-colors',
            activeTab === 'away'
              ? 'bg-blue-600 text-white border-b-2 border-blue-500'
              : 'text-gray-400 hover:text-white'
          ]"
        >
          Away Lineup
        </button>
        <button
          @click="activeTab = 'home'"
          :class="[
            'px-6 py-3 font-semibold transition-colors',
            activeTab === 'home'
              ? 'bg-blue-600 text-white border-b-2 border-blue-500'
              : 'text-gray-400 hover:text-white'
          ]"
        >
          Home Lineup
        </button>
      </div>

      <!-- Loading state -->
      <div v-if="loadingRoster" class="text-center py-12">
        <div class="text-xl">Loading roster...</div>
      </div>

      <!-- Main content -->
      <div v-else class="grid grid-cols-1 lg:grid-cols-3 gap-6">
        <!-- Roster Pool (Sticky on desktop) -->
        <div class="lg:col-span-1">
          <div class="lg:sticky lg:top-4">
            <h2 class="text-xl font-bold mb-4">Available Players</h2>
            <div class="bg-gray-800 rounded-lg p-4 space-y-2 max-h-[calc(100vh-8rem)] overflow-y-auto">
            <div
              v-for="player in currentRoster"
              :key="player.id"
              @dragstart="(e) => e.dataTransfer?.setData('player', JSON.stringify(player))"
              draggable="true"
              class="bg-gray-700 rounded p-3 cursor-move hover:bg-gray-600 transition-colors"
            >
              <div class="font-semibold">{{ player.name }}</div>
              <div class="text-sm text-gray-400">
                {{ getPlayerPositions(player).join(', ') || 'No positions' }}
              </div>
            </div>

            <div v-if="currentRoster.length === 0" class="text-gray-500 text-center py-4">
              All players assigned
            </div>
            </div>
          </div>
        </div>

        <!-- Lineup Slots -->
        <div class="lg:col-span-2">
          <h2 class="text-xl font-bold mb-4">Lineup</h2>

          <!-- Batting order slots (1-9) -->
          <div class="space-y-3 mb-6">
            <div
              v-for="(slot, index) in currentLineup.slice(0, 9)"
              :key="index"
              class="bg-gray-800 rounded-lg p-4"
            >
              <div class="flex items-center gap-4">
                <!-- Batting order number -->
                <div class="text-2xl font-bold text-gray-500 w-8">
                  {{ index + 1 }}
                </div>

                <!-- Player slot -->
                <div
                  class="flex-1"
                  @drop.prevent="(e) => {
                    const playerData = e.dataTransfer?.getData('player')
                    const fromSlotData = e.dataTransfer?.getData('fromSlot')
                    if (playerData) {
                      const player = JSON.parse(playerData) as SbaPlayer
                      const fromSlot = fromSlotData ? parseInt(fromSlotData) : undefined
                      handleRosterDrag(player, index, fromSlot)
                    }
                  }"
                  @dragover.prevent
                >
                  <div
                    v-if="slot.player"
                    class="bg-blue-900 rounded p-3 cursor-move"
                    draggable="true"
                    @dragstart="(e) => {
                      e.dataTransfer?.setData('player', JSON.stringify(slot.player))
                      e.dataTransfer?.setData('fromSlot', index.toString())
                    }"
                  >
                    <div class="flex justify-between items-start">
                      <div class="flex-1">
                        <div class="font-semibold">{{ slot.player.name }}</div>
                        <div class="text-sm text-gray-400 mt-1">
                          Available: {{ getPlayerPositions(slot.player).join(', ') }}
                        </div>
                      </div>
                      <button
                        @click="removePlayer(index)"
                        class="text-red-400 hover:text-red-300 ml-2"
                      >
                        ✕
                      </button>
                    </div>
                  </div>
                  <div v-else class="border-2 border-dashed border-gray-600 rounded p-4 text-center text-gray-500">
                    Drop player here
                  </div>
                </div>

                <!-- Position selector -->
                <div class="w-32">
                  <select
                    v-if="slot.player"
                    v-model="slot.position"
                    :class="[
                      'w-full bg-gray-700 border rounded px-3 py-2',
                      duplicatePositions.includes(slot.position || '')
                        ? 'border-red-500 font-bold text-red-400'
                        : 'border-gray-600'
                    ]"
                  >
                    <option :value="null">Position</option>
                    <option
                      v-for="pos in getPlayerPositions(slot.player)"
                      :key="pos"
                      :value="pos"
                    >
                      {{ pos }}
                    </option>
                  </select>
                  <div v-else class="text-gray-600 text-sm text-center">
                    -
                  </div>
                </div>
              </div>
            </div>
          </div>

          <!-- Pitcher slot (10) -->
          <div class="mb-6">
            <h3 class="text-lg font-semibold mb-3 flex items-center gap-2">
              Pitcher (Non-Batting)
              <span v-if="pitcherSlotDisabled" class="text-sm text-yellow-400">
                (Disabled - Pitcher batting)
              </span>
            </h3>
            <div
              :class="[
                'bg-gray-800 rounded-lg p-4',
                pitcherSlotDisabled && 'opacity-50 pointer-events-none'
              ]"
            >
              <div class="flex items-center gap-4">
                <div class="text-2xl font-bold text-gray-500 w-8">P</div>

                <div
                  class="flex-1"
                  @drop.prevent="(e) => {
                    const playerData = e.dataTransfer?.getData('player')
                    const fromSlotData = e.dataTransfer?.getData('fromSlot')
                    if (playerData) {
                      const player = JSON.parse(playerData) as SbaPlayer
                      const fromSlot = fromSlotData ? parseInt(fromSlotData) : undefined
                      handleRosterDrag(player, 9, fromSlot)
                    }
                  }"
                  @dragover.prevent
                >
                  <div
                    v-if="currentLineup[9].player"
                    class="bg-blue-900 rounded p-3 cursor-move"
                    draggable="true"
                    @dragstart="(e) => {
                      e.dataTransfer?.setData('player', JSON.stringify(currentLineup[9].player))
                      e.dataTransfer?.setData('fromSlot', '9')
                    }"
                  >
                    <div class="flex justify-between items-start">
                      <div class="flex-1">
                        <div class="font-semibold">{{ currentLineup[9].player.name }}</div>
                        <div class="text-sm text-gray-400 mt-1">
                          Available: {{ getPlayerPositions(currentLineup[9].player).join(', ') }}
                        </div>
                      </div>
                      <button
                        @click="removePlayer(9)"
                        class="text-red-400 hover:text-red-300 ml-2"
                      >
                        ✕
                      </button>
                    </div>
                  </div>
                  <div v-else class="border-2 border-dashed border-gray-600 rounded p-4 text-center text-gray-500">
                    Drop pitcher here
                  </div>
                </div>

                <div class="w-32">
                  <div class="text-gray-600 text-sm text-center font-semibold">P</div>
                </div>
              </div>
            </div>
          </div>

          <!-- Validation errors -->
          <div v-if="validationErrors.length > 0" class="bg-red-900/30 border border-red-500 rounded-lg p-4 mb-4">
            <div class="font-semibold mb-2">Please fix the following errors:</div>
            <ul class="list-disc list-inside space-y-1">
              <li v-for="error in validationErrors" :key="error" class="text-sm">
                {{ error }}
              </li>
            </ul>
          </div>

          <!-- Submit button -->
          <ActionButton
            variant="success"
            size="lg"
            full-width
            :disabled="!canSubmit"
            :loading="submittingLineups"
            @click="submitLineups"
          >
            {{ submittingLineups ? 'Submitting Lineups...' : (canSubmit ? 'Submit Lineups & Start Game' : 'Complete Both Lineups to Continue') }}
          </ActionButton>
        </div>
      </div>
    </div>
  </div>
</template>
