import { createSlice, PayloadAction } from "@reduxjs/toolkit";

export interface DeviceEventsState {
  ksx: number[]; // 32 Slots: Schleifenmessung aktiv
  ksy: number[]; // 32 Slots: TDR-Messung aktiv
  ksz: number[]; // 32 Slots: Abgleich aktiv
  anyLoopActive: boolean;
  anyTdrActive: boolean;
  anyAlignmentActive: boolean;
  loopStartedAt: number | null; // unix ms timestamp when KSX became active
  tdrStartedAt: number | null; // unix ms timestamp when KSY became active
  alignmentStartedAt: number | null; // unix ms timestamp when KSZ became active
}

const ZERO32 = Array.from({ length: 32 }, () => 0);

const initialState: DeviceEventsState = {
  ksx: ZERO32.slice(),
  ksy: ZERO32.slice(),
  ksz: ZERO32.slice(),
  anyLoopActive: false,
  anyTdrActive: false,
  anyAlignmentActive: false,
  loopStartedAt: null,
  tdrStartedAt: null,
  alignmentStartedAt: null,
};

export const deviceEventsSlice = createSlice({
  name: "deviceEvents",
  initialState,
  reducers: {
    setEvents(
      state,
      action: PayloadAction<{ ksx?: number[]; ksy?: number[]; ksz?: number[] }>
    ) {
      const prevLoop = state.anyLoopActive;
      const prevTdr = state.anyTdrActive;
      const prevAlign = state.anyAlignmentActive;
      const to32 = (arr?: number[]) => {
        if (!Array.isArray(arr)) return ZERO32.slice();
        const a = arr
          .slice(0, 32)
          .map((v) => (typeof v === "number" && v ? 1 : 0));
        while (a.length < 32) a.push(0);
        return a;
      };
      state.ksx = to32(action.payload.ksx);
      state.ksy = to32(action.payload.ksy);
      state.ksz = to32(action.payload.ksz);
      state.anyLoopActive = state.ksx.some((v) => v === 1);
      state.anyTdrActive = state.ksy.some((v) => v === 1);
      state.anyAlignmentActive = state.ksz.some((v) => v === 1);

      // Transition detection to set/reset startedAt timestamps
      if (!prevLoop && state.anyLoopActive) state.loopStartedAt = Date.now();
      if (prevLoop && !state.anyLoopActive) state.loopStartedAt = null;
      if (!prevTdr && state.anyTdrActive) state.tdrStartedAt = Date.now();
      if (prevTdr && !state.anyTdrActive) state.tdrStartedAt = null;
      if (!prevAlign && state.anyAlignmentActive)
        state.alignmentStartedAt = Date.now();
      if (prevAlign && !state.anyAlignmentActive)
        state.alignmentStartedAt = null;
    },
    resetEvents(state) {
      state.ksx = ZERO32.slice();
      state.ksy = ZERO32.slice();
      state.ksz = ZERO32.slice();
      state.anyLoopActive = false;
      state.anyTdrActive = false;
      state.anyAlignmentActive = false;
      state.loopStartedAt = null;
      state.tdrStartedAt = null;
      state.alignmentStartedAt = null;
    },
  },
});

export const { setEvents, resetEvents } = deviceEventsSlice.actions;
export default deviceEventsSlice.reducer;
