import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import type { Task, TaskStatus, ProcessingTrack, ProcessingOptions } from '@/types/apiV2'

/**
 * Processing state for tracking ongoing operations
 */
export interface ProcessingState {
  isProcessing: boolean
  startedAt: string | null
  track: ProcessingTrack | null
  options: ProcessingOptions | null
}

/**
 * Cached task info for quick display without API calls
 */
export interface CachedTask {
  taskId: string
  filename: string | null
  status: TaskStatus
  updatedAt: string
  processingTrack?: ProcessingTrack
}

/**
 * Task Store State
 * Centralized state management for task operations
 */
interface TaskState {
  // Current active task
  currentTaskId: string | null

  // Processing state for current task
  processingState: ProcessingState

  // Recently accessed tasks cache (max 20)
  recentTasks: CachedTask[]

  // Actions
  setCurrentTask: (taskId: string | null, filename?: string | null) => void
  clearCurrentTask: () => void

  // Processing state actions
  startProcessing: (track: ProcessingTrack | null, options?: ProcessingOptions) => void
  stopProcessing: () => void

  // Cache management
  updateTaskCache: (task: Task | CachedTask) => void
  updateTaskStatus: (taskId: string, status: TaskStatus, track?: ProcessingTrack) => void
  removeFromCache: (taskId: string) => void
  clearCache: () => void

  // Get cached task
  getCachedTask: (taskId: string) => CachedTask | undefined
}

/**
 * Maximum number of recent tasks to cache
 */
const MAX_RECENT_TASKS = 20

/**
 * Task Store
 * Manages task state with localStorage persistence
 */
export const useTaskStore = create<TaskState>()(
  persist(
    (set, get) => ({
      // Initial state
      currentTaskId: null,
      processingState: {
        isProcessing: false,
        startedAt: null,
        track: null,
        options: null,
      },
      recentTasks: [],

      // Set current task
      setCurrentTask: (taskId, filename) => {
        set({ currentTaskId: taskId })

        // Add to cache if we have task info
        if (taskId && filename !== undefined) {
          const existing = get().recentTasks.find(t => t.taskId === taskId)
          if (!existing) {
            get().updateTaskCache({
              taskId,
              filename,
              status: 'pending',
              updatedAt: new Date().toISOString(),
            })
          }
        }
      },

      // Clear current task
      clearCurrentTask: () => {
        set({
          currentTaskId: null,
          processingState: {
            isProcessing: false,
            startedAt: null,
            track: null,
            options: null,
          },
        })
      },

      // Start processing
      startProcessing: (track, options) => {
        set({
          processingState: {
            isProcessing: true,
            startedAt: new Date().toISOString(),
            track,
            options: options || null,
          },
        })

        // Update cache status
        const currentTaskId = get().currentTaskId
        if (currentTaskId) {
          get().updateTaskStatus(currentTaskId, 'processing', track || undefined)
        }
      },

      // Stop processing
      stopProcessing: () => {
        set((state) => ({
          processingState: {
            ...state.processingState,
            isProcessing: false,
          },
        }))
      },

      // Update task in cache
      updateTaskCache: (task) => {
        set((state) => {
          const taskId = 'task_id' in task ? task.task_id : task.taskId
          // Extract processing track from either Task (snake_case) or CachedTask (camelCase)
          const track = 'processing_track' in task
            ? task.processing_track
            : ('processingTrack' in task ? task.processingTrack : undefined)
          const cached: CachedTask = {
            taskId,
            filename: task.filename || null,
            status: task.status,
            updatedAt: new Date().toISOString(),
            processingTrack: track,
          }

          // Remove existing entry if present
          const filtered = state.recentTasks.filter(t => t.taskId !== taskId)

          // Add to front and limit size
          const updated = [cached, ...filtered].slice(0, MAX_RECENT_TASKS)

          return { recentTasks: updated }
        })
      },

      // Update task status in cache
      updateTaskStatus: (taskId, status, track) => {
        set((state) => {
          const updated = state.recentTasks.map(t => {
            if (t.taskId === taskId) {
              return {
                ...t,
                status,
                processingTrack: track || t.processingTrack,
                updatedAt: new Date().toISOString(),
              }
            }
            return t
          })
          return { recentTasks: updated }
        })
      },

      // Remove task from cache
      removeFromCache: (taskId) => {
        set((state) => ({
          recentTasks: state.recentTasks.filter(t => t.taskId !== taskId),
          // Also clear current task if it matches
          currentTaskId: state.currentTaskId === taskId ? null : state.currentTaskId,
        }))
      },

      // Clear all cached tasks
      clearCache: () => {
        set({
          recentTasks: [],
          currentTaskId: null,
          processingState: {
            isProcessing: false,
            startedAt: null,
            track: null,
            options: null,
          },
        })
      },

      // Get cached task by ID
      getCachedTask: (taskId) => {
        return get().recentTasks.find(t => t.taskId === taskId)
      },
    }),
    {
      name: 'tool-ocr-task-store',
      // Only persist essential state, not processing state
      partialize: (state) => ({
        currentTaskId: state.currentTaskId,
        recentTasks: state.recentTasks,
      }),
    }
  )
)

/**
 * Helper hook to get current task from cache
 */
export function useCurrentTask() {
  const currentTaskId = useTaskStore((state) => state.currentTaskId)
  const recentTasks = useTaskStore((state) => state.recentTasks)

  if (!currentTaskId) return null
  return recentTasks.find(t => t.taskId === currentTaskId) || null
}

/**
 * Helper hook for processing state
 */
export function useProcessingState() {
  return useTaskStore((state) => state.processingState)
}
