import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { customTaskStatusService, type AllTaskStatusesResponse, type CustomTaskStatus, type SystemTaskStatus } from '@/services/customTaskStatus'

interface ProjectTaskStatuses {
  projectId: number
  data: AllTaskStatusesResponse
  lastFetched: number
}

export const useTaskStatusesStore = defineStore('taskStatuses', () => {
  // Cache task statuses by project ID
  const projectStatuses = ref<Map<number, ProjectTaskStatuses>>(new Map())
  const loading = ref<Set<number>>(new Set())
  const error = ref<string | null>(null)

  // Cache duration: 5 minutes
  const CACHE_DURATION = 5 * 60 * 1000

  // Get cached statuses for a project
  const getProjectStatuses = computed(() => {
    return (projectId: number): AllTaskStatusesResponse | null => {
      const cached = projectStatuses.value.get(projectId)
      if (!cached) return null

      // Check if cache is still valid
      const now = Date.now()
      if (now - cached.lastFetched > CACHE_DURATION) {
        // Cache expired, remove it
        projectStatuses.value.delete(projectId)
        return null
      }

      return cached.data
    }
  })

  // Check if statuses are currently being loaded for a project
  const isLoading = computed(() => {
    return (projectId: number): boolean => {
      return loading.value.has(projectId)
    }
  })

  // Get all status options (system + custom) for a project
  const getAllStatusOptions = computed(() => {
    return (projectId: number) => {
      const statuses = getProjectStatuses.value(projectId)
      if (!statuses) return []

      const options: Array<CustomTaskStatus | SystemTaskStatus> = []
      
      // Add system statuses first
      statuses.system_statuses.forEach(status => {
        options.push(status)
      })
      
      // Add custom statuses
      statuses.statuses.forEach(status => {
        options.push(status)
      })
      
      return options
    }
  })

  // Get a specific status by ID for a project
  const getStatusById = computed(() => {
    return (projectId: number, statusId: string) => {
      const statuses = getProjectStatuses.value(projectId)
      if (!statuses) return null

      // Check custom statuses first
      const customStatus = statuses.statuses.find(s => s.id === statusId)
      if (customStatus) return customStatus

      // Check system statuses
      const systemStatus = statuses.system_statuses.find(s => s.id === statusId)
      if (systemStatus) return systemStatus

      return null
    }
  })

  // Fetch task statuses for a project
  async function fetchProjectStatuses(projectId: number, force = false): Promise<AllTaskStatusesResponse> {
    // Return cached data if available and not forced
    if (!force) {
      const cached = getProjectStatuses.value(projectId)
      if (cached) {
        return cached
      }
    }

    // Check if already loading
    if (loading.value.has(projectId)) {
      // Wait for existing request to complete
      return new Promise((resolve, reject) => {
        const checkInterval = setInterval(() => {
          if (!loading.value.has(projectId)) {
            clearInterval(checkInterval)
            const cached = getProjectStatuses.value(projectId)
            if (cached) {
              resolve(cached)
            } else {
              reject(new Error('Failed to load task statuses'))
            }
          }
        }, 100)
        
        // Timeout after 10 seconds
        setTimeout(() => {
          clearInterval(checkInterval)
          reject(new Error('Timeout waiting for task statuses'))
        }, 10000)
      })
    }

    loading.value.add(projectId)
    error.value = null

    try {
      const data = await customTaskStatusService.getAllStatuses(projectId)
      
      // Cache the result
      projectStatuses.value.set(projectId, {
        projectId,
        data,
        lastFetched: Date.now()
      })

      return data
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to fetch task statuses'
      console.error('Error fetching task statuses:', err)
      throw err
    } finally {
      loading.value.delete(projectId)
    }
  }

  // Invalidate cache for a project (useful after creating/updating/deleting statuses)
  function invalidateProject(projectId: number) {
    projectStatuses.value.delete(projectId)
  }

  // Clear all cached data
  function clearCache() {
    projectStatuses.value.clear()
    loading.value.clear()
    error.value = null
  }

  // Update cached statuses after a change (to avoid refetch)
  function updateProjectStatuses(projectId: number, data: AllTaskStatusesResponse) {
    projectStatuses.value.set(projectId, {
      projectId,
      data,
      lastFetched: Date.now()
    })
  }

  return {
    // State
    error,
    
    // Computed
    getProjectStatuses,
    isLoading,
    getAllStatusOptions,
    getStatusById,
    
    // Actions
    fetchProjectStatuses,
    invalidateProject,
    clearCache,
    updateProjectStatuses
  }
})