import {createSlice, createAsyncThunk, PayloadAction, ThunkDispatch} from '@reduxjs/toolkit';
import apiClient from 'api/apiClient';
import * as SecureStore from 'expo-secure-store';
import {AppDispatch} from "../../redux/store";
import {useDispatch} from "react-redux";
import {AxiosError} from "axios";
import {RejectedAction} from "@reduxjs/toolkit/dist/query/core/buildThunks";
import {createApi, fetchBaseQuery} from "@reduxjs/toolkit/query/react";
import {EndpointBuilder} from "@reduxjs/toolkit/dist/query/endpointDefinitions";

interface AuthState {
    accessToken: string | null;
    status: 'idle' | 'loading' | 'succeeded' | 'failed';
    errorMessage: string | null;
    isAuthenticated: boolean;
}

const initialState: AuthState = {
    accessToken: null,
    status: 'idle',
    errorMessage: null,
    isAuthenticated: false
};


export const loginUser = createAsyncThunk(
    'auth/login',
    async (credentials: { login: string; password: string }, {rejectWithValue}) => {
        try {
            const response = await apiClient.post<{ access_token: string }>('/auth/login', credentials);
            if (response.status == 401) {
                throw Error("Invalid credentials");
            }
            return response.data.access_token;
        } catch (error: any) {
            if (error instanceof AxiosError)
                return rejectWithValue('Server response error');
            else if (error instanceof Error)
                return rejectWithValue('Invalid credentials');
            return rejectWithValue('Unexpected error')
        }
    }
);

export const loadToken = createAsyncThunk<
    void,
    undefined,
    {
        dispatch: AppDispatch // Тип для dispatch
    }
>('auth/loadToken', async (_, {dispatch}) => {
    try {
        const token = await SecureStore.getItemAsync('access_token');
        if (token) {
            dispatch(authSlice.actions.setToken(token));
        }
    } catch (error) {
        console.error("Couldn't read token", error);
    }
});

export const logoutUser = createAsyncThunk<
    void,
    undefined,
    {
        dispatch: AppDispatch // Тип для dispatch
    }
>('auth/loadToken', async (_, {dispatch}) => {
    try {
        await SecureStore.deleteItemAsync('access_token');
        dispatch(authSlice.actions.logout())
    } catch (error) {
        console.error("Couldn't read token", error);
    }
});

const authSlice = createSlice({
    name: 'auth',
    initialState,
    reducers: {
        setToken: (state, action: PayloadAction<string>) => {
            state.accessToken = action.payload;
            state.isAuthenticated = true;
            state.status = "succeeded";
        },
        logout: (state) => {
            state.accessToken = null;
            state.status = "idle";
            state.isAuthenticated = false
            state.errorMessage = null;
        }
    },
    extraReducers: (builder) => {
        builder.addCase(loginUser.pending, (state) => {
            state.accessToken = "";
            state.status = 'loading';
            state.errorMessage = null;
            state.isAuthenticated = false;
        }).addCase(loginUser.fulfilled, (state, action: PayloadAction<string>) => {
            let accessToken = action.payload;

            state.accessToken = accessToken;
            state.status = 'succeeded';
            state.errorMessage = null
            state.isAuthenticated = true;

            SecureStore.setItemAsync('access_token', accessToken);
        }).addCase(loginUser.rejected, (state, action) => {
            if (action.payload)
                state.errorMessage = action.payload as string;
            state.status = "failed";
            state.isAuthenticated = false;
            state.accessToken = "";
        })
    },
});


export default authSlice.reducer;
