import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { ObjectivResultOut, LeaderboardEntryOut } from '@/api/types.gen'

export type Objective = ObjectivResultOut

interface UserInfo {
  username: string
  rank: number | null
  score: number
  runsSubmitted: number
  deathsCount: number
  isStaff: boolean
}

export const useNoitaStore = defineStore('noita', () => {
  // State
  const userInfo = ref<UserInfo>({
    username: 'Player',
    rank: null,
    score: 0,
    runsSubmitted: 0,
    deathsCount: 0,
    isStaff: false,
  })
  const objectives = ref<Objective[]>([])
  const leaderboard = ref<LeaderboardEntryOut[]>([])
  const isLoadingLeaderboard = ref(false)
  const isUploading = ref(false)
  const error = ref<string>('')

  // Actions
  const fetchUserResults = async () => {
    try {
      const response = await fetch('/api/noita/results')
      if (!response.ok) throw new Error('Failed to fetch results')

      const results = await response.json()
      userInfo.value.score = results.total_score
      userInfo.value.deathsCount = results.deaths_count
      userInfo.value.runsSubmitted = results.objectives.length
      objectives.value = results.objectives
    } catch (err) {
      error.value = 'Failed to fetch user results'
      console.error('Error fetching results:', err)
    }
  }

  const fetchLeaderboard = async () => {
    isLoadingLeaderboard.value = true
    try {
      const response = await fetch('/api/noita/leaderboard')
      if (!response.ok) throw new Error('Failed to fetch leaderboard')

      const data = await response.json()
      leaderboard.value = data.leaderboard

      // Find current user's rank
      const userRank = leaderboard.value.find(
        (entry) => entry.username === userInfo.value.username
      )

      if (userRank) {
        userInfo.value.rank = userRank.rank
        userInfo.value.score = userRank.total_score
        userInfo.value.deathsCount = userRank.deaths_count
      }
    } catch (err) {
      error.value = 'Failed to fetch leaderboard'
      console.error('Error fetching leaderboard:', err)
    } finally {
      isLoadingLeaderboard.value = false
    }
  }

  const loadUserData = async () => {
    try {
      const response = await fetch('/api/user')
      if (response.ok) {
        const user = await response.json()
        if (user.is_authenticated) {
          userInfo.value.username = user.username
          userInfo.value.isStaff = user.is_staff || false
        }
      }
    } catch (err) {
      console.error('Error fetching user info:', err)
    }

    await Promise.all([fetchUserResults(), fetchLeaderboard()])
  }

  const submitRun = async (files: File[]) => {
    if (files.length === 0) return

    isUploading.value = true
    try {
      for (const file of files) {
        const formData = new FormData()
        formData.append('file', file)

        const response = await fetch('/api/noita/submit', {
          method: 'POST',
          body: formData,
        })

        if (!response.ok) {
          const errorData = await response.json()
          throw new Error(errorData.detail || 'Unknown error')
        }

        const result = await response.json()
        console.log('Submission successful:', result)
      }

      // Refresh objectives, score, and rank after successful submission
      await Promise.all([fetchUserResults(), fetchLeaderboard()])
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Unknown error'
      error.value = `Error submitting run: ${errorMessage}`
      throw err
    } finally {
      isUploading.value = false
    }
  }

  const clearCache = async () => {
    try {
      const response = await fetch('/api/cache/clear', {
        method: 'POST',
      })

      if (!response.ok) {
        const errorData = await response.json()
        throw new Error(errorData.detail || 'Unknown error')
      }

      await Promise.all([fetchUserResults(), fetchLeaderboard()])
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Unknown error'
      error.value = `Error clearing cache: ${errorMessage}`
      throw err
    }
  }

  const refreshData = async () => {
    await Promise.all([fetchUserResults(), fetchLeaderboard()])
  }

  return {
    // State
    userInfo,
    objectives,
    leaderboard,
    isLoadingLeaderboard,
    isUploading,
    error,

    // Actions
    fetchUserResults,
    fetchLeaderboard,
    loadUserData,
    submitRun,
    clearCache,
    refreshData,
  }
})
