import { Employee } from '@/interface/Employee';
import {
  ConfirmationDashboardMetrics,
  ConfirmEmployeePayload,
  EmployeeConfirmation,
  ExtendProbationPayload,
} from '@/interface/EmployeeConfirmation';
import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import { apiGet, apiPost } from '@/services/api/api';
import Helpers from '@/utilities/Helpers';
import { createAsyncThunk, createSlice, Draft, PayloadAction } from '@reduxjs/toolkit';
import { message } from 'antd';
import axios, { AxiosResponse } from 'axios';
import { ConfirmationActions } from './actionTypes';

interface ConfirmationState {
  dashboardMetrics: ConfirmationDashboardMetrics | null;
  confirmationList: Employee[];
  confirmationListPagination: {
    current_page: number;
    last_page: number;
    total: number;
    per_page: number;
  } | null;
  confirmationHistory: EmployeeConfirmation[];
  loading: boolean;
  dashboardLoading: boolean;
  actionLoading: boolean;
}

const initialState: ConfirmationState = {
  dashboardMetrics: null,
  confirmationList: [],
  confirmationListPagination: null,
  confirmationHistory: [],
  loading: false,
  dashboardLoading: false,
  actionLoading: false,
};

export const fetchConfirmationDashboard = createAsyncThunk(
  ConfirmationActions.FETCH_DASHBOARD,
  async () => {
    const response = (await apiGet(
      '/hr/confirmations/dashboard',
    )) as AxiosResponse<ConfirmationDashboardMetrics>;
    return response.data;
  },
);

export const fetchConfirmationList = createAsyncThunk(
  ConfirmationActions.FETCH_LIST,
  async (params?: Record<string, string | number | undefined>) => {
    const query = new URLSearchParams();
    if (params) {
      Object.entries(params).forEach(([key, value]) => {
        if (value !== undefined && value !== '') {
          query.append(key, String(value));
        }
      });
    }
    const url = `/hr/confirmations${query.toString() ? `?${query.toString()}` : ''}`;
    const response = (await apiGet(url)) as AxiosResponse<{
      data: Employee[];
      current_page: number;
      last_page: number;
      total: number;
      per_page: number;
    }>;
    return response.data;
  },
);

export const fetchConfirmationHistory = createAsyncThunk(
  ConfirmationActions.FETCH_HISTORY,
  async (employeeId: string) => {
    const response = (await apiGet(
      `/hr/employees/${employeeId}/confirmation-history`,
    )) as AxiosResponse<EmployeeConfirmation[]>;
    return response.data;
  },
);

export const confirmEmployee = createAsyncThunk(
  ConfirmationActions.CONFIRM_EMPLOYEE,
  async (payload: ConfirmEmployeePayload, { rejectWithValue }) => {
    try {
      const { employee_id, ...data } = payload;
      const response = (await apiPost(
        `/hr/employees/${employee_id}/confirm`,
        data,
      )) as AxiosResponse<EmployeeConfirmation>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const extendProbation = createAsyncThunk(
  ConfirmationActions.EXTEND_PROBATION,
  async (payload: ExtendProbationPayload, { rejectWithValue }) => {
    try {
      const { employee_id, ...data } = payload;
      const response = (await apiPost(
        `/hr/employees/${employee_id}/extend-probation`,
        data,
      )) as AxiosResponse<EmployeeConfirmation>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const ConfirmationSlice = createSlice({
  name: 'confirmations',
  initialState,
  reducers: {},
  extraReducers(builder) {
    builder
      .addCase(fetchConfirmationDashboard.pending, (state: Draft<ConfirmationState>) => {
        state.dashboardLoading = true;
      })
      .addCase(
        fetchConfirmationDashboard.fulfilled,
        (state: Draft<ConfirmationState>, action: PayloadAction<ConfirmationDashboardMetrics>) => {
          state.dashboardMetrics = action.payload;
          state.dashboardLoading = false;
        },
      )
      .addCase(fetchConfirmationDashboard.rejected, (state: Draft<ConfirmationState>) => {
        state.dashboardLoading = false;
      });

    builder
      .addCase(fetchConfirmationList.pending, (state: Draft<ConfirmationState>) => {
        state.loading = true;
      })
      .addCase(fetchConfirmationList.fulfilled, (state: Draft<ConfirmationState>, action) => {
        state.confirmationList = action.payload.data;
        state.confirmationListPagination = {
          current_page: action.payload.current_page,
          last_page: action.payload.last_page,
          total: action.payload.total,
          per_page: action.payload.per_page,
        };
        state.loading = false;
      })
      .addCase(fetchConfirmationList.rejected, (state: Draft<ConfirmationState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(fetchConfirmationHistory.pending, (state: Draft<ConfirmationState>) => {
        state.loading = true;
      })
      .addCase(
        fetchConfirmationHistory.fulfilled,
        (state: Draft<ConfirmationState>, action: PayloadAction<EmployeeConfirmation[]>) => {
          state.confirmationHistory = action.payload;
          state.loading = false;
        },
      )
      .addCase(fetchConfirmationHistory.rejected, (state: Draft<ConfirmationState>) => {
        state.loading = false;
      });

    builder
      .addCase(confirmEmployee.pending, (state: Draft<ConfirmationState>) => {
        state.actionLoading = true;
      })
      .addCase(confirmEmployee.fulfilled, (state: Draft<ConfirmationState>) => {
        state.actionLoading = false;
        message.success('Employee confirmed successfully');
      })
      .addCase(
        confirmEmployee.rejected,
        (state: Draft<ConfirmationState>, action: RejectedActionPayload) => {
          state.actionLoading = false;
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );

    builder
      .addCase(extendProbation.pending, (state: Draft<ConfirmationState>) => {
        state.actionLoading = true;
      })
      .addCase(extendProbation.fulfilled, (state: Draft<ConfirmationState>) => {
        state.actionLoading = false;
        message.success('Probation extended successfully');
      })
      .addCase(
        extendProbation.rejected,
        (state: Draft<ConfirmationState>, action: RejectedActionPayload) => {
          state.actionLoading = false;
          message.error(Helpers.handleServerError(action.payload), 10);
        },
      );
  },
});

export default ConfirmationSlice;
export type { ConfirmationState };
