import type {BaseResponse} from '../baseTypes';

export interface CreateInboundShipmentPlanBody {
  ShipFromAddress: Address;
  LabelPrepPreference: LabelPrepPreference;
  ShipToCountryCode?: string;
  ShipToCountrySubdivisionCode?: string;
  InboundShipmentPlanRequestItems: InboundShipmentPlanRequestItem[];
}

export interface CreateInboundShipmentPlanResponse extends BaseResponse {
  payload?: {
    InboundShipmentPlans: InboundShipmentPlan[];
  };
}

interface BasePath {
  shipmentId: string;
}

export interface UpdateInboundShipmentPath extends BasePath {}

export interface UpdateInboundShipmentResponse extends BaseResponse {
  payload?: {
    ShipmentId: string;
  };
}

export interface CreateInboundShipmentPath extends BasePath {}

export interface CreateInboundShipmentResponse extends UpdateInboundShipmentResponse {}

export interface GetPreorderInfoPath extends BasePath {}

export interface GetPreorderInfoQuery {
  MarketplaceId: string;
}

export interface GetPreorderInfoResponse extends BaseResponse {
  payload?: GetPreorderInfoResult;
}

export interface ConfirmPreorderPath {
  shipmentId: string;
}

export interface ConfirmPreorderQuery {
  NeedByDate: string;
  MarketplaceId: string;
}

export interface ConfirmPreorderResponse extends BaseResponse {
  payload?: ConfirmPreorderResult;
}

export interface GetPrepInstructionsQuery {
  ShipToCountryCode: string;
  SellerSKUList?: string[];
  ASINList?: string[];
}

export interface GetPrepInstructionsResponse extends BaseResponse {
  payload?: GetPrepInstructionsResult;
}

interface GetPrepInstructionsResult {
  SKUPrepInstructionsList?: SKUPrepInstructions[];
  InvalidSKUList?: InvalidSKU[];
  ASINPrepInstructionsList?: ASINPrepInstructions[];
  InvalidASINList?: InvalidASIN[];
}

interface InvalidASIN {
  ASIN?: string;
  ErrorReason?: ErrorReason;
}

interface SKUPrepInstructions {
  SellerSKU?: string;
  ASIN?: string;
  BarcodeInstruction?: BarcodeInstruction;
  PrepGuidance?: PrepGuidance;
  PrepInstructionList?: PrepInstruction[];
  AmazonPrepFeesDetailsList?: AmazonPrepFeesDetails[];
}

interface AmazonPrepFeesDetails {
  PrepInstruction?: PrepInstruction;
  FeePerUnit?: Amount;
}

interface ASINPrepInstructions {
  ASIN?: string;
  BarcodeInstruction?: BarcodeInstruction;
  PrepGuidance?: PrepGuidance;
  PrepInstructionList?: PrepInstruction[];
}

type BarcodeInstruction = 'RequiresFNSKULabel' | 'CanUseOriginalBarcode' | 'MustProvideSellerSKU';
type PrepGuidance = 'ConsultHelpDocuments' | 'NoAdditionalPrepRequired' | 'SeePrepInstructionsList';

type SellerFreightClass =
  | '50'
  | '55'
  | '60'
  | '65'
  | '77.5'
  | '85'
  | '92.5'
  | '100'
  | '110'
  | '125'
  | '150'
  | '175'
  | '200'
  | '250'
  | '300'
  | '400'
  | '500';

interface ConfirmPreorderResult {
  ConfirmedNeedByDate?: string;
  ConfirmedFulfillableDate?: string;
}

interface GetPreorderInfoResult {
  ShipmentContainsPreorderableItems?: boolean;
  ShipmentConfirmedForPreorder?: boolean;
  NeedByDate?: string;
  ConfirmedFulfillableDate?: string;
}

type ErrorReason = 'DoesNotExist' | 'InvalidASIN';

interface InvalidSKU {
  SellerSKU?: string;
  ErrorReason?: ErrorReason;
}

interface InvalidASIN {
  ASIN?: string;
  ErrorReason?: ErrorReason;
}

interface Address {
  Name: string;
  AddressLine1: string;
  AddressLine2?: string;
  DistrictOrCounty?: string;
  City: string;
  StateOrProvinceCode: string;
  CountryCode: string;
  PostalCode: string;
}

type LabelPrepPreference = 'SELLER_LABEL' | 'AMAZON_LABEL_ONLY' | 'AMAZON_LABEL_PREFERRED';

interface InboundShipmentPlanRequestItem {
  SellerSKU: string;
  ASIN: string;
  Condition: Condition;
  Quantity: number;
  QuantityInCase: number;
  PrepDetailsList: PrepDetails[];
}

type Condition =
  | 'NewItem'
  | 'NewWithWarranty'
  | 'NewOEM'
  | 'NewOpenBox'
  | 'UsedLikeNew'
  | 'UsedVeryGood'
  | 'UsedGood'
  | 'UsedAcceptable'
  | 'UsedPoor'
  | 'UsedRefurbished'
  | 'CollectibleLikeNew'
  | 'CollectibleVeryGood'
  | 'CollectibleGood'
  | 'CollectibleAcceptable'
  | 'CollectiblePoor'
  | 'RefurbishedWithWarranty'
  | 'Refurbished'
  | 'Club';

interface PrepDetails {
  PrepInstruction: PrepInstruction;
  PrepOwner: PrepOwner;
}

type PrepInstruction = 'Polybagging' | 'BubbleWrapping' | 'Taping' | 'BlackShrinkWrapping' | 'Labeling' | 'HangGarment';

type PrepOwner = 'AMAZON' | 'SELLER';

interface InboundShipmentPlan {
  ShipmentId: string;
  DestinationFulfillmentCenterId: string;
  ShipToAddress: Address;
  LabelPrepType: LabelPrepType;
  Items: InboundShipmentPlanItem[];
  EstimatedBoxContentsFee?: BoxContentsFeeDetails;
}

type LabelPrepType = 'NO_LABEL' | 'SELER_LABEL' | 'AMAZON_LABEL';

interface InboundShipmentPlanItem {
  SellerSKU: string;
  FulfillmentNetworkSKU: string;
  Quantity: number;
  PrepDetailsList?: PrepDetails[];
}

interface BoxContentsFeeDetails {
  TotalUnits?: number;
  FeePerUnit?: Amount;
  TotalFee?: Amount;
}

interface Amount {
  CurrencyCode: 'USD' | 'GBP';
  Value: number;
}

export interface CreateInboundShipmentBody {
  InboundShipmentHeader: InboundShipmentHeader;
  InboundShipmentItems: InboundShipmentItem[];
  MarketplaceId: string;
}

export interface UpdateInboundShipmentBody {
  InboundShipmentHeader: InboundShipmentHeader;
  InboundShipmentItems: InboundShipmentItem[];
  MarketplaceId: string;
}

interface InboundShipmentHeader {
  ShipmentName: string;
  ShipFromAddress: Address;
  DestinationFulfillmentCenterId: string;
  AreCasesRequired?: boolean;
  ShipmentStatus: ShipmentStatus;
  LabelPrepPreference: LabelPrepPreference;
  IntendedBoxContentsSource?: IntendedBoxContentsSource;
}

type ShipmentStatus =
  | 'WORKING'
  | 'SHIPPED'
  | 'RECEIVING'
  | 'CANCELLED'
  | 'DELETED'
  | 'CLOSED'
  | 'ERROR'
  | 'IN_TRANSIT'
  | 'DELIVERED'
  | 'CHECKED_IN';

type IntendedBoxContentsSource = 'NONE' | 'FEED' | '2D_BARCODE';

interface InboundShipmentItem {
  ShipmentId?: string;
  SellerSKU: string;
  FulfillmentNetworkSKU?: string;
  QuantityShipped?: number;
  QuantityReceived?: number;
  QuantityInCase?: number;
  ReleaseDate?: string;
  PrepDetailsList?: PrepDetails[];
}

export interface PutTransportDetailsPath extends BasePath {}

export interface PutTransportDetailsBody {
  IsPartnered: boolean;
  ShipmentType: ShipmentType;
  TransportDetails: TransportDetailInput;
}

type ShipmentType = 'SP' | 'LTL';

interface TransportDetailInput {
  PartneredSmallParcelData?: PartneredSmallParcelDataInput;
  NonPartneredSmallParcelData?: NonPartneredSmallParcelDataInput;
  PartneredLtlData?: PartneredLtlDataInput;
  NonPartneredLtlData?: NonPartneredLtlDataInput;
}

interface PartneredSmallParcelDataInput {
  PackageList?: PartneredSmallParcelPackageInput[];
  CarrierName?: string;
}

interface PartneredSmallParcelPackageInput {
  Dimensions: Dimensions;
  Weight: Weight;
}

interface NonPartneredSmallParcelDataInput {
  CarrierName: string;
  PackageList: NonPartneredSmallParcelPackageInput[];
}

interface NonPartneredSmallParcelPackageInput {
  TrackingId: string;
}

interface PartneredLtlDataInput {
  Contact?: Contact;
  BoxCount?: number;
  SellerFreightClass?: SellerFreightClass;
  FreightReadyDate?: string;
  PalletList?: Pallet[];
  TotalWeight?: Weight;
  SellerDeclaredValue: Amount;
}

interface NonPartneredLtlDataInput {
  CarrierName: string;
  ProNumber: string;
}

interface Dimensions {
  Length: number;
  Width: number;
  Height: number;
  Unit: UnitOfMeasurement;
}

type UnitOfMeasurement = 'inches' | 'centimeters';

interface Weight {
  Value: number;
  Unit: UnitOfWeight;
}

type UnitOfWeight = 'pounds' | 'kilograms';

interface Contact {
  Name: string;
  Phone: string;
  Email: string;
  Fax?: string;
}

interface Pallet {
  Dimensions: Dimensions;
  Weight?: Weight;
  IsStacked: boolean;
}

export interface PutTransportDetailsResponse extends BaseResponse {
  payload?: CommonTransportResult;
}

interface CommonTransportResult {
  TransportResult?: TransportResult;
}

interface TransportResult {
  TransportStatus: TransportStatus;
  ErrorCode?: string;
  ErrorDescription?: string;
}

type TransportStatus =
  | 'WORKING'
  | 'ESTIMATING'
  | 'ESTIMATED'
  | 'ERROR_ON_ESTIMATING'
  | 'CONFIRMING'
  | 'CONFIRMED'
  | 'ERROR_ON_CONFIRMING'
  | 'VOIDING'
  | 'VOIDED'
  | 'ERROR_IN_VOIDING'
  | 'ERROR';

export interface GetTransportDetailsPath extends BasePath {}

export interface GetTransportDetailsResponse extends BaseResponse {
  payload?: GetTransportDetailsResult;
}

interface GetTransportDetailsResult {
  TransportContent?: TransportContent;
}

interface TransportContent {
  TransportHeader: TransportHeader;
  TransportDetails: TransportDetailOutput;
  TransportResult: TransportResult;
}

interface TransportHeader {
  SellerId: string;
  ShipmentId: string;
  IsPartnered: string;
  ShipmentType: ShipmentType;
}

interface TransportDetailOutput {
  PartneredSmallParcelData?: PartneredSmallParcelDataOutput;
  NonPartneredSmallParcelData?: NonPartneredSmallParcelDataOutput;
  PartneredLtlData?: PartneredLtlDataOutput;
  NonPartneredLtlData?: NonPartneredLtlDataOutput;
}

interface PartneredSmallParcelDataOutput {
  PackageList: PartneredSmallParcelPackageOutput[];
  PartneredEstimate?: PartneredEstimate;
}

interface PartneredSmallParcelPackageOutput {
  Dimensions: Dimensions;
  Weight: Weight;
  CarrierName: string;
  TrackingId: string;
  PackageStatus: PackageStatus;
}

interface PartneredEstimate {
  Amount: Amount;
  ConfirmDeadline?: string;
  VoidDeadline?: string;
}

interface NonPartneredSmallParcelDataOutput {
  PackageList: NonPartneredSmallParcelPackageOutput[];
}

interface NonPartneredSmallParcelPackageOutput {
  CarrierName: string;
  TrackingId: string;
  PackageStatus: PackageStatus;
}

interface PartneredLtlDataOutput {
  Contact: Contact;
  BoxCount: number;
  SellerFreightClass?: SellerFreightClass;
  FreightReadyDate: string;
  PalletList: Pallet[];
  TotalWeight: Weight;
  SellerDeclaredValue?: Amount;
  AmazonCalculatedValue?: Amount;
  PreviewPickupDate: string;
  PreviewDeliveryDate: string;
  PreviewFreightClass: SellerFreightClass;
  AmazonReferenceId: string;
  IsBillOfLadingAvailable: boolean;
  PartneredEstimate?: PartneredEstimate;
  CarrierName: string;
}

interface NonPartneredLtlDataOutput {
  CarrierName: string;
  ProNumber: string;
}

type PackageStatus = 'SHIPPED' | 'IN_TRANSIT' | 'DELIVERED' | 'CHECKED_IN' | 'RECEIVING' | 'CLOSED' | 'DELETED';

export interface VoidTransportPath extends BasePath {}

export interface VoidTransportResponse extends BaseResponse {
  payload?: CommonTransportResult;
}

export interface EstimateTransportPath extends BasePath {}

export interface EstimateTransportResponse extends BaseResponse {
  payload?: CommonTransportResult;
}

export interface ConfirmTransportPath extends BasePath {}

export interface ConfirmTransportResponse extends BaseResponse {
  payload?: CommonTransportResult;
}

export interface GetLabelsPath extends BasePath {}

export interface GetLabelsQuery {
  PageType: PageType;
  LabelType: LabelType;
  NumberOfPackages?: number;
  PackageLabelsToPrint?: string[];
  NumberOfPallets?: number;
  PageSize?: number;
  PageStartIndex?: number;
}

type PageType =
  | 'PackageLabel_Letter_2'
  | 'PackageLabel_Letter_4'
  | 'PackageLabel_Letter_6'
  | 'PackageLabel_Letter_6_CarrierLeft'
  | 'PackageLabel_A4_2'
  | 'PackageLabel_A4_4'
  | 'PackageLabel_Plain_Paper'
  | 'PackageLabel_Plain_Paper_CarrierBottom'
  | 'PackageLabel_Thermal'
  | 'PackageLabel_Thermal_Unified'
  | 'PackageLabel_Thermal_NonPCP'
  | 'PackageLabel_Thermal_No_Carrier_Rotation';

type LabelType = 'BARCODE_2D' | 'UNIQUE' | 'PALLET';

export interface GetLabelsResponse extends BaseResponse {
  payload?: LabelDownloadURL;
}

interface LabelDownloadURL {
  DownloadURL?: string;
}

export interface GetBillOfLadingPath extends BasePath {}

export interface GetBillOfLadingResponse extends BaseResponse {
  payload?: BillOfLadingDownloadURL;
}

interface BillOfLadingDownloadURL {
  DownloadURL?: string;
}

export interface GetShipmentsQuery {
  ShipmentStatusList?: ShipmentStatusList[];
  ShipmentIdList?: string[];
  LastUpdatedAfter?: string;
  LastUpdatedBefore?: string;
  QueryType: GetShipmentsQueryType;
  NextToken?: string;
  MarketplaceId: string;
}

export interface GetShipmentsResponse extends BaseResponse {
  payload?: GetShipmentsResult;
}

type ShipmentStatusList =
  | 'WORKING'
  | 'SHIPPED'
  | 'RECEIVING'
  | 'CANCELLED'
  | 'DELETED'
  | 'CLOSED'
  | 'ERROR'
  | 'IN_TRANSIT'
  | 'DELIVERED'
  | 'CHECKED_IN';

type GetShipmentsQueryType = 'SHIPMENT' | 'DATE_RANGE' | 'NEXT_TOKEN';

interface GetShipmentsResult {
  ShipmentData?: InboundShipmentInfo[];
  NextToken?: string;
}

interface InboundShipmentInfo {
  ShipmentId?: string;
  ShipmentName?: string;
  ShipFromAddress: Address;
  DestinationFulfillmentCenterId?: string;
  ShipmentStatus?: ShipmentStatus;
  LabelPrepType?: LabelPrepType;
  AreCasesRequired: boolean;
  ConfirmedNeedByDate?: string;
  BoxContentsSource?: BoxContentsSource;
  EstimatedBoxContentsFee?: BoxContentsFeeDetails;
}

type BoxContentsSource = 'NONE' | 'FEED' | '2D_BARCODE' | 'INTERACTIVE';

interface BoxContentsFeeDetails {
  TotalUnits?: number;
  FeePerUnit?: Amount;
  TotalFee?: Amount;
}

export interface GetShipmentItemsByShipmentIdPath extends BasePath {}

export interface GetShipmentItemsByShipmentIdQuery {
  MarketplaceId: string;
}

export interface GetShipmentItemsByShipmentIdResponse extends BaseResponse {
  payload?: GetShipmentItemsResult;
}

interface GetShipmentItemsResult {
  ItemData?: InboundShipmentItem[];
  NextToken?: string;
}

export interface GetShipmentItemsQuery {
  LastUpdatedAfter?: string;
  LastUpdatedBefore?: string;
  QueryType: GetShipmentItemsQueryType;
  NextToken?: string;
  MarketplaceId: string;
}

export interface GetShipmentItemsResponse extends BaseResponse {
  payload?: GetShipmentItemsResult;
}

type GetShipmentItemsQueryType = 'DATE_RANGE' | 'NEXT_TOKEN';
