import { FC, useContext, useEffect, useState } from 'react';
import {
  AppBar,
  Box,
  Button,
  Card,
  CardContent,
  makeStyles,
  Modal,
  Tab,
  Tabs,
  TextField,
  Theme,
  Typography,
} from '@material-ui/core';
import { Autocomplete } from '@material-ui/lab';
import FcCollapsibleText from '../../../../../components/core/FcCollapsibleText';
import FulfilmentPlans from './FulfilmentPlans';
import { QuantitySelector } from '../../../../../components/pick/QuantitySelector';
import { MultiOrder, MultiOrderItem, SplitItem } from './MultiBasketCollection';
import { useI18n } from 'mystique/hooks/useI18n';
import { useReturnSettingValue } from '../../../../../hooks/useReturnSettingValue';
import { orderTypesSettingName } from '../../../../../constants/SettingNames';
import { OrderType } from './CustomerAndOrderType';
import { useTemplateRender } from '../../../../../hooks/useTemplateRender';
import { CustomerAddress, MultiCustomerAddress } from 'interfaces/address';
import {
  FulfilmentCCPlanInterface,
  FulfilmentHDPlanInterface,
} from 'interfaces/fulfilmentPlans';
import { createFulfilmentPlans } from '../../../../../queries/createFulfilmentPlans';
import { useActiveRetailer } from '../../../../../hooks/useActiveRetailer';
import { CreateOrderContext } from '../CreateOrderContext';
import { CreateOrderInterface } from '../CreateOrder';
import _ from 'lodash';

interface MultiBasketCollectionItemProps {
  idx: number;
  item: MultiOrderItem;
  changeMultiOrder: (value: unknown, property?: string) => void;
  addNewMultiItem: (
    orderItem: MultiOrderItem,
    splitItem: SplitItem | undefined,
  ) => void;
  itemsQuantity: number;
}

const MultiBasketCollectionItem: FC<MultiBasketCollectionItemProps> = ({
  idx,
  item,
  changeMultiOrder,
  addNewMultiItem,
  itemsQuantity,
}) => {
  const [openSplitIdxModal, setSplitIdxModal] = useState(-1);
  const [openAddressIdxModal, setAddressIdxModal] = useState(-1);
  const [splitItem, setSplitItem] = useState<SplitItem>();
  const [fulfilmentPlans, setFulfilmentPlans] = useState<
    FulfilmentHDPlanInterface[] | FulfilmentCCPlanInterface[]
  >([]);
  const [tabIndex, setTabIndex] = useState(0);
  const [newAddress, setNewAddress] = useState<CustomerAddress>();
  const { createOrderInf, availableLocations: locations } =
    useContext(CreateOrderContext);
  const { multiOrder } = createOrderInf as CreateOrderInterface;
  const { customerAddresses } = multiOrder as MultiOrder;

  const classes = useStyles();

  const activeRetailer = useActiveRetailer();

  const { translate } = useI18n();

  const templateRender = useTemplateRender();

  const orderTypesValue = useReturnSettingValue(orderTypesSettingName);

  const orderTypes: OrderType[] = orderTypesValue?.map((type: OrderType) => {
    return {
      ...type,
      label: templateRender(type.label),
    };
  });

  useEffect(() => {
    if (item.deliveryAddressRef || item.orderItemType == 'CC') {
      setFulfilmentPlans([]);
      createFulfilmentPlans({
        deliveryAddress: customerAddresses.find(
          (address) => address.ref === item.deliveryAddressRef,
        ),
        orderType: item.orderItemType,
        activeRetailer: activeRetailer,
        products: [item],
      }).then((value) => {
        if (value) {
          changeMultiOrder(undefined, `orderItems[${idx}].fulfilmentPlanRef`);
          changeMultiOrder(value[0].fulfilmentOptionId, 'fulfilmentOptionId');
          setFulfilmentPlans(value);
        }
      });
    }
  }, [
    activeRetailer,
    item.orderItemType,
    itemsQuantity,
    item.deliveryAddressRef,
  ]);

  const handleTabChange = (_event: any, newValue: number) => {
    setTabIndex(newValue);
  };

  const handleOpenModal = (idx: number, typeModal: 'split' | 'address') => {
    if (typeModal === 'split') {
      setSplitIdxModal(idx);
    } else {
      setAddressIdxModal(idx);
    }
  };

  const handleCloseModal = () => {
    setSplitIdxModal(-1);
    setAddressIdxModal(-1);
  };

  const addSplitItem = (ref: string, idx: number, initialQuantity: number) => {
    setSplitItem({ ref, idx, quantity: initialQuantity });
  };

  const getHalfNumber = (number: number) => {
    return Math.floor(number / 2);
  };

  const removeSplitItem = () => {
    setSplitItem(undefined);
  };

  const addQuantityToSplitItem = (quantity: number) => {
    setSplitItem((prevState) => {
      if (!prevState) {
        return;
      }

      return {
        ...prevState,
        quantity,
      };
    });
  };

  const changeNewAddress = (value: string, property: string) => {
    setNewAddress((prevState: any) => {
      return prevState == undefined
        ? { [property]: value }
        : { ...prevState, [property]: value };
    });
  };

  const addNewAddressForCollection = () => {
    if (newAddress) {
      const newAddressRef = `Multi-${Math.random() * 100}`;
      const newMultiOrder = _.cloneDeep(multiOrder as MultiOrder);
      newMultiOrder.customerAddresses.push({
        ...newAddress,
        ref: newAddressRef,
      });
      newMultiOrder.orderItems[idx].deliveryAddressRef = newAddressRef;
      changeMultiOrder(newMultiOrder);
      setNewAddress(undefined);
    }
  };

  const changeItemAddress = () => {
    const addressRef = customerAddresses[tabIndex - 1].ref;
    changeMultiOrder(addressRef, `orderItems[${idx}].deliveryAddressRef`);
  };

  const handleSaveAddressBtn = () => {
    if (tabIndex === 0 && newAddress) {
      addNewAddressForCollection();
    } else {
      changeItemAddress();
    }

    setTabIndex(0);
    handleCloseModal();
  };

  const findCustomerAddress = (
    addresses: MultiCustomerAddress[],
    deliveryAddressRef?: string,
  ) => {
    return addresses.find((address) => address.ref === deliveryAddressRef);
  };

  return (
    <div className={classes.product}>
      <div className={classes.productContainer}>
        <img className={classes.productImg} src={item.imageUrl} alt="" />
        <div className={classes.productContainerText}>
          <div className={classes.productWrapper}>
            <Typography variant="body1" className={classes.productName}>
              {translate(
                'fc.se.field.create.order.multi.collection.items.product',
              )}
            </Typography>
            <Typography variant="body1" className={classes.productValue}>
              {item.name}
            </Typography>
          </div>
          <div className={classes.productWrapper}>
            <Typography variant="body1" className={classes.productName}>
              {translate(
                'fc.se.field.create.order.multi.collection.items.ref.no',
              )}
            </Typography>
            <Typography variant="body1" className={classes.productValue}>
              {item.ref}
            </Typography>
          </div>
          <div className={classes.productWrapper}>
            <Typography variant="body1" className={classes.productName}>
              {translate('fc.se.field.create.order.multi.collection.quantity')}
            </Typography>
            <Typography variant="body1" className={classes.productValue}>
              {item.quantity}
              <Button
                color="primary"
                disabled={item.quantity === 1}
                onClick={() => {
                  handleOpenModal(idx, 'split');
                  addSplitItem(item.ref, idx, getHalfNumber(item.quantity));
                }}
              >
                {translate(
                  'fc.se.field.create.order.multi.collection.split.btn',
                )}
              </Button>
            </Typography>
          </div>
        </div>
        <div className={classes.productContainerRow}>
          <Autocomplete
            fullWidth
            value={
              orderTypes?.find(
                (orderType) => orderType.value === item.orderItemType,
              ) || null
            }
            options={orderTypes}
            getOptionLabel={(option) => option.label}
            getOptionSelected={(option, value) => option.value === value.value}
            onChange={(_e, orderType) => {
              changeMultiOrder(
                orderType?.value,
                `orderItems[${idx}].orderItemType`,
              );
              changeMultiOrder('STANDARD', `orderItems[${idx}].deliveryType`);
            }}
            renderInput={(params) => (
              <TextField
                {...params}
                variant="standard"
                label={`${translate(
                  'fc.se.field.create.order.multi.collection.order.type.label',
                )} *`}
              />
            )}
          />
          {item.orderItemType == 'HD' && (
            <>
              {!!item.deliveryAddressRef && (
                <div>
                  <Typography variant="h4">
                    {translate(
                      'fc.se.field.create.order.multi.collection.address.title',
                    )}
                  </Typography>
                  <FcCollapsibleText
                    charCutoff={30}
                    text={`${
                      findCustomerAddress(
                        customerAddresses,
                        item.deliveryAddressRef,
                      )?.country || ''
                    } ${
                      findCustomerAddress(
                        customerAddresses,
                        item.deliveryAddressRef,
                      )?.state || ''
                    } ${
                      findCustomerAddress(
                        customerAddresses,
                        item.deliveryAddressRef,
                      )?.city || ''
                    } ${
                      findCustomerAddress(
                        customerAddresses,
                        item.deliveryAddressRef,
                      )?.postcode || ''
                    } ${
                      findCustomerAddress(
                        customerAddresses,
                        item.deliveryAddressRef,
                      )?.street || ''
                    }`}
                  />
                </div>
              )}
              <Button
                color="primary"
                onClick={() => {
                  handleOpenModal(idx, 'address');
                }}
              >
                {customerAddresses?.length
                  ? translate(
                    'fc.se.field.create.order.multi.collection.change.address',
                  )
                  : translate('fc.se.field.create.order.multi.collection.add.address')}
              </Button>
            </>
          )}
          {(!!item.deliveryAddressRef || item.orderItemType === 'CC') && (
            <FulfilmentPlans
              onChange={(value, property) => {
                changeMultiOrder(value, `orderItems[${idx}].[${property}]`);
              }}
              fulfilmentPlans={fulfilmentPlans}
              orderType={item.orderItemType}
              deliveryType={item.deliveryType}
              locations={locations}
              fulfilmentPlanRef={item.fulfilmentPlanRef}
              locationRef={item.pickupLocationRef}
            />
          )}
          {item.orderItemType == 'CC' &&
          item.deliveryType === 'STANDARD' &&
          locations?.length ? (
              <Autocomplete
                fullWidth
                options={locations}
                getOptionLabel={(option) =>
                  `${option.name}, ${option.postcode} (${option.ref})`
                }
                onChange={(_e, value) => {
                  changeMultiOrder(
                    value?.ref,
                    `orderItems[${idx}].pickupLocationRef`,
                  );
                }}
                value={
                  locations.find(
                    (location) => location.ref === item.pickupLocationRef,
                  ) || null
                }
                getOptionSelected={(option, value) => option.ref === value.ref}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    label={`${translate(
                      'fc.se.field.create.order.multi.collection.location',
                    )} *`}
                    variant="standard"
                  />
                )}
              />
            ) : null}
        </div>
      </div>
      <Modal
        className={classes.modal}
        open={openSplitIdxModal === idx}
        onClose={() => {
          handleCloseModal();
          removeSplitItem();
        }}
        aria-labelledby={`split-item-modal-${idx}`}
        aria-describedby={`split-item-modal-${idx}`}
      >
        <Card className={classes.modalContent}>
          <CardContent>
            <Typography variant="h3">
              {translate(
                'fc.se.field.create.order.multi.collection.split.item.label',
              )}
            </Typography>
            <QuantitySelector
              name={`quantity[${item.ref}-${idx}]`}
              label={''}
              value={getHalfNumber(item.quantity)}
              validation={{
                min: 1,
                max: item.quantity - 1,
              }}
              onChange={addQuantityToSplitItem}
              onBlur={() => ''}
            />
            <Button
              color="primary"
              variant="contained"
              className={classes.modalButton}
              onClick={() => {
                handleCloseModal();
                addNewMultiItem(item, splitItem);
                removeSplitItem();
              }}
            >
              {translate(
                'fc.se.field.create.order.multi.collection.split.done.btn',
              )}
            </Button>
          </CardContent>
        </Card>
      </Modal>
      <Modal
        className={classes.modal}
        open={openAddressIdxModal === idx}
        onClose={() => {
          handleCloseModal();
        }}
        aria-labelledby={`address-modal-${idx}`}
        aria-describedby={`address-modal-${idx}`}
      >
        <Card>
          <CardContent>
            <Typography variant="h3" align="center">
              {translate(
                'fc.se.field.create.order.multi.collection.address.modal',
              )}
            </Typography>
            <AppBar
              position="static"
              className={classes.appBar}
              color="default"
            >
              <Tabs
                value={tabIndex}
                onChange={handleTabChange}
                indicatorColor="primary"
                textColor="primary"
                variant="scrollable"
                scrollButtons="auto"
              >
                <Tab label="Add New" {...a11yProps(0)} />
                {customerAddresses.map((address, id) => (
                  <Tab
                    key={id}
                    label={`${
                      address.ref.includes('-dd-')
                        ? translate(
                          'fc.se.field.create.order.multi.collection.default.delivery.address',
                        )
                        : address.ref.includes('-dc-')
                          ? translate(
                            'fc.se.field.create.order.multi.collection.default.customer.address',
                          )
                          : address.street.length > 15
                            ? `${address.street.slice(0, 15)}...`
                            : address.street
                    }`}
                    {...a11yProps(id + 1)}
                  />
                ))}
              </Tabs>
            </AppBar>
            <TabPanel
              value={tabIndex}
              index={0}
              className={classes.modalContentAddress}
            >
              <TextField
                fullWidth
                label={`${translate(
                  'fc.se.field.create.order.multi.collection.address.form.street.label',
                )} *`}
                variant="standard"
                value={newAddress?.street}
                onChange={(event) => {
                  changeNewAddress(event.target.value, 'street');
                }}
              />
              <TextField
                fullWidth
                label={translate(
                  'fc.se.field.create.order.multi.collection.address.form.city.label',
                )}
                variant="standard"
                value={newAddress?.city}
                onChange={(event) => {
                  changeNewAddress(event.target.value, 'city');
                }}
              />
              <TextField
                fullWidth
                label={`${translate(
                  'fc.se.field.create.order.multi.collection.address.form.postcode.label',
                )} *`}
                variant="standard"
                value={newAddress?.postcode}
                onChange={(event) => {
                  changeNewAddress(event.target.value, 'postcode');
                }}
              />
              <TextField
                fullWidth
                label={translate(
                  'fc.se.field.create.order.multi.collection.address.form.state.label',
                )}
                variant="standard"
                value={newAddress?.state}
                onChange={(event) => {
                  changeNewAddress(event.target.value, 'state');
                }}
              />
              <TextField
                fullWidth
                label={`${translate(
                  'fc.se.field.create.order.multi.collection.address.form.country.label',
                )} *`}
                variant="standard"
                value={newAddress?.country}
                onChange={(event) => {
                  changeNewAddress(event.target.value, 'country');
                }}
              />
            </TabPanel>
            {customerAddresses.map((address, id) => (
              <TabPanel value={tabIndex} index={id + 1} key={id}>
                <TextField
                  fullWidth
                  label={`${translate(
                    'fc.se.field.create.order.multi.collection.address.form.street.label',
                  )} *`}
                  variant="standard"
                  value={address?.street}
                  disabled
                />
                <TextField
                  fullWidth
                  label={translate(
                    'fc.se.field.create.order.multi.collection.address.form.city.label',
                  )}
                  variant="standard"
                  value={address?.city}
                  disabled
                />
                <TextField
                  fullWidth
                  label={`${translate(
                    'fc.se.field.create.order.multi.collection.address.form.postcode.label',
                  )} *`}
                  variant="standard"
                  value={address?.postcode}
                  disabled
                />
                <TextField
                  fullWidth
                  label={translate(
                    'fc.se.field.create.order.multi.collection.address.form.state.label',
                  )}
                  variant="standard"
                  value={address?.state}
                  disabled
                />
                <TextField
                  fullWidth
                  label={`${translate(
                    'fc.se.field.create.order.multi.collection.address.form.country.label',
                  )} *`}
                  variant="standard"
                  value={address?.country}
                  disabled
                />
              </TabPanel>
            ))}
            <div className={classes.modalButtons}>
              <Button variant="contained" onClick={handleCloseModal}>
                {translate(
                  'fc.se.field.create.order.multi.collection.address.close.btn',
                )}
              </Button>
              <Button
                color="primary"
                variant="contained"
                onClick={handleSaveAddressBtn}
                disabled={
                  !(
                    tabIndex === 0 &&
                    newAddress?.street &&
                    newAddress?.postcode &&
                    newAddress?.country
                  )
                }
              >
                {translate(
                  'fc.se.field.create.order.multi.collection.address.save.btn',
                )}
              </Button>
            </div>
          </CardContent>
        </Card>
      </Modal>
    </div>
  );
};

function TabPanel(props: any) {
  const { children, value, index, ...other } = props;

  return (
    <div
      role="tabpanel"
      hidden={value !== index}
      id={`simple-tabpanel-${index}`}
      aria-labelledby={`simple-tab-${index}`}
      {...other}
    >
      {value === index && (
        <Box p={3}>
          <Typography>{children}</Typography>
        </Box>
      )}
    </div>
  );
}

function a11yProps(index: number) {
  return {
    id: `scrollable-auto-tab-${index}`,
    'aria-controls': `scrollable-auto-tabpanel-${index}`,
  };
}

const useStyles = makeStyles((theme: Theme) => ({
  fullWidth: {
    width: '100%',
  },
  appBar: {
    backgroundColor: 'transparent',
    marginTop: '10px',
    boxShadow: 'none',
  },
  product: {
    padding: '24px 22px',
    border: `2px solid ${theme.palette.divider}`,
    borderBottom: 'none',
    width: '100%',
    boxSizing: 'border-box',
    position: 'relative',
    '&:last-child': {
      borderBottom: `2px solid ${theme.palette.divider}`,
    },
  },
  productImg: {
    width: '80px',
  },
  productContainer: {
    display: 'flex',
    alignItems: 'flex-start',
    justifyContent: 'space-between',
    flexWrap: 'wrap',
  },
  productContainerText: {
    width: '70%',
  },
  productContainerRow: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'flex-start',
    width: '100%',
    gap: '15px',
  },
  productWrapper: {
    display: 'grid',
    alignItems: 'center',
    gridGap: '10px',
    paddingTop: '0.8em',
    gridTemplateAreas: '"productName productValue"',
    gridTemplateColumns: '1fr 2fr',
  },
  productName: {
    color: theme.palette.text.secondary,
    gridArea: '"productName"',
    fontSize: '13px',
  },
  productValue: {
    fontSize: '13px',
    lineHeight: 1.2,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between',
    '& p:nth-of-type(2)': {
      color: '#4CAF50',
    },
  },
  modal: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    maxWidth: '500px',
    margin: '0 auto',
  },
  modalRow: {
    display: 'flex',
    alignItems: 'center',
    flexWrap: 'wrap',
  },
  modalButtons: {
    marginTop: '15px',
    display: 'flex',
    justifyContent: 'space-between',
    width: '100%',
  },
  modalButton: {
    marginTop: '15px',
    marginLeft: 'auto',
    display: 'block',
    width: '100%',
  },
  modalContent: {
    minWidth: '300px',
  },
  modalContentAddress: {
    display: 'flex',
    flexDirection: 'column',
    gap: '10px',
    alignItems: 'flex-start',
  },
}));

export default MultiBasketCollectionItem;