import { createSlice, PayloadAction, createSelector } from '@reduxjs/toolkit';
import { TaskGroup } from '@/types/task-management.types';
import { RootState } from '@/app/store';
import { selectAllTasksArray } from './task-management.slice';

type GroupingType = 'status' | 'priority' | 'phase';

interface LocalGroupingState {
  currentGrouping: GroupingType | null;
  customPhases: string[];
  groupOrder: {
    status: string[];
    priority: string[];
    phase: string[];
  };
  groupStates: Record<string, { collapsed: boolean }>;
  collapsedGroups: string[];
}

const initialState: LocalGroupingState = {
  currentGrouping: null,
  customPhases: ['Planning', 'Development', 'Testing', 'Deployment'],
  groupOrder: {
    status: ['todo', 'doing', 'done'],
    priority: ['critical', 'high', 'medium', 'low'],
    phase: ['Planning', 'Development', 'Testing', 'Deployment'],
  },
  groupStates: {},
  collapsedGroups: [],
};

const groupingSlice = createSlice({
  name: 'grouping',
  initialState,
  reducers: {
    setCurrentGrouping: (state, action: PayloadAction<GroupingType | null>) => {
      state.currentGrouping = action.payload;
    },

    addCustomPhase: (state, action: PayloadAction<string>) => {
      const phase = action.payload.trim();
      if (phase && !state.customPhases.includes(phase)) {
        state.customPhases.push(phase);
        state.groupOrder.phase.push(phase);
      }
    },

    removeCustomPhase: (state, action: PayloadAction<string>) => {
      const phase = action.payload;
      state.customPhases = state.customPhases.filter(p => p !== phase);
      state.groupOrder.phase = state.groupOrder.phase.filter(p => p !== phase);
    },

    updateCustomPhases: (state, action: PayloadAction<string[]>) => {
      state.customPhases = action.payload;
      state.groupOrder.phase = action.payload;
    },

    updateGroupOrder: (state, action: PayloadAction<{ groupType: keyof LocalGroupingState['groupOrder']; order: string[] }>) => {
      const { groupType, order } = action.payload;
      state.groupOrder[groupType] = order;
    },

    toggleGroupCollapsed: (state, action: PayloadAction<string>) => {
      const groupId = action.payload;
      const isCollapsed = state.collapsedGroups.includes(groupId);
      if (isCollapsed) {
        state.collapsedGroups = state.collapsedGroups.filter(id => id !== groupId);
      } else {
        state.collapsedGroups.push(groupId);
      }
    },

    setGroupCollapsed: (state, action: PayloadAction<{ groupId: string; collapsed: boolean }>) => {
      const { groupId, collapsed } = action.payload;
      if (!state.groupStates[groupId]) {
        state.groupStates[groupId] = { collapsed: false };
      }
      state.groupStates[groupId].collapsed = collapsed;
    },

    collapseAllGroups: (state, action: PayloadAction<string[]>) => {
      state.collapsedGroups = action.payload;
    },

    expandAllGroups: state => {
      state.collapsedGroups = [];
    },

    resetGrouping: () => initialState,
  },
});

export const {
  setCurrentGrouping,
  addCustomPhase,
  removeCustomPhase,
  updateCustomPhases,
  updateGroupOrder,
  toggleGroupCollapsed,
  setGroupCollapsed,
  collapseAllGroups,
  expandAllGroups,
  resetGrouping,
} = groupingSlice.actions;

// Selectors
export const selectCurrentGrouping = (state: RootState) => state.grouping.currentGrouping;
export const selectCustomPhases = (state: RootState) => state.grouping.customPhases;
export const selectGroupOrder = (state: RootState) => state.grouping.groupOrder;
export const selectGroupStates = (state: RootState) => state.grouping.groupStates;
export const selectCollapsedGroups = (state: RootState) => new Set(state.grouping.collapsedGroups);
export const selectIsGroupCollapsed = (state: RootState, groupId: string) =>
  state.grouping.collapsedGroups.includes(groupId);

// Complex selectors using createSelector for memoization
export const selectCurrentGroupOrder = createSelector(
  [selectCurrentGrouping, selectGroupOrder],
  (currentGrouping, groupOrder) => {
    if (!currentGrouping) return [];
    return groupOrder[currentGrouping] || [];
  }
);

export const selectTaskGroups = createSelector(
  [selectAllTasksArray, selectCurrentGrouping, selectCurrentGroupOrder, selectGroupStates],
  (tasks, currentGrouping, groupOrder, groupStates) => {
    const groups: TaskGroup[] = [];

    if (!currentGrouping) return groups;

    // Get unique values for the current grouping
    const groupValues =
      groupOrder.length > 0
        ? groupOrder
        : Array.from(new Set(
            tasks.map(task => {
              if (currentGrouping === 'status') return task.status;
              if (currentGrouping === 'priority') return task.priority;
              return task.phase;
            })
          ));

    groupValues.forEach(value => {
      if (!value) return; // Skip undefined values
      
      const tasksInGroup = tasks
        .filter(task => {
          if (currentGrouping === 'status') return task.status === value;
          if (currentGrouping === 'priority') return task.priority === value;
          return task.phase === value;
        })
        .sort((a, b) => (a.order || 0) - (b.order || 0));

      const groupId = `${currentGrouping}-${value}`;

      groups.push({
        id: groupId,
        title: value.charAt(0).toUpperCase() + value.slice(1),
        taskIds: tasksInGroup.map(task => task.id),
        type: currentGrouping,
        color: getGroupColor(currentGrouping, value),
        collapsed: groupStates[groupId]?.collapsed || false,
        groupValue: value,
      });
    });

    return groups;
  }
);

export const selectTasksByCurrentGrouping = createSelector(
  [selectAllTasksArray, selectCurrentGrouping],
  (tasks, currentGrouping) => {
    const grouped: Record<string, typeof tasks> = {};

    if (!currentGrouping) return grouped;

    tasks.forEach(task => {
      let key: string;
      if (currentGrouping === 'status') key = task.status;
      else if (currentGrouping === 'priority') key = task.priority;
      else key = task.phase || 'Development';

      if (!grouped[key]) grouped[key] = [];
      grouped[key].push(task);
    });

    // Sort tasks within each group by order
    Object.keys(grouped).forEach(key => {
      grouped[key].sort((a, b) => (a.order || 0) - (b.order || 0));
    });

    return grouped;
  }
);

// Helper function to get group colors
const getGroupColor = (groupType: GroupingType, value: string): string => {
  const colorMaps = {
    status: {
      todo: '#f0f0f0',
      doing: '#1890ff',
      done: '#52c41a',
    },
    priority: {
      critical: '#ff4d4f',
      high: '#ff7a45',
      medium: '#faad14',
      low: '#52c41a',
    },
    phase: {
      Planning: '#722ed1',
      Development: '#1890ff',
      Testing: '#faad14',
      Deployment: '#52c41a',
    },
  };

  const colorMap = colorMaps[groupType];
  return (colorMap as any)?.[value] || '#d9d9d9';
};

export default groupingSlice.reducer;
