import { createSlice, createAsyncThunk, createAction } from '@reduxjs/toolkit';
import axios from 'axios';

interface MainState {
  isFetching: boolean;
  errorMessage: string;
  currentUser: any;
  notify: any;
  token: string;
}

const initialState: MainState = {
  /* User */
  isFetching: false,
  errorMessage: '',
  currentUser: null,
  token: '',
  notify: {
    showNotification: false,
    textNotification: '',
    typeNotification: 'warn',
  },
};

export const resetAction = createAction('auth/passwordReset/reset')

export const loginUser = createAsyncThunk(
    'auth/loginUser',
    async (creds: Record<string, string>, { rejectWithValue }) => {
      try {
        const response = await axios.post('auth/signin/local', creds);
        return response.data;
      } catch (error) {
        if (!error.response) {
          throw error;
        }
        return rejectWithValue(error.response.data);
      }
    }
);

export const loginDemoUser = createAsyncThunk(
  'auth/loginDemoUser',
  async (role: 'admin' | 'coach' | 'client', { rejectWithValue }) => {
    try {
      const response = await axios.post('auth/signin/demo', { role });
      return response.data;
    } catch (error) {
      if (!error.response) {
        throw error;
      }
      return rejectWithValue(error.response.data);
    }
  },
);

export const passwordReset = createAsyncThunk(
    'auth/passwordReset',
    async (value: Record<string, string>, { rejectWithValue }) => {
      try {
        const { data: response } = await axios.put('/auth/password-reset', {
          token: value.token,
          password: value.password,
          type: value.type,
        });

        return response.data;
      } catch (error) {
        if (!error.response) {
          throw error;
        }

        return rejectWithValue(error.response.data);
      }
    },
);

export const findMe = createAsyncThunk('auth/findMe', async () => {
  const response = await axios.get('auth/me');
  return response.data;
});

export const logoutUser = createAsyncThunk('auth/logoutUser', async () => {
  await axios.post('/auth/logout');
  return true;
});

export const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder.addCase(loginUser.pending, (state) => {
      state.isFetching = true;
    });
    builder.addCase(loginUser.fulfilled, (state, action) => {
      state.errorMessage = '';
      state.token = action.payload.authenticated ? 'cookie' : '';
      state.isFetching = false;
    });

    builder.addCase(loginUser.rejected, (state, action) => {
      state.errorMessage = String(action.payload) || 'Something went wrong. Try again';
      state.isFetching = false;
    });
    builder.addCase(loginDemoUser.pending, (state) => {
      state.isFetching = true;
    });
    builder.addCase(loginDemoUser.fulfilled, (state, action) => {
      state.errorMessage = '';
      state.token = action.payload.authenticated ? 'cookie' : '';
      state.isFetching = false;
    });
    builder.addCase(loginDemoUser.rejected, (state, action) => {
      state.errorMessage = String(action.payload) || 'Demo login failed. Try again';
      state.isFetching = false;
    });
    builder.addCase(findMe.pending, (state) => {
      state.isFetching = true;
      state.errorMessage = '';
    });
    builder.addCase(findMe.fulfilled, (state, action) => {
      state.currentUser = action.payload;
      state.isFetching = false;
    });
    builder.addCase(findMe.rejected, (state) => {
      state.currentUser = null;
      state.isFetching = false;
    });
    builder.addCase(logoutUser.fulfilled, () => initialState);
    builder.addCase(logoutUser.rejected, (state) => {
      state.errorMessage = 'Logout failed. Please retry.';
    });

    builder.addCase(passwordReset.fulfilled, (state, action) => {
      state.notify.showNotification = true;
      state.notify.textNotification = 'Password has been reset successfully';
    });

    builder.addCase(resetAction, (state) => initialState);

    builder.addCase(passwordReset.rejected, (state) => {
      state.errorMessage = 'Something was wrong. Try again';
    });
  },
});

// Action creators are generated for each case reducer function
export default authSlice.reducer;
