import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import type { MarathonResponse, AssignmentResponse } from '@shared/types'

interface MarathonState {
  marathons: MarathonResponse[]
  selectedMarathonId: number | null
  currentAssignment: AssignmentResponse | null
  isLoading: boolean
  error: string | null

  loadMarathons: () => Promise<void>
  selectMarathon: (marathonId: number) => Promise<void>
  loadCurrentAssignment: () => Promise<void>
  syncTime: (minutes: number) => Promise<void>
  reset: () => void
}

export const useMarathonStore = create<MarathonState>()(
  persist(
    (set, get) => ({
      marathons: [],
      selectedMarathonId: null,
      currentAssignment: null,
      isLoading: false,
      error: null,

      loadMarathons: async () => {
        set({ isLoading: true, error: null })

        const result = await window.electronAPI.apiRequest<MarathonResponse[]>('GET', '/marathons')

        if (!result.success) {
          set({ isLoading: false, error: result.error || 'Failed to load marathons' })
          return
        }

        const marathons = result.data || []
        const activeMarathons = marathons.filter(m => m.status === 'active')

        set({ marathons: activeMarathons, isLoading: false })

        // If we have a selected marathon, verify it's still valid
        const { selectedMarathonId } = get()
        if (selectedMarathonId) {
          const stillExists = activeMarathons.some(m => m.id === selectedMarathonId)
          if (!stillExists && activeMarathons.length > 0) {
            // Select first available marathon
            await get().selectMarathon(activeMarathons[0].id)
          } else if (stillExists) {
            // Reload assignment for current selection
            await get().loadCurrentAssignment()
          }
        } else if (activeMarathons.length > 0) {
          // No selection, select first marathon
          await get().selectMarathon(activeMarathons[0].id)
        }
      },

      selectMarathon: async (marathonId: number) => {
        set({ selectedMarathonId: marathonId, currentAssignment: null })
        await get().loadCurrentAssignment()
      },

      loadCurrentAssignment: async () => {
        const { selectedMarathonId } = get()
        if (!selectedMarathonId) {
          set({ currentAssignment: null })
          return
        }

        const result = await window.electronAPI.apiRequest<AssignmentResponse | null>(
          'GET',
          `/marathons/${selectedMarathonId}/current-assignment`
        )

        if (result.success) {
          set({ currentAssignment: result.data ?? null })
        } else {
          // User might not be participant of this marathon
          set({ currentAssignment: null, error: result.error })
        }
      },

      syncTime: async (minutes: number) => {
        const { currentAssignment } = get()
        if (!currentAssignment || currentAssignment.status !== 'active') {
          return
        }

        const result = await window.electronAPI.apiRequest(
          'PATCH',
          `/assignments/${currentAssignment.id}/track-time`,
          { minutes }
        )

        if (result.success) {
          // Update local assignment with new tracked time
          set({
            currentAssignment: {
              ...currentAssignment,
              tracked_time_minutes: minutes
            }
          })
        }
      },

      reset: () => {
        set({
          marathons: [],
          selectedMarathonId: null,
          currentAssignment: null,
          isLoading: false,
          error: null
        })
      }
    }),
    {
      name: 'marathon-storage',
      partialize: (state) => ({ selectedMarathonId: state.selectedMarathonId })
    }
  )
)
