import {
  createAsyncThunk,
  createSlice,
  type PayloadAction,
} from "@reduxjs/toolkit";
import { sendRpcRequest } from "../../services/apiClient";
import { TG_USER_ID } from "../../constants/constants";

interface IAuthUser {
  token: string;
}

interface IAuthState {
  user: IAuthUser | null;
  loadingLogin: boolean;
  loadingRegister: boolean;
  loadingRecover: boolean;
  errorLogin: string | null;
  errorRegister: string | null;
  errorRecover: string | null;
  successLogin: boolean | string;
  successRegister: boolean | string;
  successRecover: boolean | string;
}

interface IResponseError {
  code: number;
  message: string;
}

const initialState: IAuthState = {
  user: null,
  loadingLogin: false,
  loadingRegister: false,
  loadingRecover: false,
  errorLogin: null,
  errorRegister: null,
  errorRecover: null,
  successLogin: false,
  successRegister: false,
  successRecover: false,
};

export const authLogin = createAsyncThunk<
  IAuthUser,
  { login: string; password: string },
  { rejectValue: string }
>("auth/login", async ({ login, password }, { rejectWithValue }) => {
  try {
    const response = await sendRpcRequest("auth.loginPass", {
      login,
      password,
      fcmKey: null,
    });

    return response as IAuthUser;
  } catch (error: unknown) {
    const err = error as IResponseError;
    return rejectWithValue(err.message);
  }
});

export const authRegister = createAsyncThunk<
  IAuthUser,
  { login: string; password: string },
  { rejectValue: string }
>("auth/register", async ({ login, password }, { rejectWithValue }) => {
  try {
    const response = await sendRpcRequest("auth.registerloginpass", {
      login,
      password,
    });

    return response as IAuthUser;
  } catch (error: unknown) {
    const err = error as IResponseError;
    return rejectWithValue(err.message);
  }
});

export const authRecover = createAsyncThunk<
  IAuthUser,
  { login: string; newPassword: string },
  { rejectValue: string }
>("auth/recover", async ({ login, newPassword }, { rejectWithValue }) => {
  try {
    const response = await sendRpcRequest("auth.resetpassword", {
      login,
      newPassword,
    });

    return response as IAuthUser;
  } catch (error: unknown) {
    const err = error as IResponseError;
    return rejectWithValue(err.message);
  }
});

const authSlice = createSlice({
  name: "auth",
  initialState,
  reducers: {
    logout() {
      localStorage.removeItem(`token-${TG_USER_ID}`);
      localStorage.removeItem(`pincode-${TG_USER_ID}`);
      sessionStorage.removeItem(`pincode-${TG_USER_ID}`);
      window.location.href = "/";
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(authLogin.pending, (state) => {
        state.loadingLogin = true;
      })
      .addCase(
        authLogin.fulfilled,
        (state, action: PayloadAction<IAuthUser>) => {
          state.loadingLogin = false;
          state.user = action.payload;
          state.successLogin = true;
        }
      )
      .addCase(authLogin.rejected, (state, action) => {
        state.loadingLogin = false;
        state.errorLogin = action.payload ?? "Login failed";
      })

      .addCase(authRegister.pending, (state) => {
        state.loadingRegister = true;
        state.errorRegister = null;
      })
      .addCase(
        authRegister.fulfilled,
        (state, action: PayloadAction<IAuthUser>) => {
          state.loadingRegister = false;
          state.user = action.payload;
          state.successRegister = true;
        }
      )
      .addCase(authRegister.rejected, (state, action) => {
        state.loadingRegister = false;
        state.errorRegister = action.payload ?? "Registration failed";
      })

      .addCase(authRecover.pending, (state) => {
        state.loadingRecover = true;
        state.errorRecover = null;
      })
      .addCase(
        authRecover.fulfilled,
        (state, action: PayloadAction<IAuthUser>) => {
          state.loadingRecover = false;
          state.user = action.payload;
          state.successRecover = "Confirmation code sent to email";
        }
      )
      .addCase(authRecover.rejected, (state, action) => {
        state.loadingRecover = false;
        state.errorRecover = action.payload ?? "Recovery failed";
      });
  },
});

export const { logout } = authSlice.actions;
export default authSlice.reducer;
