import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { RootState } from '../../store';
import { BookingPriceDetail, BookingPriceDetails, BookingProductNotification } from '@qite/tide-client/build/types';
import { setPackage } from '../booking/booking-slice';
import { selectBookingPackageBookRequest, selectLanguageCode, selectPackageDetails } from '../booking/selectors';
import priceDetailsApi from './price-details-api';
import { updatePackageDetails } from './util';

export interface PriceDetailsState {
  priceDetails: BookingPriceDetail[];
  notifications: BookingProductNotification[];
  deposit?: number;
  commission?: number;
  isBusy: boolean;
}

export const fetchPriceDetails = createAsyncThunk('priceDetails/fetchPriceDetails', async (_, { dispatch, getState, signal }) => {
  dispatch(setFetchingPriceDetails(true));
  dispatch(resetPriceDetails());

  const state = getState() as RootState;
  const languageCode = selectLanguageCode(state);

  const request = selectBookingPackageBookRequest(state);

  if (!request) {
    throw Error('Product not available.');
  }

  const priceDetails: BookingPriceDetails = await priceDetailsApi.fetchPriceDetails(state.apiSettings, request, signal, languageCode);

  dispatch(setFetchingPriceDetails(false));

  const packageDetails = selectPackageDetails(state);
  if (packageDetails) {
    const updatedPackageDetails = updatePackageDetails(packageDetails, priceDetails.changedLines);
    dispatch(setPackage(updatedPackageDetails));
  }

  return priceDetails;
});

const priceDetailsSlice = createSlice({
  name: 'priceDetails',
  initialState: <PriceDetailsState>{
    priceDetails: [],
    notifications: [],
    isBusy: false
  },
  reducers: {
    setFetchingPriceDetails(state, action: PayloadAction<boolean>) {
      state.isBusy = action.payload;
    },
    setNotifications(state, action: PayloadAction<BookingProductNotification[]>) {
      state.notifications = action.payload;
    },
    resetPriceDetails(state, _: PayloadAction<void>) {
      state.priceDetails = [];
    }
  },
  extraReducers: (builder) => {
    builder.addCase(fetchPriceDetails.fulfilled, (state, action) => {
      if (action.payload) {
        state.deposit = action.payload.deposit;
        state.commission = action.payload.commission;
        state.priceDetails = action.payload.details;
        state.notifications = action.payload.notifications;
      }
    });
  }
});

const { setFetchingPriceDetails } = priceDetailsSlice.actions;

export const { resetPriceDetails, setNotifications } = priceDetailsSlice.actions;

export const selectNotifications = (state: RootState) => state.priceDetails.notifications;

export default priceDetailsSlice.reducer;
