import { CustomerAddress } from 'interfaces/address';
import {
  FulfilmentCCPlanInterface,
  FulfilmentHDPlanInterface,
  FulfilmentOptionResult,
} from 'interfaces/fulfilmentPlans';
import { getQuery } from 'mystique/hooks/getQuery';
import uuid from 'react-uuid';
import { OrderItem } from '../forms/fields/order/СreateOrder/CreateOrder';

const createFulfilmentPlansMutation = `
mutation createFulfilmentOption(
  $products: [CreateFulfilmentOptionProductInput]!
  $orderType: String!
  $retailerId: Int!
  $type: String!
  $uuid: String!
  $address: CreateFulfilmentOptionAddressInput
  $locationRef: String
) {
  createFulfilmentOption(
    input: {
      ref: $uuid
      type: $type
      orderType: $orderType
      retailerId: $retailerId
      address: $address
      locationRef: $locationRef
      products: $products
    }
    executionMode: AWAIT_ORCHESTRATION
  ) {
    id
    plans {
      edges {
        node {
          ref
          status
          eta
          type
          attributes {
            name
            type
            value
          }
          fulfilments {
            fulfilmentType
            locationRef
            items {
              productRef
              availableQuantity
              requestedQuantity
            }
          }
        }
      }
    }
  }
}
`;

interface CreateFulfilmentPlansProps {
  deliveryAddress: CustomerAddress | undefined;
  orderType: string;
  pickupLocationRef?: string | undefined;
  activeRetailer: string | undefined;
  products: OrderItem[];
}

export const createFulfilmentPlans = ({
  deliveryAddress,
  pickupLocationRef,
  orderType,
  activeRetailer,
  products,
}: CreateFulfilmentPlansProps) => {
  const deliveryAddressForQuery = deliveryAddress
    ? {
      state: deliveryAddress?.state || '.',
      city: deliveryAddress?.city || '.',
      country: deliveryAddress?.country || '.',
      postcode: deliveryAddress?.postcode,
    }
    : undefined;

  return getQuery<FulfilmentOptionResult>(createFulfilmentPlansMutation, {
    uuid: `App-${uuid()}`,
    type: orderType, // TODO type of FulfilmentOption entity (for example, DEFAULT or HD/CC (orderType))
    orderType: orderType,
    retailerId: activeRetailer,
    address: deliveryAddressForQuery,
    locationRef: pickupLocationRef,
    products: products.map((product) => {
      return {
        productRef: product.ref,
        requestedQuantity: product.quantity,
      };
    }),
  })
    .then((resp) => {
      if (resp.data?.createFulfilmentOption) {
        let plans:
          | FulfilmentHDPlanInterface[]
          | FulfilmentCCPlanInterface[] = [];
        if (orderType === 'HD') {
          plans = resp.data?.createFulfilmentOption.plans.edges.map((plan) => {
            return {
              deliveryType: plan.node.attributes?.byName?.deliveryType.toUpperCase(),
              carrier: plan.node.attributes?.byName.carrier,
              eta: plan.node.eta,
              ref: plan.node.ref,
              pickUpLocation: plan.node.fulfilments[0].locationRef,
            };
          });
        }
        if (orderType === 'CC') {
          plans = [
            {
              deliveryType: 'STANDARD',
            },
          ];

          if (resp.data?.createFulfilmentOption.plans.edges.length) {
            plans.push({
              deliveryType: 'EXPRESS',
              locations: resp.data.createFulfilmentOption.plans.edges[0].node.fulfilments
                .filter(
                  (fulfilment) =>
                    fulfilment.items.length === products.length,
                )
                .map((fulfilment) => fulfilment.locationRef),
            });
          }
        }

        plans.forEach(plan => plan.fulfilmentOptionId = resp.data?.createFulfilmentOption.id);

        return plans.length ? plans : [{
          deliveryType: 'STANDARD',
          fulfilmentOptionId: resp.data?.createFulfilmentOption.id,
        }];
      }
      return;
    });
};
