import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import APIs from '@src/api/APIs';
import { EItemType } from '@src/constants/Enums';
import URLInfo from '@src/constants/URLInfo';
import { ILog, IOwner, IResaleInfo, IToken, ITokenBaseInfo } from 'metarare';

type TokenState = {
  isDataLoaded: boolean;
  baseInfo: ITokenBaseInfo | null;
  log: ILog[];
  owner: IOwner[];
  resaleInfo: IResaleInfo | null;
  data: IToken | null;
}

const tokenState: TokenState = {
  isDataLoaded: true,
  baseInfo: null,
  log: [],
  owner: [],
  resaleInfo: null,
  data: null,
};

export const fetchToken = createAsyncThunk<Promise<any>, number>(
  'token/fetchToken',
  async (id, thunkAPI) => {
    try {
      const response = await APIs.fetchToken(id);
      return response;
    } catch (err) {
      return thunkAPI.rejectWithValue('Something went wrong.');
    }
  }
);

export const fetchBaseInfo = createAsyncThunk<Promise<any>, EItemType>(
  'token/fetchBaseInfo',
  async (type, thunkAPI) => {
    try {
      const response = await APIs.fetchBaseInfo(type);
      return response;
    } catch (err) {
      return thunkAPI.rejectWithValue('Something went wrong.');
    }
  }
);

export const fetchLog = createAsyncThunk<Promise<any>, number>(
  'token/fetchLog',
  async (id, thunkAPI) => {
    try {
      const response = await APIs.fetchLog(id);
      return response;
    } catch (err) {
      return thunkAPI.rejectWithValue('Something went wrong.');
    }
  }
);

export const fetchOwner = createAsyncThunk<Promise<any>, string>(
  'token/fetchOwner',
  async (id, thunkAPI) => {
    try {
      const response = await APIs.fetchOwner(id);
      return response;
    } catch (err) {
      return thunkAPI.rejectWithValue('Something went wrong.');
    }
  }
);

export const fetchResaleInfo = createAsyncThunk<Promise<any>, number>(
  'token/fetchResaleInfo',
  async (id, thunkAPI) => {
    try {
      const response = await APIs.fetchResaleInfo(id);
      return response;
    } catch (err) {
      return thunkAPI.rejectWithValue('Something went wrong.');
    }
  }
);

export const slice = createSlice({
  name: 'token',
  initialState: tokenState,
  reducers: {
    addCollection: (state: TokenState, action) => {
      const { name, thumbnail_image } = action.payload.collection_profile;
      const { id, is_official } = action.payload.collection;

      state.baseInfo?.collection.push({
        collection_id: id,
        name,
        thumbnail_image,
        is_official,
      });
    }
  },
  extraReducers: {
    [fetchToken.pending.type]: (state: TokenState) => {
      state.isDataLoaded = false;
    },
    [fetchToken.fulfilled.type]: (state: TokenState, action) => {
      const { payload } = action;

      state.data = payload;
      state.isDataLoaded = true;
    },
    [fetchToken.rejected.type]: (state: TokenState) => {
      state.isDataLoaded = true;
      window.location.href = URLInfo.ERROR;
    },
    [fetchBaseInfo.fulfilled.type]: (state: TokenState, action) => {
      const { payload } = action;

      state.baseInfo = payload;
    },
    [fetchLog.fulfilled.type]: (state: TokenState, action) => {
      const { payload } = action;

      state.log = payload;
    },
    [fetchOwner.fulfilled.type]: (state: TokenState, action) => {
      const { payload } = action;

      state.owner = payload;
    },
    [fetchResaleInfo.fulfilled.type]: (state: TokenState, action) => {
      const { payload } = action;

      state.resaleInfo = payload;
    },
  },
});

export const {
  addCollection
} = slice.actions;

const TokenReducer = slice.reducer;
export default TokenReducer;
