import { RejectedActionPayload } from '@/interface/Shared';
import { apiGet } from '@/services/api/api';
import Helpers from '@/utilities/Helpers';
import { createAsyncThunk, createSlice, Draft } from '@reduxjs/toolkit';

export interface AttendanceRecord {
  id: string;
  employee_id: string;
  date: string;
  clock_in: string | null;
  clock_out: string | null;
  status: string;
  shift?: { name: string; start_time: string; end_time: string };
  [key: string]: any;
}

export interface ShiftSchedule {
  id: string;
  shift_id: string;
  date: string;
  shift: { name: string; start_time: string; end_time: string };
  [key: string]: any;
}

interface PaginationMeta {
  current_page: number;
  last_page: number;
  per_page: number;
  total: number;
}

interface EmployeeAttendanceState {
  attendance: AttendanceRecord[];
  attendanceMeta: PaginationMeta | null;
  shifts: ShiftSchedule[];
  loading: boolean;
  error: string | null;
}

const initialState: EmployeeAttendanceState = {
  attendance: [],
  attendanceMeta: null,
  shifts: [],
  loading: false,
  error: null,
};

export const fetchMyAttendance = createAsyncThunk(
  'employeeAttendance/fetchMyAttendance',
  async (params: { from?: string; to?: string; page?: number; per_page?: number } = {}, { rejectWithValue }) => {
    try {
      const response = await apiGet('/hr/me/attendance', { params });
      return response.data;
    } catch (error: any) {
      return rejectWithValue(Helpers.handleServerError(error));
    }
  },
);

export const fetchMyShifts = createAsyncThunk(
  'employeeAttendance/fetchMyShifts',
  async (params: { from?: string; to?: string } = {}, { rejectWithValue }) => {
    try {
      const response = await apiGet('/hr/me/shifts', { params });
      return response.data;
    } catch (error: any) {
      return rejectWithValue(Helpers.handleServerError(error));
    }
  },
);

const EmployeeAttendanceSlice = createSlice({
  name: 'employeeAttendance',
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchMyAttendance.pending, (state: Draft<EmployeeAttendanceState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchMyAttendance.fulfilled, (state: Draft<EmployeeAttendanceState>, action) => {
        state.loading = false;
        state.attendance = action.payload.data ?? action.payload;
        if (action.payload.meta) {
          state.attendanceMeta = action.payload.meta;
        }
      })
      .addCase(fetchMyAttendance.rejected, (state: Draft<EmployeeAttendanceState>, action) => {
        state.loading = false;
        state.error = (action.payload as RejectedActionPayload)?.message ?? 'Failed to fetch attendance';
      })
      .addCase(fetchMyShifts.pending, (state: Draft<EmployeeAttendanceState>) => {
        state.loading = true;
      })
      .addCase(fetchMyShifts.fulfilled, (state: Draft<EmployeeAttendanceState>, action) => {
        state.loading = false;
        state.shifts = action.payload.data ?? action.payload;
      })
      .addCase(fetchMyShifts.rejected, (state: Draft<EmployeeAttendanceState>, action) => {
        state.loading = false;
        state.error = (action.payload as RejectedActionPayload)?.message ?? 'Failed to fetch shifts';
      });
  },
});

export default EmployeeAttendanceSlice;
