import {
  TrainingSummaryReportData,
  EmployeeTrainingRecordData,
  ComplianceReportData,
} from '@/interface/TrainingReport';
import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import { apiGet } 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 { TrainingReportActions } from './actionTypes';

interface TrainingReportsState {
  summaryReport: TrainingSummaryReportData | null;
  employeeRecord: EmployeeTrainingRecordData | null;
  complianceReport: ComplianceReportData | null;
  loading: boolean;
  error: string | null;
}

const initialState: TrainingReportsState = {
  summaryReport: null,
  employeeRecord: null,
  complianceReport: null,
  loading: false,
  error: null,
};

export const fetchTrainingSummaryReport = createAsyncThunk(
  TrainingReportActions.FETCH_SUMMARY_REPORT,
  async (year: number, { rejectWithValue }) => {
    try {
      const response = (await apiGet(
        `/training/reports/summary?year=${year}`,
      )) as AxiosResponse<TrainingSummaryReportData>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchEmployeeTrainingRecord = createAsyncThunk(
  TrainingReportActions.FETCH_EMPLOYEE_RECORD,
  async (employeeId: string, { rejectWithValue }) => {
    try {
      const response = (await apiGet(
        `/training/reports/employee/${employeeId}`,
      )) as AxiosResponse<EmployeeTrainingRecordData>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchComplianceReport = createAsyncThunk(
  TrainingReportActions.FETCH_COMPLIANCE_REPORT,
  async (_, { rejectWithValue }) => {
    try {
      const response = (await apiGet(
        '/training/reports/compliance',
      )) as AxiosResponse<ComplianceReportData>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const TrainingReportsSlice = createSlice({
  name: 'trainingReports',
  initialState,
  reducers: {
    clearTrainingReport: (state: Draft<TrainingReportsState>) => {
      state.summaryReport = null;
      state.employeeRecord = null;
      state.complianceReport = null;
      state.error = null;
    },
  },
  extraReducers(builder) {
    builder
      .addCase(fetchTrainingSummaryReport.pending, (state: Draft<TrainingReportsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchTrainingSummaryReport.fulfilled,
        (state: Draft<TrainingReportsState>, action: PayloadAction<TrainingSummaryReportData>) => {
          state.loading = false;
          state.summaryReport = action.payload;
        },
      )
      .addCase(
        fetchTrainingSummaryReport.rejected,
        (state: Draft<TrainingReportsState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(state.error, 10);
        },
      )

      .addCase(fetchEmployeeTrainingRecord.pending, (state: Draft<TrainingReportsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchEmployeeTrainingRecord.fulfilled,
        (
          state: Draft<TrainingReportsState>,
          action: PayloadAction<EmployeeTrainingRecordData>,
        ) => {
          state.loading = false;
          state.employeeRecord = action.payload;
        },
      )
      .addCase(
        fetchEmployeeTrainingRecord.rejected,
        (state: Draft<TrainingReportsState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(state.error, 10);
        },
      )

      .addCase(fetchComplianceReport.pending, (state: Draft<TrainingReportsState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchComplianceReport.fulfilled,
        (state: Draft<TrainingReportsState>, action: PayloadAction<ComplianceReportData>) => {
          state.loading = false;
          state.complianceReport = action.payload;
        },
      )
      .addCase(
        fetchComplianceReport.rejected,
        (state: Draft<TrainingReportsState>, action: RejectedActionPayload) => {
          state.loading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(state.error, 10);
        },
      );
  },
});

export const { clearTrainingReport } = TrainingReportsSlice.actions;
export default TrainingReportsSlice;
