import {
  createSlice,
  createEntityAdapter,
  PayloadAction,
  createAsyncThunk,
  EntityState,
  EntityId,
} from '@reduxjs/toolkit';
import { Task, TaskManagementState, TaskGroup, TaskGrouping } from '@/types/task-management.types';
import { RootState } from '@/app/store';
import {
  tasksApiService,
  ITaskListConfigV2,
  ITaskListV3Response,
} from '@/api/tasks/tasks.api.service';
import logger from '@/utils/errorLogger';
import { DEFAULT_TASK_NAME } from '@/shared/constants';
import { InlineMember } from '@/types/teamMembers/inlineMember.types';

// Helper function to safely convert time values
const convertTimeValue = (value: any): number => {
  if (typeof value === 'number') return value;
  if (typeof value === 'string') {
    const parsed = parseFloat(value);
    return isNaN(parsed) ? 0 : parsed;
  }
  if (typeof value === 'object' && value !== null) {
    // Handle time objects like {hours: 2, minutes: 30}
    if ('hours' in value || 'minutes' in value) {
      const hours = Number(value.hours || 0);
      const minutes = Number(value.minutes || 0);
      return hours + minutes / 60;
    }
  }
  return 0;
};

export enum IGroupBy {
  STATUS = 'status',
  PRIORITY = 'priority',
  PHASE = 'phase',
  MEMBERS = 'members',
}

// Entity adapter for normalized state
const tasksAdapter = createEntityAdapter<Task>();

// Get the initial state from the adapter
const initialState: TaskManagementState = {
  ids: [],
  entities: {},
  loading: false,
  error: null,
  groups: [],
  grouping: undefined,
  selectedPriorities: [],
  search: '',
  loadingSubtasks: {},
};

// Async thunk to fetch tasks from API
export const fetchTasks = createAsyncThunk(
  'taskManagement/fetchTasks',
  async (projectId: string, { rejectWithValue, getState }) => {
    try {
      const state = getState() as RootState;
      const currentGrouping = state.grouping.currentGrouping;

      const config: ITaskListConfigV2 = {
        id: projectId,
        archived: false,
        group: currentGrouping || '',
        field: '',
        order: '',
        search: '',
        statuses: '',
        members: '',
        projects: '',
        isSubtasksInclude: false,
        labels: '',
        priorities: '',
      };

      const response = await tasksApiService.getTaskList(config);

      // Helper function to safely convert time values
      const convertTimeValue = (value: any): number => {
        if (typeof value === 'number') return value;
        if (typeof value === 'string') {
          const parsed = parseFloat(value);
          return isNaN(parsed) ? 0 : parsed;
        }
        if (typeof value === 'object' && value !== null) {
          // Handle time objects like {hours: 2, minutes: 30}
          if ('hours' in value || 'minutes' in value) {
            const hours = Number(value.hours || 0);
            const minutes = Number(value.minutes || 0);
            return hours + minutes / 60;
          }
        }
        return 0;
      };

      // Create a mapping from status IDs to group names
      const statusIdToNameMap: Record<string, string> = {};
      const priorityIdToNameMap: Record<string, string> = {};

      response.body.forEach((group: any) => {
        statusIdToNameMap[group.id] = group.name.toLowerCase();
      });

      // For priority mapping, we need to get priority names from the tasks themselves
      // Since the API doesn't provide priority names in the group structure
      response.body.forEach((group: any) => {
        group.tasks.forEach((task: any) => {
          // Map priority value to name (this is an assumption based on common patterns)
          if (task.priority_value !== undefined) {
            switch (task.priority_value) {
              case 0:
                priorityIdToNameMap[task.priority] = 'low';
                break;
              case 1:
                priorityIdToNameMap[task.priority] = 'medium';
                break;
              case 2:
                priorityIdToNameMap[task.priority] = 'high';
                break;
              case 3:
                priorityIdToNameMap[task.priority] = 'critical';
                break;
              default:
                priorityIdToNameMap[task.priority] = 'medium';
            }
          }
        });
      });

      // Transform the API response to our Task type
      const tasks: Task[] = response.body.flatMap((group: any) =>
        group.tasks.map((task: any) => ({
          id: task.id,
          task_key: task.task_key || '',
          title: (task.title && task.title.trim()) ? task.title.trim() : DEFAULT_TASK_NAME,
          description: task.description || '',
          status: statusIdToNameMap[task.status] || 'todo',
          priority: priorityIdToNameMap[task.priority] || 'medium',
          phase: task.phase_name || 'Development',
          progress: typeof task.complete_ratio === 'number' ? task.complete_ratio : 0,
          assignees: task.assignees?.map((a: any) => a.team_member_id) || [],
          assignee_names: task.assignee_names || task.names || [],
          labels:
            task.labels?.map((l: any) => ({
              id: l.id || l.label_id,
              name: l.name,
              color: l.color || '#1890ff',
              end: l.end,
              names: l.names,
            })) || [],
          dueDate: task.dueDate,
          startDate: task.startDate,
          timeTracking: {
            estimated: convertTimeValue(task.total_time),
            logged: convertTimeValue(task.time_spent),
          },
          customFields: {},
          createdAt: task.created_at || new Date().toISOString(),
          updatedAt: task.updated_at || new Date().toISOString(),
          created_at: task.created_at || new Date().toISOString(),
          updated_at: task.updated_at || new Date().toISOString(),
          order: typeof task.sort_order === 'number' ? task.sort_order : 0,
          // Ensure all Task properties are mapped, even if undefined in API response
          sub_tasks: task.sub_tasks || [],
          sub_tasks_count: task.sub_tasks_count || 0,
          show_sub_tasks: task.show_sub_tasks || false,
          parent_task_id: task.parent_task_id || undefined,
          weight: task.weight || 0,
          color: task.color || undefined,
          statusColor: task.statusColor || undefined,
          priorityColor: task.priorityColor || undefined,
          comments_count: task.comments_count || 0,
          attachments_count: task.attachments_count || 0,
          has_dependencies: task.has_dependencies || false,
          schedule_id: task.schedule_id || null,
        }))
      );

      return tasks;
    } catch (error) {
      logger.error('Fetch Tasks', error);
      if (error instanceof Error) {
        return rejectWithValue(error.message);
      }
      return rejectWithValue('Failed to fetch tasks');
    }
  }
);

// New V3 fetch that minimizes frontend processing
export const fetchTasksV3 = createAsyncThunk(
  'taskManagement/fetchTasksV3',
  async (projectId: string, { rejectWithValue, getState }) => {
    try {
      const state = getState() as RootState;
      const currentGrouping = state.grouping.currentGrouping;

      // Get selected labels from taskReducer
      const selectedLabels = state.taskReducer.labels
        .filter((l: any) => l.selected && l.id)
        .map((l: any) => l.id)
        .join(' ');

      // Get selected assignees from taskReducer
      const selectedAssignees = state.taskReducer.taskAssignees
        .filter((m: any) => m.selected && m.id)
        .map((m: any) => m.id)
        .join(' ');

      // Get selected priorities from taskReducer
      const selectedPriorities = state.taskReducer.priorities.join(' ');

      // Get search value from taskReducer
      const searchValue = state.taskReducer.search || '';

      const config: ITaskListConfigV2 = {
        id: projectId,
        archived: false,
        group: currentGrouping || '',
        field: '',
        order: '',
        search: searchValue,
        statuses: '',
        members: selectedAssignees,
        projects: '',
        isSubtasksInclude: false,
        labels: selectedLabels,
        priorities: selectedPriorities,
      };

      const response = await tasksApiService.getTaskListV3(config);



      // Ensure tasks are properly normalized
      const tasks: Task[] = response.body.allTasks.map((task: any) => {
        const now = new Date().toISOString();
        
        const transformedTask = {
          id: task.id,
          task_key: task.task_key || task.key || '',
          title: (task.title && task.title.trim()) ? task.title.trim() : DEFAULT_TASK_NAME,
          description: task.description || '',
          status: task.status || 'todo',
          priority: task.priority || 'medium',
          phase: task.phase || 'Development',
          progress: typeof task.complete_ratio === 'number' ? task.complete_ratio : 0,
          assignees: task.assignees?.map((a: { team_member_id: string }) => a.team_member_id) || [],
          assignee_names: task.assignee_names || task.names || [],
          labels: task.labels?.map((l: { id: string; label_id: string; name: string; color_code: string; end: boolean; names: string[] }) => ({
            id: l.id || l.label_id,
            name: l.name,
            color: l.color || '#1890ff',
            end: l.end,
            names: l.names,
          })) || [],
          dueDate: task.dueDate,
          startDate: task.startDate,
          timeTracking: {
            estimated: convertTimeValue(task.total_time),
            logged: convertTimeValue(task.time_spent),
          },
          customFields: {},
          createdAt: task.created_at || now,
          updatedAt: task.updated_at || now,
          created_at: task.created_at || now,
          updated_at: task.updated_at || now,
          order: typeof task.sort_order === 'number' ? task.sort_order : 0,
          sub_tasks: task.sub_tasks || [],
          sub_tasks_count: task.sub_tasks_count || 0,
          show_sub_tasks: task.show_sub_tasks || false,
          parent_task_id: task.parent_task_id || undefined,
          weight: task.weight || 0,
          color: task.color || undefined,
          statusColor: task.statusColor || undefined,
          priorityColor: task.priorityColor || undefined,
          comments_count: task.comments_count || 0,
          attachments_count: task.attachments_count || 0,
          has_dependencies: task.has_dependencies || false,
          schedule_id: task.schedule_id || null,
        };
        
        return transformedTask;
      });

      return {
        allTasks: tasks,
        groups: response.body.groups,
        grouping: response.body.grouping,
        totalTasks: response.body.totalTasks,
      };
    } catch (error) {
      logger.error('Fetch Tasks V3', error);
      if (error instanceof Error) {
        return rejectWithValue(error.message);
      }
      return rejectWithValue('Failed to fetch tasks V3');
    }
  }
);

// Refresh task progress separately to avoid slowing down initial load
export const fetchSubTasks = createAsyncThunk(
  'taskManagement/fetchSubTasks',
  async (
    { taskId, projectId }: { taskId: string; projectId: string },
    { rejectWithValue, getState }
  ) => {
    try {
      const state = getState() as RootState;
      const currentGrouping = state.grouping.currentGrouping;

      const config: ITaskListConfigV2 = {
        id: projectId,
        archived: false,
        group: currentGrouping || '',
        field: '',
        order: '',
        search: '',
        statuses: '',
        members: '',
        projects: '',
        isSubtasksInclude: false,
        labels: '',
        priorities: '',
        parent_task: taskId,
      };

      const response = await tasksApiService.getTaskListV3(config);
      return { parentTaskId: taskId, subtasks: response.body.allTasks };
    } catch (error) {
      logger.error('Fetch Sub Tasks', error);
      if (error instanceof Error) {
        return rejectWithValue(error.message);
      }
      return rejectWithValue('Failed to fetch sub tasks');
    }
  }
);

export const refreshTaskProgress = createAsyncThunk(
  'taskManagement/refreshTaskProgress',
  async (projectId: string, { rejectWithValue }) => {
    try {
      const response = await tasksApiService.refreshTaskProgress(projectId);
      return response.body;
    } catch (error) {
      logger.error('Refresh Task Progress', error);
      if (error instanceof Error) {
        return rejectWithValue(error.message);
      }
      return rejectWithValue('Failed to refresh task progress');
    }
  }
);

// Async thunk to reorder tasks with API call
export const reorderTasksWithAPI = createAsyncThunk(
  'taskManagement/reorderTasksWithAPI',
  async (
    { taskIds, newOrder, projectId }: { taskIds: string[]; newOrder: number[]; projectId: string },
    { rejectWithValue }
  ) => {
    try {
      // Make API call to update task order
      const response = await tasksApiService.reorderTasks({
        taskIds,
        newOrder,
        projectId,
      });

      if (response.done) {
        return { taskIds, newOrder };
      } else {
        return rejectWithValue('Failed to reorder tasks');
      }
    } catch (error) {
      logger.error('Reorder Tasks API Error:', error);
      return rejectWithValue('Failed to reorder tasks');
    }
  }
);

// Async thunk to move task between groups with API call
export const moveTaskToGroupWithAPI = createAsyncThunk(
  'taskManagement/moveTaskToGroupWithAPI',
  async (
    {
      taskId,
      groupType,
      groupValue,
      projectId,
    }: {
      taskId: string;
      groupType: 'status' | 'priority' | 'phase';
      groupValue: string;
      projectId: string;
    },
    { rejectWithValue }
  ) => {
    try {
      // Make API call to update task group
      const response = await tasksApiService.updateTaskGroup({
        taskId,
        groupType,
        groupValue,
        projectId,
      });

      if (response.done) {
        return { taskId, groupType, groupValue };
      } else {
        return rejectWithValue('Failed to move task');
      }
    } catch (error) {
      logger.error('Move Task API Error:', error);
      return rejectWithValue('Failed to move task');
    }
  }
);

// Add action to update task with subtasks
export const updateTaskWithSubtasks = createAsyncThunk(
  'taskManagement/updateTaskWithSubtasks',
  async ({ taskId, subtasks }: { taskId: string; subtasks: any[] }, { getState }) => {
    return { taskId, subtasks };
  }
);

// Create the slice
const taskManagementSlice = createSlice({
  name: 'taskManagement',
  initialState,
  reducers: {
    setTasks: (state, action: PayloadAction<Task[]>) => {
      const tasks = action.payload;
      state.ids = tasks.map(task => task.id);
      state.entities = tasks.reduce((acc, task) => {
        acc[task.id] = task;
        return acc;
      }, {} as Record<string, Task>);
    },
    addTask: (state, action: PayloadAction<Task>) => {
      const task = action.payload;
      state.ids.push(task.id);
      state.entities[task.id] = task;
    },
    addTaskToGroup: (state, action: PayloadAction<{ task: Task; groupId: string }>) => {
      const { task, groupId } = action.payload;
      state.ids.push(task.id);
      state.entities[task.id] = task;
      const group = state.groups.find(g => g.id === groupId);
      if (group) {
        group.taskIds.push(task.id);
      }
    },
    updateTask: (state, action: PayloadAction<Task>) => {
      tasksAdapter.upsertOne(state as EntityState<Task, string>, action.payload);
      // Additionally, update the task within its group if necessary (e.g., if status changed)
      const updatedTask = action.payload;
      const oldTask = state.entities[updatedTask.id];
  
      if (oldTask && state.grouping?.id === IGroupBy.STATUS && oldTask.status !== updatedTask.status) {
        // Remove from old status group
        const oldGroup = state.groups.find(group => group.id === oldTask.status);
        if (oldGroup) {
          oldGroup.taskIds = oldGroup.taskIds.filter(id => id !== updatedTask.id);
        }
  
        // Add to new status group
        const newGroup = state.groups.find(group => group.id === updatedTask.status);
        if (newGroup) {
          newGroup.taskIds.push(updatedTask.id);
        }
      }
    },
    deleteTask: (state, action: PayloadAction<string>) => {
      const taskId = action.payload;
      delete state.entities[taskId];
      state.ids = state.ids.filter(id => id !== taskId);
      state.groups = state.groups.map(group => ({
        ...group,
        taskIds: group.taskIds.filter(id => id !== taskId),
      }));
    },
    bulkUpdateTasks: (state, action: PayloadAction<Task[]>) => {
      action.payload.forEach(task => {
        state.entities[task.id] = task;
      });
    },
    bulkDeleteTasks: (state, action: PayloadAction<string[]>) => {
      const taskIds = action.payload;
      taskIds.forEach(taskId => {
        delete state.entities[taskId];
      });
      state.ids = state.ids.filter(id => !taskIds.includes(id));
      state.groups = state.groups.map(group => ({
        ...group,
        taskIds: group.taskIds.filter(id => !taskIds.includes(id)),
      }));
    },
    reorderTasks: (state, action: PayloadAction<{ taskIds: string[]; groupId: string }>) => {
      const { taskIds, groupId } = action.payload;
      const group = state.groups.find(g => g.id === groupId);
      if (group) {
        group.taskIds = taskIds;
      }
    },
    moveTaskToGroup: (state, action: PayloadAction<{ taskId: string; groupId: string }>) => {
      const { taskId, groupId } = action.payload;
      state.groups = state.groups.map(group => ({
        ...group,
        taskIds:
          group.id === groupId
            ? [...group.taskIds, taskId]
            : group.taskIds.filter(id => id !== taskId),
      }));
    },
    moveTaskBetweenGroups: (
      state,
      action: PayloadAction<{
        taskId: string;
        sourceGroupId: string;
        targetGroupId: string;
      }>
    ) => {
      const { taskId, sourceGroupId, targetGroupId } = action.payload;
      state.groups = state.groups.map(group => ({
        ...group,
        taskIds:
          group.id === targetGroupId
            ? [...group.taskIds, taskId]
            : group.id === sourceGroupId
            ? group.taskIds.filter(id => id !== taskId)
            : group.taskIds,
      }));
    },
    optimisticTaskMove: (
      state,
      action: PayloadAction<{
        taskId: string;
        sourceGroupId: string;
        targetGroupId: string;
      }>
    ) => {
      const { taskId, sourceGroupId, targetGroupId } = action.payload;
      state.groups = state.groups.map(group => ({
        ...group,
        taskIds:
          group.id === targetGroupId
            ? [...group.taskIds, taskId]
            : group.id === sourceGroupId
            ? group.taskIds.filter(id => id !== taskId)
            : group.taskIds,
      }));
    },
    reorderTasksInGroup: (
      state,
      action: PayloadAction<{
        sourceTaskId: string;
        destinationTaskId: string;
        sourceGroupId: string;
        destinationGroupId: string;
      }>
    ) => {
      const { sourceTaskId, destinationTaskId, sourceGroupId, destinationGroupId } = action.payload;
  
      // Get a mutable copy of entities for updates
      const newEntities = { ...state.entities };
  
      const sourceTask = newEntities[sourceTaskId];
      const destinationTask = newEntities[destinationTaskId];
  
      if (!sourceTask || !destinationTask) return;
  
      if (sourceGroupId === destinationGroupId) {
        // Reordering within the same group
        const group = state.groups.find(g => g.id === sourceGroupId);
        if (group) {
          const newTasks = Array.from(group.taskIds);
          const [removed] = newTasks.splice(newTasks.indexOf(sourceTaskId), 1);
          newTasks.splice(newTasks.indexOf(destinationTaskId), 0, removed);
          group.taskIds = newTasks;
  
          // Update order for affected tasks. Assuming simple reordering affects order.
          // This might need more sophisticated logic based on how `order` is used.
          newTasks.forEach((id, index) => {
            if (newEntities[id]) {
              newEntities[id] = { ...newEntities[id], order: index };
            }
          });
        }
      } else {
        // Moving between different groups
        const sourceGroup = state.groups.find(g => g.id === sourceGroupId);
        const destinationGroup = state.groups.find(g => g.id === destinationGroupId);
  
        if (sourceGroup && destinationGroup) {
          // Remove from source group
          sourceGroup.taskIds = sourceGroup.taskIds.filter(id => id !== sourceTaskId);
  
          // Add to destination group at the correct position relative to destinationTask
          const destinationIndex = destinationGroup.taskIds.indexOf(destinationTaskId);
          if (destinationIndex !== -1) {
            destinationGroup.taskIds.splice(destinationIndex, 0, sourceTaskId);
          } else {
            destinationGroup.taskIds.push(sourceTaskId); // Add to end if destination task not found
          }
  
          // Update task's grouping field to reflect new group (e.g., status, priority, phase)
          // This assumes the group ID directly corresponds to the task's field value
          if (sourceTask) {
            let updatedTask = { ...sourceTask };
            switch (state.grouping?.id) {
              case IGroupBy.STATUS:
                updatedTask.status = destinationGroup.id;
                break;
              case IGroupBy.PRIORITY:
                updatedTask.priority = destinationGroup.id;
                break;
              case IGroupBy.PHASE:
                updatedTask.phase = destinationGroup.id;
                break;
              case IGroupBy.MEMBERS:
                // If moving to a member group, ensure task is assigned to that member
                // This assumes the group ID is the member ID
                if (!updatedTask.assignees) {
                  updatedTask.assignees = [];
                }
                if (!updatedTask.assignees.includes(destinationGroup.id)) {
                  updatedTask.assignees.push(destinationGroup.id);
                }
                // If moving from a member group, and the task is no longer in any member group,
                // consider removing the assignment (more complex logic might be needed here)
                break;
              default:
                break;
            }
            newEntities[sourceTaskId] = updatedTask;
          }
  
          // Update order for affected tasks in both groups if necessary
          sourceGroup.taskIds.forEach((id, index) => {
            if (newEntities[id]) newEntities[id] = { ...newEntities[id], order: index };
          });
          destinationGroup.taskIds.forEach((id, index) => {
            if (newEntities[id]) newEntities[id] = { ...newEntities[id], order: index };
          });
        }
      }
  
      // Update the state's entities after all modifications
      state.entities = newEntities;
    },
    setLoading: (state, action: PayloadAction<boolean>) => {
      state.loading = action.payload;
    },
    setError: (state, action: PayloadAction<string | null>) => {
      state.error = action.payload;
    },
    setSelectedPriorities: (state, action: PayloadAction<string[]>) => {
      state.selectedPriorities = action.payload;
    },
    setSearch: (state, action: PayloadAction<string>) => {
      state.search = action.payload;
    },
    resetTaskManagement: state => {
      state.loading = false;
      state.error = null;
      state.groups = [];
      state.grouping = undefined;
      state.selectedPriorities = [];
      state.search = '';
      state.ids = [];
      state.entities = {};
    },
    toggleTaskExpansion: (state, action: PayloadAction<string>) => {
      const task = state.entities[action.payload];
      if (task) {
        task.show_sub_tasks = !task.show_sub_tasks;
      }
    },
    addSubtaskToParent: (
      state,
      action: PayloadAction<{ parentId: string; subtask: Task }>
    ) => {
      const { parentId, subtask } = action.payload;
      const parent = state.entities[parentId];
      if (parent) {
        state.ids.push(subtask.id);
        state.entities[subtask.id] = subtask;
        if (!parent.sub_tasks) {
          parent.sub_tasks = [];
        }
        parent.sub_tasks.push(subtask);
        parent.sub_tasks_count = (parent.sub_tasks_count || 0) + 1;
      }
    },
    createSubtask: (
      state,
      action: PayloadAction<{ parentTaskId: string; name: string; projectId: string }>
    ) => {
      const { parentTaskId, name, projectId } = action.payload;
      const parent = state.entities[parentTaskId];
      if (parent) {
        // Create a temporary subtask - the real one will come from the socket
        const tempId = `temp-${Date.now()}`;
        const tempSubtask: Task = {
          id: tempId,
          task_key: '',
          title: name,
          name: name,
          description: '',
          status: 'todo',
          priority: 'low',
          phase: 'Development',
          progress: 0,
          assignees: [],
          assignee_names: [],
          labels: [],
          dueDate: undefined,
          due_date: undefined,
          startDate: undefined,
          timeTracking: {
            estimated: 0,
            logged: 0,
          },
          created_at: new Date().toISOString(),
          updated_at: new Date().toISOString(),
          order: 0,
          parent_task_id: parentTaskId,
          is_sub_task: true,
          sub_tasks_count: 0,
          show_sub_tasks: false,
          isTemporary: true, // Mark as temporary
        };
        
        // Add temporary subtask for immediate UI feedback
        if (!parent.sub_tasks) {
          parent.sub_tasks = [];
        }
        parent.sub_tasks.push(tempSubtask);
        parent.sub_tasks_count = (parent.sub_tasks_count || 0) + 1;
        state.entities[tempId] = tempSubtask;
        state.ids.push(tempId);
      }
    },
    removeTemporarySubtask: (
      state,
      action: PayloadAction<{ parentTaskId: string; tempId: string }>
    ) => {
      const { parentTaskId, tempId } = action.payload;
      const parent = state.entities[parentTaskId];
      if (parent && parent.sub_tasks) {
        parent.sub_tasks = parent.sub_tasks.filter(subtask => subtask.id !== tempId);
        parent.sub_tasks_count = Math.max((parent.sub_tasks_count || 0) - 1, 0);
        delete state.entities[tempId];
        state.ids = state.ids.filter(id => id !== tempId);
      }
    },
    updateTaskAssignees: (state, action: PayloadAction<{
      taskId: string;
      assigneeIds: string[];
      assigneeNames: InlineMember[];
    }>) => {
      const { taskId, assigneeIds, assigneeNames } = action.payload;
      const existingTask = state.entities[taskId];
  
      if (existingTask) {
        state.entities[taskId] = {
          ...existingTask,
          assignees: assigneeIds,
          assignee_names: assigneeNames,
        };
      }
    },
    
  },
  extraReducers: builder => {
    builder
      .addCase(fetchTasksV3.pending, state => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchTasksV3.fulfilled, (state, action) => {
        state.loading = false;
        const { allTasks, groups, grouping } = action.payload;
        tasksAdapter.setAll(state as EntityState<Task, string>, allTasks || []); // Ensure allTasks is an array
        state.ids = (allTasks || []).map(task => task.id); // Also update ids
        state.groups = groups;
        state.grouping = grouping;
      })
      .addCase(fetchTasksV3.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error?.message || (action.payload as string) || 'Failed to load tasks (V3)';
        state.ids = [];
        state.entities = {};
        state.groups = [];
      })
      .addCase(fetchSubTasks.pending, (state, action) => {
        // Set loading state for specific task
        const { taskId } = action.meta.arg;
        state.loadingSubtasks[taskId] = true;
        state.error = null;
      })
      .addCase(fetchSubTasks.fulfilled, (state, action) => {
        const { parentTaskId, subtasks } = action.payload;
        const parentTask = state.entities[parentTaskId];
        // Clear loading state
        state.loadingSubtasks[parentTaskId] = false;
        if (parentTask && subtasks) {
          // Convert subtasks to the proper format
          const convertedSubtasks = subtasks.map(subtask => ({
            id: subtask.id || '',
            task_key: subtask.task_key || '',
            title: subtask.name || subtask.title || '',
            name: subtask.name || subtask.title || '',
            description: subtask.description || '',
            status: subtask.status || 'todo',
            priority: subtask.priority || 'low',
            phase: subtask.phase_name || subtask.phase || 'Development',
            progress: subtask.complete_ratio || subtask.progress || 0,
            assignees: subtask.assignees || [],
            assignee_names: subtask.assignee_names || subtask.names || [],
            labels: subtask.labels || [],
            dueDate: subtask.end_date || subtask.dueDate,
            due_date: subtask.end_date || subtask.due_date,
            startDate: subtask.start_date || subtask.startDate,
            timeTracking: subtask.timeTracking || {
              estimated: 0,
              logged: 0,
            },
            createdAt: subtask.created_at || subtask.createdAt || new Date().toISOString(),
            created_at: subtask.created_at || subtask.createdAt || new Date().toISOString(),
            updatedAt: subtask.updated_at || subtask.updatedAt || new Date().toISOString(),
            updated_at: subtask.updated_at || subtask.updatedAt || new Date().toISOString(),
            order: subtask.sort_order || subtask.order || 0,
            parent_task_id: parentTaskId,
            is_sub_task: true,
            sub_tasks_count: 0,
            show_sub_tasks: false,
          }));

          // Update parent task with subtasks
          parentTask.sub_tasks = convertedSubtasks;
          parentTask.sub_tasks_count = convertedSubtasks.length;
          
          // Add subtasks to entities so they can be accessed by ID
          convertedSubtasks.forEach(subtask => {
            state.entities[subtask.id] = subtask;
            if (!state.ids.includes(subtask.id)) {
              state.ids.push(subtask.id);
            }
          });
        }
      })
      .addCase(fetchSubTasks.rejected, (state, action) => {
        // Clear loading state and set error
        const { taskId } = action.meta.arg;
        state.loadingSubtasks[taskId] = false;
        state.error = action.error.message || action.payload || 'Failed to fetch subtasks. Please try again.';
      })
      .addCase(fetchTasks.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchTasks.fulfilled, (state, action) => {
        state.loading = false;
        tasksAdapter.setAll(state as EntityState<Task, string>, action.payload || []); // Ensure payload is an array
        state.ids = (action.payload || []).map(task => task.id); // Also update ids
        state.groups = []; // Assuming no groups when using old fetchTasks
        state.grouping = undefined; // Assuming no grouping when using old fetchTasks
      })
      .addCase(fetchTasks.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error?.message || (action.payload as string) || 'Failed to load tasks';
        state.ids = [];
        state.entities = {};
        state.groups = [];
      });
  },
});

// Export the slice reducer and actions
export const {
  setTasks,
  addTask,
  addTaskToGroup,
  updateTask,
  deleteTask,
  bulkUpdateTasks,
  bulkDeleteTasks,
  reorderTasks,
  moveTaskToGroup,
  moveTaskBetweenGroups,
  optimisticTaskMove,
  reorderTasksInGroup,
  setLoading,
  setError,
  setSelectedPriorities,
  setSearch,
  resetTaskManagement,
  toggleTaskExpansion,
  addSubtaskToParent,
  updateTaskAssignees,
  createSubtask,
  removeTemporarySubtask,
} = taskManagementSlice.actions;

// Export the selectors
export const selectAllTasks = (state: RootState) => state.taskManagement.entities;
export const selectAllTasksArray = (state: RootState) => Object.values(state.taskManagement.entities);
export const selectTaskById = (state: RootState, taskId: string) => state.taskManagement.entities[taskId];
export const selectTaskIds = (state: RootState) => state.taskManagement.ids;
export const selectGroups = (state: RootState) => state.taskManagement.groups;
export const selectGrouping = (state: RootState) => state.taskManagement.grouping;
export const selectLoading = (state: RootState) => state.taskManagement.loading;
export const selectError = (state: RootState) => state.taskManagement.error;
export const selectSelectedPriorities = (state: RootState) => state.taskManagement.selectedPriorities;
export const selectSearch = (state: RootState) => state.taskManagement.search;
export const selectSubtaskLoading = (state: RootState, taskId: string) => state.taskManagement.loadingSubtasks[taskId] || false;

// Memoized selectors
export const selectTasksByStatus = (state: RootState, status: string) =>
  Object.values(state.taskManagement.entities).filter(task => task.status === status);

export const selectTasksByPriority = (state: RootState, priority: string) =>
  Object.values(state.taskManagement.entities).filter(task => task.priority === priority);

export const selectTasksByPhase = (state: RootState, phase: string) =>
  Object.values(state.taskManagement.entities).filter(task => task.phase === phase);

// Export the reducer as default
export default taskManagementSlice.reducer;

// V3 API selectors - no processing needed, data is pre-processed by backend
export const selectTaskGroupsV3 = (state: RootState) => state.taskManagement.groups;
export const selectCurrentGroupingV3 = (state: RootState) => state.taskManagement.grouping;
