import { pick } from 'lodash';

import { PartialNullableObject } from '../../types/utilTypes';
import {
  REST_LineItem as RESTLineItem, REST_Order,
} from '../../types/ShopifyAdminREST';

import { ShopifyObjectModel } from './ShopifyObject';

/**
 * created_at and updated_at are useful when calculating desync by values since
 * line items have neither
 */
const OrderSummaryKeys = [
  'id',
  'name',
  'created_at',
  'updated_at',
  'admin_graphql_api_id',
] as const;
type OrderSummaryKeys = typeof OrderSummaryKeys[number];

export type LineItemQueryResult = RESTLineItem & {
  order: OrderSummary;
};

export type OrderSummary = Pick<REST_Order, OrderSummaryKeys>;

export function getOrderSummary(order:REST_Order):OrderSummary {
  return pick(order, OrderSummaryKeys);
}

export const OmittedLineItemKeys = [
  // Can't be derived from GQL (at least no direct way to do so)
  'fulfillable_quantity',

  'origin_location',
  'fulfillment_service',
  'fulfillment_status',

  // Omitted since we're updating the type from REST number to GQL string
  'id',
  'price_set',
  'total_discount_set',
  'duties',
  'discount_allocations',
  'tax_lines',

  // Not including these since they're not available on the GraphQL LineItem
  'tip_payment_gateway',
  'tip_payment_method', 'admin_graphql_api_id'
] as const;
export type OmittedLineItemKey = typeof OmittedLineItemKeys[number];

type RemainingLineItemKey = Exclude<keyof RESTLineItem, OmittedLineItemKey>;
const RemainingLineItemKeysRecord:Record<RemainingLineItemKey, undefined> = {
  gift_card: undefined,
  grams: undefined,
  name: undefined,
  price: undefined,
  product_id: undefined,
  properties: undefined,
  quantity: undefined,
  requires_shipping: undefined,
  sku: undefined,
  taxable: undefined,
  title: undefined,
  total_discount: undefined,
  variant_id: undefined,
  variant_title: undefined,
  vendor: undefined,
};
const RemainingLineItemKeys = Object.keys(RemainingLineItemKeysRecord) as readonly RemainingLineItemKey[];

const NewLineItemKeys = [
  'order_id',
  'order',
  'tax_lines_json',
  'id',
  'variant',
  'duties_json',
  'discount_allocations_json',
  'total_grams',

  // price * quantity
  'total_item_price'
] as const;

type NewLineItemKeys = typeof NewLineItemKeys[number];
type LineItemProps = Omit<RESTLineItem, OmittedLineItemKey> & {
  tax_lines_json: RESTLineItem['tax_lines'];
  duties_json: RESTLineItem['duties'];
  discount_allocations_json: RESTLineItem['discount_allocations'];
  total_grams: number;
  total_item_price: RESTLineItem['price'];

  // This will be a related field
  variant: RESTLineItem['variant_id'];
  order_id: string;
  order: OrderSummary;
  id: string;
};

export const LineItemKeys = [
  ...RemainingLineItemKeys,
  ...NewLineItemKeys
] as const;

/**
 * Most of these are nullable if the related product / variant DNE
 * Will be present in the REST object but if being converted 
 */
const NullablePropKeys = [
  'grams',
  'name',
  'price',
  'product_id',
  'sku',
  'title',
  'variant_id',
  'variant_title',
  'variant',
  'total_grams',
  'total_item_price',

  // Optional prop
  'vendor'
] as const;
type NullablePropKey = typeof NullablePropKeys[number];

export type LineItemKey = (typeof LineItemKeys)[number];

export const LineItemTypeName = 'line_items';
export type LineItemTypeName = typeof LineItemTypeName;

export interface LineItem extends ShopifyObjectModel {
  type: LineItemTypeName;
  props: PartialNullableObject<LineItemProps, NullablePropKey>;
}