import React, { FC } from 'react'
import {
  Button,
  CheckboxControl,
  Notice,
  Snackbar,
} from '@wordpress/components'
import { createInterpolateElement } from '@wordpress/element'
import { Badge, Text } from '@wordpress/ui'
import HsCodeSelector from './HsCodeSelector'
import { OrderItem } from '../model/models'
import { useI18n } from '@wordpress/react-i18n'
import apiFetch from '@wordpress/api-fetch'

export declare interface CustomsInformationHsCodesProps {
  itemsMissingHsCode: Array<OrderItem>
  onCancel: () => void
  onSave: () => void
}

const CustomsInformationHsCodes: FC<CustomsInformationHsCodesProps> = ({
  itemsMissingHsCode,
  onCancel,
  onSave,
}) => {
  const [inProgress, setInProgress] = React.useState<boolean>(false)
  const [applyToAll, setApplyToAll] = React.useState<boolean>(false)
  const [updateFailed, setUpdateFailed] = React.useState<boolean>(false)
  const [hsCodeForAll, setHsCodeForAll] = React.useState<
    string | null | undefined
  >()
  const [updatedItems, setUpdatedItems] =
    React.useState<Array<OrderItem>>(itemsMissingHsCode)

  const { __ } = useI18n()

  const onSelectHsCode = (
    hsCode: string | null | undefined,
    item?: OrderItem
  ) => {
    setUpdatedItems(prevItems =>
      prevItems.map(prevItem => {
        if (item) {
          return prevItem.product_id === item.product_id
            ? {
                ...prevItem,
                hs_code: hsCode ?? undefined,
              }
            : prevItem
        } else {
          return itemsMissingHsCode.find(
            i => i.product_id === prevItem.product_id
          )
            ? {
                ...prevItem,
                hs_code: hsCode ?? undefined,
              }
            : prevItem
        }
      })
    )
  }

  const saveHsCodes = async () => {
    setInProgress(true)
    setUpdateFailed(false)
    await apiFetch({
      path: '/posten-bring-checkout/hscodes',
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(
        updatedItems.map(item => ({
          productId: item.product_id,
          hsCode: item.hs_code,
        }))
      ),
    })
      .then(() => {
        onSave()
      })
      .catch(() => setUpdateFailed(true))
      .finally(() => setInProgress(false))
  }

  // Stacked item images position calculation
  const imageSize = 55
  const maxSpread = 30
  const xStep =
    itemsMissingHsCode.length > 1
      ? maxSpread / (itemsMissingHsCode.length - 1)
      : 0
  const yStep =
    itemsMissingHsCode.length > 1 ? 24 / (itemsMissingHsCode.length - 1) : 0

  const stackWidth = imageSize + maxSpread
  const stackHeight = imageSize + 24

  return (
    <div>
      <Notice isDismissible={false} status="info" className="mbl">
        {createInterpolateElement(
          __(
            'For the fastest and most cost-effective shipping, shipments to Northern Norway are transported by rail through Sweden. Due to new EU regulations, these shipments now require customs information. Read more about new customs regulations for <link>Norwegian goods in transit (NVIT)</link>',
            'posten-bring-checkout'
          ),
          {
            link: (
              <a
                href="https://www.bring.no/tjenester/toll/endringer-norske-varer-i-transitt"
                target="_blank"
                rel="noopener noreferrer"
              />
            ),
          }
        )}
      </Notice>
      {itemsMissingHsCode.length > 1 && (
        <div className="mbm">
          <CheckboxControl
            onChange={checked => {
              setApplyToAll(checked)
              setHsCodeForAll(null)
            }}
            checked={applyToAll}
            label={__(
              'All items have the same HS code',
              'posten-bring-checkout'
            )}
          />
        </div>
      )}
      <div className="flex flex-dir-col gas mbl">
        {applyToAll && (
          <div className="pam item flex flex-dir-row gam align-ic">
            <div className="stacked-images">
              <div
                className="stacked-images-inner"
                style={{
                  width: `${stackWidth}px`,
                  height: `${stackHeight}px`,
                }}
              >
                {updatedItems
                  .filter(item =>
                    itemsMissingHsCode.find(
                      i => item.product_id === i.product_id
                    )
                  )
                  .slice(0, 4)
                  .map((item, index) => (
                    <img
                      key={item.product_id}
                      src={item.image_url}
                      style={{
                        left: `${index * xStep}px`,
                        top: `${index * yStep}px`,
                        zIndex: itemsMissingHsCode.length - index,
                      }}
                      alt=""
                      className="stacked-image"
                    />
                  ))}
              </div>
            </div>
            <div className="item-details">
              <Text variant="heading-lg">
                {__('All items', 'posten-bring-checkout')}
              </Text>
              <HsCodeSelector
                value={hsCodeForAll}
                onSelectHsCode={hsCode => {
                  setHsCodeForAll(hsCode)
                  onSelectHsCode(hsCode, undefined)
                }}
              />
            </div>
          </div>
        )}
        {!applyToAll &&
          updatedItems
            .filter(item =>
              itemsMissingHsCode.find(i => item.product_id === i.product_id)
            )
            .map(item => (
              <div
                className="pam item flex flex-dir-row gam align-ic"
                key={item.product_id}
              >
                <img
                  src={item.image_url}
                  alt={item.name}
                  className="item-image"
                />
                <div className="item-details">
                  <Text variant="heading-lg">{item.name}</Text>
                  <HsCodeSelector
                    value={item.hs_code}
                    onSelectHsCode={hsCode => onSelectHsCode(hsCode, item)}
                  />
                </div>
              </div>
            ))}
      </div>
      {updateFailed && (
        <Snackbar
          className="mbm"
          explicitDismiss
          politeness="assertive"
          onRemove={() => setUpdateFailed(false)}
        >
          {__(
            'An error occurred while saving HS codes. Please try again',
            'posten-bring-checkout'
          )}
        </Snackbar>
      )}
      <div className="flex flex-dir-row justify-csb">
        <div className="flex flex-dir-row gas">
          <Button
            variant="primary"
            __next40pxDefaultSize={true}
            isBusy={inProgress}
            onClick={() => saveHsCodes()}
          >
            {__('Save', 'posten-bring-checkout')}
          </Button>
          <Button
            variant="secondary"
            __next40pxDefaultSize={true}
            onClick={onCancel}
            disabled={inProgress}
          >
            {__('Cancel', 'posten-bring-checkout')}
          </Button>
        </div>
        <div>
          <Badge intent={'none'}>
            {__(
              'HS code data is provided by Tolletaten (Norwegian customs)',
              'posten-bring-checkout'
            )}
          </Badge>
        </div>
      </div>
    </div>
  )
}

export default CustomsInformationHsCodes
