import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { taskService, type Task, type TaskListItem } from '@/services/task'
import { shotService, type Shot } from '@/services/shot'
import { assetService, type Asset } from '@/services/asset'

export const useTasksStore = defineStore('tasks', () => {
  const tasks = ref<TaskListItem[]>([])
  const loading = ref(false)
  const error = ref<string | null>(null)
  const selectedTask = ref<Task | null>(null)

  // Computed properties maintain existing store interface
  const myTasks = computed(() => {
    // This will be filtered by the backend based on user role
    return tasks.value
  })

  const tasksByStatus = computed(() => {
    return tasks.value.reduce((acc, task) => {
      if (!acc[task.status]) {
        acc[task.status] = []
      }
      acc[task.status].push(task)
      return acc
    }, {} as Record<string, TaskListItem[]>)
  })

  const overdueTasks = computed(() => {
    const now = new Date()
    return tasks.value.filter(task => {
      if (!task.deadline) return false
      const deadline = new Date(task.deadline)
      return deadline < now && task.status !== 'approved'
    })
  })

  /**
   * Optimized task fetching using embedded task data from shots/assets.
   * This eliminates separate API calls for task data by using the task_details
   * already included in shot and asset responses from the optimized backend.
   * 
   * Requirements: 1.2, 2.2, 4.4
   */
  async function fetchTasks(filters?: {
    projectId?: number
    assignedUserId?: number
    status?: string
    taskType?: string
  }) {
    loading.value = true
    error.value = null
    try {
      // Always use optimized approach when projectId is available
      if (filters?.projectId) {
        // Use optimized approach: get both shots and assets with embedded task data
        const [shots, assets] = await Promise.all([
          shotService.getShotsByProject(filters.projectId),
          assetService.getAssets(filters.projectId)
        ])

        // Extract tasks from embedded data in shots and assets
        const shotTasks = extractTasksFromShots(shots)
        const assetTasks = extractTasksFromAssets(assets)
        
        // Combine all tasks
        let allTasks = [...shotTasks, ...assetTasks]

        // Apply additional filters if provided
        if (filters.assignedUserId) {
          allTasks = allTasks.filter(task => task.assigned_user_id === filters.assignedUserId)
        }
        if (filters.status) {
          allTasks = allTasks.filter(task => task.status === filters.status)
        }
        if (filters.taskType) {
          allTasks = allTasks.filter(task => task.task_type === filters.taskType)
        }

        tasks.value = allTasks
      } else {
        // Fallback to original task service only when no projectId is provided
        // This maintains backward compatibility for legacy usage
        const response = await taskService.getTasks(filters)
        tasks.value = response
      }
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to fetch tasks'
      console.error('Error fetching tasks:', err)
    } finally {
      loading.value = false
    }
  }

  function extractTasksFromShots(shots: Shot[]): TaskListItem[] {
    const tasks: TaskListItem[] = []
    
    for (const shot of shots) {
      // Skip shots without task details
      if (!shot.task_details || shot.task_details.length === 0) {
        continue
      }
      
      for (const taskDetail of shot.task_details) {
        // Ensure we have valid task data
        if (!taskDetail.task_type || !taskDetail.status) {
          continue
        }
        
        tasks.push({
          id: taskDetail.task_id || 0,
          name: `${shot.name} - ${formatTaskType(taskDetail.task_type)}`,
          task_type: taskDetail.task_type,
          status: taskDetail.status,
          project_id: shot.project_id,
          project_name: shot.project_name || '',
          episode_id: shot.episode_id,
          shot_id: shot.id,
          shot_name: shot.name,
          assigned_user_id: taskDetail.assigned_user_id,
          created_at: shot.created_at,
          updated_at: shot.updated_at
        })
      }
    }
    
    return tasks
  }

  function extractTasksFromAssets(assets: Asset[]): TaskListItem[] {
    const tasks: TaskListItem[] = []
    
    for (const asset of assets) {
      // Skip assets without task details
      if (!asset.task_details || asset.task_details.length === 0) {
        continue
      }
      
      for (const taskDetail of asset.task_details) {
        // Ensure we have valid task data
        if (!taskDetail.task_type || !taskDetail.status) {
          continue
        }
        
        tasks.push({
          id: taskDetail.task_id || 0,
          name: `${asset.name} - ${formatTaskType(taskDetail.task_type)}`,
          task_type: taskDetail.task_type,
          status: taskDetail.status,
          project_id: asset.project_id,
          project_name: '', // Asset service doesn't include project name
          asset_id: asset.id,
          asset_name: asset.name,
          assigned_user_id: taskDetail.assigned_user_id,
          created_at: asset.created_at,
          updated_at: asset.updated_at
        })
      }
    }
    
    return tasks
  }

  function formatTaskType(taskType: string): string {
    return taskType.charAt(0).toUpperCase() + taskType.slice(1).replace('_', ' ')
  }

  async function fetchTask(taskId: number) {
    loading.value = true
    error.value = null
    try {
      const task = await taskService.getTask(taskId)
      selectedTask.value = task
      
      // Update in tasks array if exists
      const index = tasks.value.findIndex(t => t.id === taskId)
      if (index !== -1) {
        // Convert Task to TaskListItem for consistency
        const taskListItem: TaskListItem = {
          id: task.id,
          name: task.name,
          task_type: task.task_type,
          status: task.status,
          deadline: task.deadline,
          project_id: task.project_id,
          project_name: task.project_name || '',
          episode_id: task.episode_id,
          episode_name: task.episode_name,
          shot_id: task.shot_id,
          shot_name: task.shot_name,
          asset_id: task.asset_id,
          asset_name: task.asset_name,
          assigned_user_id: task.assigned_user_id,
          assigned_user_name: task.assigned_user_name,
          created_at: task.created_at,
          updated_at: task.updated_at
        }
        tasks.value[index] = taskListItem
      } else {
        // Add to tasks array as TaskListItem
        const taskListItem: TaskListItem = {
          id: task.id,
          name: task.name,
          task_type: task.task_type,
          status: task.status,
          deadline: task.deadline,
          project_id: task.project_id,
          project_name: task.project_name || '',
          episode_id: task.episode_id,
          episode_name: task.episode_name,
          shot_id: task.shot_id,
          shot_name: task.shot_name,
          asset_id: task.asset_id,
          asset_name: task.asset_name,
          assigned_user_id: task.assigned_user_id,
          assigned_user_name: task.assigned_user_name,
          created_at: task.created_at,
          updated_at: task.updated_at
        }
        tasks.value.push(taskListItem)
      }
      
      return task
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to fetch task'
      console.error('Error fetching task:', err)
      throw err
    } finally {
      loading.value = false
    }
  }

  async function updateTaskStatus(taskId: number, status: string) {
    try {
      const updatedTask = await taskService.updateTaskStatus(taskId, status as any)
      
      // Update in tasks array
      const index = tasks.value.findIndex(t => t.id === taskId)
      if (index !== -1) {
        // Update the status in the TaskListItem
        tasks.value[index] = {
          ...tasks.value[index],
          status: updatedTask.status,
          updated_at: updatedTask.updated_at
        }
      }
      
      // Update selected task if it's the same
      if (selectedTask.value?.id === taskId) {
        selectedTask.value = updatedTask
      }
      
      return updatedTask
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to update task status'
      console.error('Error updating task status:', err)
      throw err
    }
  }

  function selectTask(task: Task | null) {
    selectedTask.value = task
  }

  function clearTasks() {
    tasks.value = []
    selectedTask.value = null
  }

  return {
    tasks,
    loading,
    error,
    selectedTask,
    myTasks,
    tasksByStatus,
    overdueTasks,
    fetchTasks,
    fetchTask,
    updateTaskStatus,
    selectTask,
    clearTasks
  }
})
