import { types } from '../../util/sdkLoader';
import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
import { updatedEntities, denormalisedEntities } from '../../util/data';

// ================ Action types ================ //

export const FETCH_ORDER_REQUEST = 'app/InboxPage/FETCH_ORDER_REQUEST';
export const FETCH_ORDER_SUCCESS = 'app/InboxPage/FETCH_ORDER_SUCCESS';
export const FETCH_ORDER_ERROR = 'app/InboxPage/FETCH_ORDER_ERROR';

// ================ Reducer ================ //

const initialState = {
  fetchInProgress: false,
  fetchOrderError: null,
  transactionRef: null,
};

export default function checkoutPageReducer(state = initialState, action = {}) {
  const { type, payload } = action;
  switch (type) {
    case FETCH_ORDER_REQUEST:
      return { ...state, fetchInProgress: true, fetchOrderError: null };
    case FETCH_ORDER_SUCCESS: {
      const transactionRef = { id: payload.data.data.id, type: 'transaction' };
      return { ...state, fetchInProgress: false, transactionRef };
    }
    case FETCH_ORDER_ERROR:
      console.error(payload); // eslint-disable-line
      return { ...state, fetchInProgress: false, fetchOrderError: payload };

    default:
      return state;
  }
}

// ================ Action creators ================ //

const fetchOrderRequest = () => ({ type: FETCH_ORDER_REQUEST });
const fetchOrderSuccess = response => ({ type: FETCH_ORDER_SUCCESS, payload: response });
const fetchOrderError = e => ({ type: FETCH_ORDER_ERROR, error: true, payload: e });

// ================ Thunks ================ //

const listingRelationship = txResponse => {
  return txResponse.data.data.relationships.listing.data;
};

export const fetchOrder = id =>
  (dispatch, getState, sdk) => {
    dispatch(fetchOrderRequest());

    let txResponse = null;

    return sdk.transactions
      .show({ id, include: ['customer', 'provider', 'listing', 'booking'] }, { expand: true })
      .then(response => {
        txResponse = response;
        const listingId = listingRelationship(response).id;
        const entities = updatedEntities({}, response.data);
        const denormalised = denormalisedEntities(entities, 'listing', [listingId]);
        const listing = denormalised[0];

        const canFetchListing = listing && listing.attributes && !listing.attributes.deleted;

        if (canFetchListing) {
          return sdk.listings.show({
            id: listingId,
            include: ['author', 'author.profileImage', 'images'],
          });
        } else {
          return response;
        }
      })
      .then(response => {
        dispatch(addMarketplaceEntities(txResponse));
        dispatch(addMarketplaceEntities(response));
        dispatch(fetchOrderSuccess(txResponse));

        return response;
      })
      .catch(e => {
        dispatch(fetchOrderError(e));
        throw e;
      });
  };

// loadData is a collection of async calls that need to be made
// before page has all the info it needs to render itself
export const loadData = params =>
  dispatch => {
    const orderId = new types.UUID(params.id);

    // Order (i.e. transaction entity in API, but from buyers perspective) contains order details
    return dispatch(fetchOrder(orderId));
  };
