import { RejectedActionPayload, ServerErrorResponse } from '@/interface/Shared';
import { apiGet, apiPut, apiPost, apiDelete } 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';

interface EmployeeProfile {
  employee_id: string;
  staff_id: string;
  firstname: string;
  lastname: string;
  othername?: string;
  title?: string;
  gender?: string;
  dob?: string;
  personal_email?: string;
  personal_phone?: string;
  secondary_phone?: string;
  official_email?: string;
  official_phone?: string;
  picture?: string;
  residential_address?: string;
  postal_address?: string;
  marital_status?: string;
  appointment_date?: string;
  status?: string;
  confirmation_status?: string;
  confirmation_due_date?: string;
  account_number?: string;
  bank_branch_id?: string;
  position?: { position_id: string; name: string };
  organisationUnit?: { id: string; name: string; type?: { name: string } };
  branch?: { branch_id: string; name: string };
  employmentType?: { id: string; name: string };
  employeeCategory?: { id: string; name: string };
  employmentStatus?: { id: string; name: string };
  bankBranch?: { id: string; name: string; bank?: { id: string; name: string } };
  supervisor?: { employee_id: string; firstname: string; lastname: string; staff_id: string; picture?: string };
  [key: string]: any;
}

interface EmergencyContact {
  id: string;
  name: string;
  relationship: string;
  phone: string;
  secondary_phone?: string;
  email?: string;
  address?: string;
}

interface EmployeeSelfServiceState {
  profile: EmployeeProfile | null;
  emergencyContacts: EmergencyContact[];
  dependents: any[];
  qualifications: any[];
  documents: any[];
  assets: any[];
  jobHistory: any[];
  loading: boolean;
  actionLoading: boolean;
  error: string | null;
}

const initialState: EmployeeSelfServiceState = {
  profile: null,
  emergencyContacts: [],
  dependents: [],
  qualifications: [],
  documents: [],
  assets: [],
  jobHistory: [],
  loading: false,
  actionLoading: false,
  error: null,
};

export const fetchMyProfile = createAsyncThunk(
  'employeeSelfService/FETCH_PROFILE',
  async (_, { rejectWithValue }) => {
    try {
      const response = (await apiGet('/hr/me/profile')) as AxiosResponse<{ data: EmployeeProfile }>;
      return response.data.data;

    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const updateMyProfile = createAsyncThunk(
  'employeeSelfService/UPDATE_PROFILE',
  async (data: Record<string, any>, { rejectWithValue }) => {
    try {
      const response = (await apiPut('/hr/me/profile', data)) as AxiosResponse<{
        data: EmployeeProfile;
        message: string;
      }>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchMyEmergencyContacts = createAsyncThunk(
  'employeeSelfService/FETCH_EMERGENCY_CONTACTS',
  async (_, { rejectWithValue }) => {
    try {
      const response = (await apiGet('/hr/me/emergency-contacts')) as AxiosResponse<{
        data: EmergencyContact[];
      }>;
      return response.data.data;

    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const createEmergencyContact = createAsyncThunk(
  'employeeSelfService/CREATE_EMERGENCY_CONTACT',
  async (data: Omit<EmergencyContact, 'id'>, { rejectWithValue }) => {
    try {
      const response = (await apiPost('/hr/me/emergency-contacts', data)) as AxiosResponse<{
        data: EmergencyContact;
        message: string;
      }>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const updateEmergencyContact = createAsyncThunk(
  'employeeSelfService/UPDATE_EMERGENCY_CONTACT',
  async ({ id, data }: { id: string; data: Partial<EmergencyContact> }, { rejectWithValue }) => {
    try {
      const response = (await apiPut(`/hr/me/emergency-contacts/${id}`, data)) as AxiosResponse<{
        data: EmergencyContact;
        message: string;
      }>;
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const deleteEmergencyContact = createAsyncThunk(
  'employeeSelfService/DELETE_EMERGENCY_CONTACT',
  async (id: string, { rejectWithValue }) => {
    try {
      await apiDelete(`/hr/me/emergency-contacts/${id}`);
      return id;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchMyDependents = createAsyncThunk(
  'employeeSelfService/FETCH_DEPENDENTS',
  async (_, { rejectWithValue }) => {
    try {
      const response = (await apiGet('/hr/me/dependents')) as AxiosResponse<{ data: any[] }>;
      return response.data.data;

    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchMyQualifications = createAsyncThunk(
  'employeeSelfService/FETCH_QUALIFICATIONS',
  async (_, { rejectWithValue }) => {
    try {
      const response = (await apiGet('/hr/me/qualifications')) as AxiosResponse<{ data: any[] }>;
      return response.data.data;

    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchMyDocuments = createAsyncThunk(
  'employeeSelfService/FETCH_DOCUMENTS',
  async (_, { rejectWithValue }) => {
    try {
      const response = (await apiGet('/hr/me/documents')) as AxiosResponse<{ data: any[] }>;
      return response.data.data;

    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchMyAssets = createAsyncThunk(
  'employeeSelfService/FETCH_ASSETS',
  async (_, { rejectWithValue }) => {
    try {
      const response = (await apiGet('/hr/me/assets')) as AxiosResponse<{ data: any[] }>;
      return response.data.data;

    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const fetchMyJobHistory = createAsyncThunk(
  'employeeSelfService/FETCH_JOB_HISTORY',
  async (_, { rejectWithValue }) => {
    try {
      const response = (await apiGet('/hr/me/job-history')) as AxiosResponse<{ data: any[] }>;
      return response.data.data;

    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return rejectWithValue(error.response.data as ServerErrorResponse);
      }
      throw error;
    }
  },
);

export const EmployeeSelfServiceSlice = createSlice({
  name: 'employeeSelfService',
  initialState,
  reducers: {},
  extraReducers(builder) {
    builder
      .addCase(fetchMyProfile.pending, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(
        fetchMyProfile.fulfilled,
        (state: Draft<EmployeeSelfServiceState>, action: PayloadAction<EmployeeProfile>) => {
          state.profile = action.payload;
          state.loading = false;
        },
      )
      .addCase(fetchMyProfile.rejected, (state: Draft<EmployeeSelfServiceState>, action: RejectedActionPayload) => {
        state.loading = false;
        message.error(Helpers.handleServerError(action.payload), 8);
      });

    builder
      .addCase(updateMyProfile.pending, (state: Draft<EmployeeSelfServiceState>) => {
        state.actionLoading = true;
        state.error = null;
      })
      .addCase(
        updateMyProfile.fulfilled,
        (
          state: Draft<EmployeeSelfServiceState>,
          action: PayloadAction<{ data: EmployeeProfile; message: string }>,
        ) => {
          state.profile = action.payload.data;
          state.actionLoading = false;
          message.success(action.payload.message);
        },
      )
      .addCase(
        updateMyProfile.rejected,
        (state: Draft<EmployeeSelfServiceState>, action: RejectedActionPayload) => {
          state.actionLoading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(state.error, 10);
        },
      );

    builder
      .addCase(fetchMyEmergencyContacts.pending, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = true;
      })
      .addCase(
        fetchMyEmergencyContacts.fulfilled,
        (state: Draft<EmployeeSelfServiceState>, action: PayloadAction<EmergencyContact[]>) => {
          state.emergencyContacts = action.payload;
          state.loading = false;
        },
      )
      .addCase(fetchMyEmergencyContacts.rejected, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = false;
        state.error = 'Failed to load emergency contacts.';
      });

    builder
      .addCase(createEmergencyContact.pending, (state: Draft<EmployeeSelfServiceState>) => {
        state.actionLoading = true;
      })
      .addCase(
        createEmergencyContact.fulfilled,
        (
          state: Draft<EmployeeSelfServiceState>,
          action: PayloadAction<{ data: EmergencyContact; message: string }>,
        ) => {
          state.emergencyContacts.push(action.payload.data);
          state.actionLoading = false;
          message.success(action.payload.message);
        },
      )
      .addCase(
        createEmergencyContact.rejected,
        (state: Draft<EmployeeSelfServiceState>, action: RejectedActionPayload) => {
          state.actionLoading = false;
          state.error = Helpers.handleServerError(action.payload);
          message.error(state.error, 10);
        },
      );

    builder
      .addCase(
        deleteEmergencyContact.fulfilled,
        (state: Draft<EmployeeSelfServiceState>, action: PayloadAction<string>) => {
          state.emergencyContacts = state.emergencyContacts.filter((c) => c.id !== action.payload);
          message.success('Emergency contact deleted.');
        },
      )
      .addCase(
        deleteEmergencyContact.rejected,
        (state: Draft<EmployeeSelfServiceState>, action: RejectedActionPayload) => {
          state.error = Helpers.handleServerError(action.payload);
          message.error(state.error, 10);
        },
      );

    builder
      .addCase(fetchMyDependents.fulfilled, (state: Draft<EmployeeSelfServiceState>, action) => {
        state.dependents = action.payload;
        state.loading = false;
      })
      .addCase(fetchMyDependents.pending, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = true;
      })
      .addCase(fetchMyDependents.rejected, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = false;
      });

    builder
      .addCase(
        fetchMyQualifications.fulfilled,
        (state: Draft<EmployeeSelfServiceState>, action) => {
          state.qualifications = action.payload;
          state.loading = false;
        },
      )
      .addCase(fetchMyQualifications.pending, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = true;
      })
      .addCase(fetchMyQualifications.rejected, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = false;
      });

    builder
      .addCase(fetchMyDocuments.fulfilled, (state: Draft<EmployeeSelfServiceState>, action) => {
        state.documents = action.payload;
        state.loading = false;
      })
      .addCase(fetchMyDocuments.pending, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = true;
      })
      .addCase(fetchMyDocuments.rejected, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = false;
      });

    builder
      .addCase(fetchMyAssets.fulfilled, (state: Draft<EmployeeSelfServiceState>, action) => {
        state.assets = action.payload;
        state.loading = false;
      })
      .addCase(fetchMyAssets.pending, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = true;
      })
      .addCase(fetchMyAssets.rejected, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = false;
      });

    builder
      .addCase(fetchMyJobHistory.fulfilled, (state: Draft<EmployeeSelfServiceState>, action) => {
        state.jobHistory = action.payload;
        state.loading = false;
      })
      .addCase(fetchMyJobHistory.pending, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = true;
      })
      .addCase(fetchMyJobHistory.rejected, (state: Draft<EmployeeSelfServiceState>) => {
        state.loading = false;
      });
  },
});

export default EmployeeSelfServiceSlice;
export type { EmployeeSelfServiceState, EmployeeProfile, EmergencyContact };
