// resources\assets\ts\ContactsPage\contactAufgabenSlice.ts

import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
import axios from 'axios';
// import { TableDataType } from '../DataPage/tableSlice';
import { TableDataType } from '../share/aufgaben-shared/types/TableDataType';

// ==========================================
// FETCH ACTIONS
// ==========================================

/**
 * Fetch tasks/aufgaben for a contact
 */
export const fetchContactAufgaben = createAsyncThunk(
  'contactAufgaben/fetch',
  async (adrId: number) => {
    const response = await axios.get(`/contacts/${adrId}/aufgabe`);
    return response.data;
  }
);

/**
 * Toggle read status for a task
 */
export const toggleContactRead = createAsyncThunk(
  'contactAufgaben/toggleRead',
  async (ergId: number) => {

    const response = await axios.get(`/c/${ergId}/readLog`);
    return response.data;
  }
);

/**
 * Mark task as read
 */
export const markContactAsRead = createAsyncThunk(
  'contactAufgaben/markAsRead',
  async (ergId: number) => {
    const response = await axios.post(`/c/${ergId}/read`);
    return response.data;
  }
);

/**
 * Fetch all CMS tasks created by the current user (for "Meine Aufgaben")
 */
export const fetchMeineAufgaben = createAsyncThunk(
  'contactAufgaben/fetchMeineAufgaben',
  async () => {
    const response = await axios.get('/contacts/meine-aufgaben');
    return response.data;
  }
);

// ==========================================
// TASK COMPLETION ACTIONS
// ==========================================

/**
 * Mark task as done (Quittieren/Quit)
 */
export const quitContactTask = createAsyncThunk(
  'contactAufgaben/quit',
  async (ergId: number) => {
    const response = await axios.post(`/ProceedTask/doAction`, {
      ergid: ergId,
      action: 'quit'
    });
    return { ergId, ...response.data };
  }
);

/**
 * Complete task and move to next (with form)
 * Note: This mainly marks as read, actual form is opened via popup
 */
export const nextContactTaskWithForm = createAsyncThunk(
  'contactAufgaben/nextWithForm',
  async ({ ergId, agbId }: { ergId: number; agbId: number }) => {
    const response = await axios.post(`/ProceedTask/doAction`, {
      ergid: ergId,
      agbid: agbId,  // ✅ Need the dynamic task ID
      action: 'next'
    });
    return { ergId, agbId, ...response.data };
  }
);

/**
 * Complete task and move to next (without form)
 */
export const nextContactTaskWithoutForm = createAsyncThunk(
  'contactAufgaben/nextWithoutForm',
  async (ergId: number) => {
    const response = await axios.post(`/ProceedTask/doAction`, {
      ergid: ergId,
      action: 'auto_next'  // ✅ Changed from 'nextwithoutaction' to 'auto_next'
    });
    return { ergId, ...response.data };
  }
);


/**
 * Recover (reactivate) a completed task
 */
export const recoverContactTask = createAsyncThunk(
  'contactAufgaben/recover',
  async (ergId: number) => {
    const response = await axios.post(`/ProceedTask/doAction`, {
      ergid: ergId,
      action: 'recover'
    });
    return { ergId, ...response.data };
  }
);
// ==========================================
// TASK MANAGEMENT ACTIONS
// ==========================================


/**
 * Delete a task
 * Controller: CommissionController.php
 */
export const deleteContactTask = createAsyncThunk(
  'contactAufgaben/delete',
  async (ergId: number) => {
    const response = await axios.post(`/ProceedTask/doAction`, {
      ergid: ergId,
      action: 'delete'
    });
    return { ergId, ...response.data };
  }
);

/**
 * Move task to different date
 * Controller: CommissionController.php
 */
export const moveContactTask = createAsyncThunk(
  'contactAufgaben/move',
  async ({ ergId, newDate }: { ergId: number; newDate: string }) => {
    const response = await axios.post(`/ProceedTask/doAction`, {
      ergid: ergId,
      action: 'move',
      datum: newDate  // ✅ Controller expects 'datum' parameter
    });
    return { ergId, newDate, ...response.data };
  }
);

/**
 * Clone/duplicate a task
 */
export const cloneContactTask = createAsyncThunk(
  'contactAufgaben/clone',
  async ({ ergId, cloneIds }: { ergId: number; cloneIds: string }) => {
    const response = await axios.post(`/ProceedTask/doAction`, {
      ergid: ergId,
      action: 'clone',
      cloneid: cloneIds  // ✅ Comma-separated IDs like "123,456,789"
    });
    return { ergId, ...response.data };
  }
);



// ==========================================
// DIALOG/MODAL DATA FETCHING
// ==========================================

/**
 * Fetch emails, history and clones are not used here, 
 * using data page's fetchEmails, fetchHistory and fetchClones
 */

// ==========================================
// TAG MANAGEMENT
// ==========================================

/**
 * Add tag to task
 */
export const addContactTaskTag = createAsyncThunk(
  'contactAufgaben/addTag',
  async ({ ergLngId, tag }: { ergLngId: string; tag: string }) => {
    const response = await axios.post(`/c/tags/add`, {
      erg_lngid: ergLngId,
      tag: tag,
    });
    return { ergLngId, tag, ...response.data };
  }
);

/**
 * Remove tag from task
 */
export const removeContactTaskTag = createAsyncThunk(
  'contactAufgaben/removeTag',
  async ({ ergLngId, tag }: { ergLngId: string; tag: string }) => {
    const response = await axios.post(`/c/tags/remove`, {
      erg_lngid: ergLngId,
      tag: tag,
    });
    return { ergLngId, tag, ...response.data };
  }
);




// ==========================================
// PDF GENERATION (No async needed - just opens window)
// ==========================================
// Note: PDF opening is handled client-side via window.open()
// No Redux action needed

// ==========================================
// STATE INTERFACE
// ==========================================

interface DialogState {
  emails: any[];
  history: any[];
  clones: any[];
  isOpen: boolean;
  taskId: number | null;
}

interface State {
  aufgaben: TableDataType[];
  groups: Record<number, { path: string[] }>;
  isLoading: boolean;
  error: string | null;

  //track which tasks are read
  readLogs: Record<number, number[]>;

  // Filter state
  filters: {
    searchString: string;
    selectedTags: string[];
    selectedStatus: number | 'none';
  };

  // Dialog states
  emailDialog: DialogState;
  historyDialog: DialogState;
  cloneDialog: DialogState;
  deleteConfirmDialog: { isOpen: boolean; taskId: number | null };
  moveTaskDialog: { isOpen: boolean; taskId: number | null };
  quitConfirmDialog: { isOpen: boolean; taskId: number | null };

  // Action tracking
  pendingActions: Record<number, string>; // { ergId: 'quitting' | 'recovering' | 'deleting' }

  // Tags by task
  taskTags: Record<string, string[]>; // { erg_lngid: ['tag1', 'tag2'] }
}

const initialDialogState: DialogState = {
  emails: [],
  history: [],
  clones: [],
  isOpen: false,
  taskId: null,
};

const initialState: State = {
  aufgaben: [],
  groups: {},
  isLoading: false,
  error: null,

  readLogs: {},

  filters: {
    searchString: '',
    selectedTags: [],
    selectedStatus: 'none',
  },

  emailDialog: initialDialogState,
  historyDialog: initialDialogState,
  cloneDialog: initialDialogState,
  deleteConfirmDialog: { isOpen: false, taskId: null },
  moveTaskDialog: { isOpen: false, taskId: null },
  quitConfirmDialog: { isOpen: false, taskId: null },

  pendingActions: {},
  taskTags: {},
};

// ==========================================
// SLICE
// ==========================================

const contactAufgabenSlice = createSlice({
  name: 'contactAufgaben',
  initialState,
  reducers: {
    clearContactAufgaben(state) {
      state.aufgaben = [];
    },

    // Filter actions
    setSearchString(state, action: PayloadAction<string>) {
      state.filters.searchString = action.payload;
    },

    setSelectedTags(state, action: PayloadAction<string[]>) {
      state.filters.selectedTags = action.payload;
    },

    setSelectedStatus(state, action: PayloadAction<number | 'none'>) {
      state.filters.selectedStatus = action.payload;
    },
    //

    // Optimistic update for task status
    updateTaskStatus(state, action: PayloadAction<{ ergId: number; status: 'done' | 'open' }>) {
      const { ergId, status } = action.payload;
      const task = state.aufgaben.find(t => t.id === ergId);
      if (task) {
        task.erg_strerl = status === 'done' ? 1 : 0;
      }
    },

    // Dialog controls
    openEmailDialog(state, action: PayloadAction<number>) {
      state.emailDialog.isOpen = true;
      state.emailDialog.taskId = action.payload;
    },
    closeEmailDialog(state) {
      state.emailDialog.isOpen = false;
      state.emailDialog.taskId = null;
    },

    openHistoryDialog(state, action: PayloadAction<number>) {
      state.historyDialog.isOpen = true;
      state.historyDialog.taskId = action.payload;
    },
    closeHistoryDialog(state) {
      state.historyDialog.isOpen = false;
      state.historyDialog.taskId = null;
    },

    openCloneDialog(state, action: PayloadAction<number>) {
      state.cloneDialog.isOpen = true;
      state.cloneDialog.taskId = action.payload;
    },
    closeCloneDialog(state) {
      state.cloneDialog.isOpen = false;
      state.cloneDialog.taskId = null;
    },

    openDeleteConfirm(state, action: PayloadAction<number>) {
      state.deleteConfirmDialog.isOpen = true;
      state.deleteConfirmDialog.taskId = action.payload;
    },
    closeDeleteConfirm(state) {
      state.deleteConfirmDialog.isOpen = false;
      state.deleteConfirmDialog.taskId = null;
    },

    openMoveTaskDialog(state, action: PayloadAction<number>) {
      state.moveTaskDialog.isOpen = true;
      state.moveTaskDialog.taskId = action.payload;
    },
    closeMoveTaskDialog(state) {
      state.moveTaskDialog.isOpen = false;
      state.moveTaskDialog.taskId = null;
    },

    openQuitConfirm(state, action: PayloadAction<number>) {
      state.quitConfirmDialog.isOpen = true;
      state.quitConfirmDialog.taskId = action.payload;
    },
    closeQuitConfirm(state) {
      state.quitConfirmDialog.isOpen = false;
      state.quitConfirmDialog.taskId = null;
    },

    // ✅ ADD: Mark task as read
    markAsRead(state, action: PayloadAction<{ agbID: number; ergID: number }>) {
      const { ergID, agbID } = action.payload;

      if (!state.readLogs[ergID]) {
        state.readLogs[ergID] = [];
      }

      if (!state.readLogs[ergID].includes(agbID)) {
        state.readLogs[ergID].push(agbID);
      }
    },

    // ✅ ADD: Toggle read status
    toggleReadStatus(state, action: PayloadAction<{ ergID: number; agbID: number }>) {
      const { ergID, agbID } = action.payload;

      if (!state.readLogs[ergID]) {
        state.readLogs[ergID] = [];
      }

      const index = state.readLogs[ergID].indexOf(agbID);
      if (index !== -1) {
        state.readLogs[ergID].splice(index, 1);
      } else {
        state.readLogs[ergID].push(agbID);
      }
    },

    // ✅ ADD: Set initial read logs from server
    setReadLogs(state, action: PayloadAction<Array<{ agb_id: number; erg_id: number }>>) {
      for (let log of action.payload) {
        const agbID = log.agb_id;
        const ergID = log.erg_id;
        if (!state.readLogs[ergID]) {
          state.readLogs[ergID] = [];
        }
        if (!state.readLogs[ergID].includes(agbID)) {
          state.readLogs[ergID].push(agbID);
        }
      }
    },
  },

  extraReducers: (builder) => {
    // ==========================================
    // FETCH AUFGABEN
    // ==========================================
    builder
      .addCase(fetchContactAufgaben.pending, (state) => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(fetchContactAufgaben.fulfilled, (state, action) => {
        const { table, groups } = action.payload;
        state.aufgaben = table;

        const groupsObj: Record<number, { path: string[] }> = {};
        groups.forEach((g: any) => {
          groupsObj[g.id] = { path: g.path };
        });
        state.groups = groupsObj;



        // Initialize tags from fetched data
        table.forEach((task: any) => {
          if (task.erg_lngid && task.tags) {
            state.taskTags[task.erg_lngid] = task.tags;
          }
        });

        state.isLoading = false;
        state.error = null;
      })
      .addCase(fetchContactAufgaben.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.error.message || 'Failed to fetch tasks';
      });



    // ==========================================
    // FETCH MEINE AUFGABEN
    // ==========================================
    builder
      .addCase(fetchMeineAufgaben.pending, (state) => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(fetchMeineAufgaben.fulfilled, (state, action) => {
        const { table, groups, readLogs } = action.payload;
        state.aufgaben = table;

        const groupsObj: Record<number, { path: string[] }> = {};
        groups.forEach((g: any) => {
          groupsObj[g.id] = { path: g.path };
        });
        state.groups = groupsObj;

        // Load read logs from response
        if (readLogs && Array.isArray(readLogs)) {
          state.readLogs = {};
          readLogs.forEach((log: any) => {
            const ergID = log.erg_id;
            const agbID = log.agb_id;
            if (!state.readLogs[ergID]) {
              state.readLogs[ergID] = [];
            }
            if (!state.readLogs[ergID].includes(agbID)) {
              state.readLogs[ergID].push(agbID);
            }
          });
        }

        // Initialize tags from fetched data
        table.forEach((task: any) => {
          if (task.erg_lngid && task.tags) {
            state.taskTags[task.erg_lngid] = task.tags;
          }
        });

        state.isLoading = false;
        state.error = null;
      })
      .addCase(fetchMeineAufgaben.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.error.message || 'Failed to fetch tasks';
      });

    // ==========================================
    // QUIT TASK
    // ==========================================
    builder
      .addCase(quitContactTask.pending, (state, action) => {
        state.pendingActions[action.meta.arg] = 'quitting';
      })
      .addCase(quitContactTask.fulfilled, (state, action) => {
        delete state.pendingActions[action.payload.ergId];
        const task = state.aufgaben.find(t => t.id === action.payload.ergId);
        if (task) {
          task.erg_strerl = 1;
        }
      })
      .addCase(quitContactTask.rejected, (state, action) => {
        delete state.pendingActions[action.meta.arg];
        state.error = action.error.message || 'Failed to quit task';
      });

    // ==========================================
    // RECOVER TASK
    // ==========================================
    builder
      .addCase(recoverContactTask.pending, (state, action) => {
        state.pendingActions[action.meta.arg] = 'recovering';
      })
      .addCase(recoverContactTask.fulfilled, (state, action) => {
        delete state.pendingActions[action.payload.ergId];
        const task = state.aufgaben.find(t => t.id === action.payload.ergId);
        if (task) {
          task.erg_strerl = 0;
        }
      })
      .addCase(recoverContactTask.rejected, (state, action) => {
        delete state.pendingActions[action.meta.arg];
        state.error = action.error.message || 'Failed to recover task';
      });

    // ==========================================
    // DELETE TASK
    // ==========================================
    builder
      .addCase(deleteContactTask.pending, (state, action) => {
        state.pendingActions[action.meta.arg] = 'deleting';
      })
      .addCase(deleteContactTask.fulfilled, (state, action) => {
        delete state.pendingActions[action.payload.ergId];
        state.aufgaben = state.aufgaben.filter(t => t.id !== action.payload.ergId);
      })
      .addCase(deleteContactTask.rejected, (state, action) => {
        delete state.pendingActions[action.meta.arg];
        state.error = action.error.message || 'Failed to delete task';
      });

    // ==========================================
    // NEXT TASK (WITHOUT FORM)
    // ==========================================
    builder
      .addCase(nextContactTaskWithoutForm.pending, (state, action) => {
        state.pendingActions[action.meta.arg] = 'processing';
      })
      .addCase(nextContactTaskWithoutForm.fulfilled, (state, action) => {
        delete state.pendingActions[action.payload.ergId];
        const task = state.aufgaben.find(t => t.id === action.payload.ergId);
        if (task) {
          task.erg_strerl = 1;
        }
      })
      .addCase(nextContactTaskWithoutForm.rejected, (state, action) => {
        delete state.pendingActions[action.meta.arg];
        state.error = action.error.message || 'Failed to process task';
      });



    // ==========================================
    // TAG MANAGEMENT
    // ==========================================
    builder
      .addCase(addContactTaskTag.fulfilled, (state, action) => {
        const { ergLngId, tag } = action.payload;
        if (!state.taskTags[ergLngId]) {
          state.taskTags[ergLngId] = [];
        }
        if (!state.taskTags[ergLngId].includes(tag)) {
          state.taskTags[ergLngId].push(tag);
        }
      })
      .addCase(removeContactTaskTag.fulfilled, (state, action) => {
        const { ergLngId, tag } = action.payload;
        if (state.taskTags[ergLngId]) {
          state.taskTags[ergLngId] = state.taskTags[ergLngId].filter(t => t !== tag);
        }
      });
    // ==========================================
    // MARK AS READ
    // ==========================================
    builder
      .addCase(markContactAsRead.fulfilled, (state, action) => {
        // We need to extract the task info from the action
        const ergId = action.meta.arg;
        const task = state.aufgaben.find(t => t.id === ergId);

        if (task) {
          const agbID = task.a1_agb_id ?? task.agb_id;

          if (!state.readLogs[ergId]) {
            state.readLogs[ergId] = [];
          }

          if (!state.readLogs[ergId].includes(agbID)) {
            state.readLogs[ergId].push(agbID);
          }
        }
      });

    // ==========================================
    // TOGGLE READ
    // ==========================================
    builder
      .addCase(toggleContactRead.fulfilled, (state, action) => {
        const ergId = action.meta.arg;
        const task = state.aufgaben.find(t => t.id === ergId);

        if (task) {
          const agbID = task.a1_agb_id ?? task.agb_id;

          if (!state.readLogs[ergId]) {
            state.readLogs[ergId] = [];
          }

          const index = state.readLogs[ergId].indexOf(agbID);
          if (index !== -1) {
            state.readLogs[ergId].splice(index, 1);
          } else {
            state.readLogs[ergId].push(agbID);
          }
        }
      });
  },
});

//export reducers 
export const {
  clearContactAufgaben,
  updateTaskStatus,
  setSearchString,
  setSelectedStatus,
  setSelectedTags,
  openEmailDialog,
  closeEmailDialog,
  openHistoryDialog,
  closeHistoryDialog,
  openCloneDialog,
  closeCloneDialog,
  openDeleteConfirm,
  closeDeleteConfirm,
  openMoveTaskDialog,
  closeMoveTaskDialog,
  openQuitConfirm,
  closeQuitConfirm,
  markAsRead,
  toggleReadStatus,
  setReadLogs,
  
} = contactAufgabenSlice.actions;

export default contactAufgabenSlice.reducer;