import type { FC } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import { ListBox, Sidecar } from '@theorchard/suite-components';
import { CountryFlag } from '@theorchard/suite-icons';
import { useDeliveryRestrictionsContext } from 'src/components/deliveryRestrictionsContext';
import {
    ContextStore,
    ContextTerritory,
    DELIVERY_TYPES,
    RestrictionLevel,
} from 'src/components/deliveryRestrictionsContext/types';

export const INTL_PREFIX = 'contentReview.restrictFurtherSidecar';
export const CLASS_NAME = 'RestrictFurtherSidecar';

const getDeliveryType = (restrictionType: string | null) =>
    restrictionType === 'service'
        ? DELIVERY_TYPES.STORES
        : DELIVERY_TYPES.TERRITORIES;

const isLockedByAccount = (delivery: ContextStore | ContextTerritory) =>
    !delivery.isDelivering &&
    delivery.restrictedAtLevel.some(level =>
        [RestrictionLevel.Account, RestrictionLevel.Subaccount].includes(level)
    );

interface RestrictionOption {
    label: string;
    value: string;
    levels: RestrictionLevel[];
}

export interface RestrictFurtherSidecarProps {
    isOpen: boolean;
    restrictionType: string | null;
    onClose: () => void;
}

const RestrictFurtherSidecar: FC<RestrictFurtherSidecarProps> = ({
    isOpen,
    restrictionType,
    onClose,
}) => {
    const { stores, territories, restrictProductLevel } =
        useDeliveryRestrictionsContext();

    const [selectedIds, setSelectedIds] = useState<string[]>([]);

    const deliveryType = getDeliveryType(restrictionType);

    const options = useMemo(() => {
        if (deliveryType === DELIVERY_TYPES.STORES)
            return stores.filter(isLockedByAccount).map(store => ({
                label: store.name,
                value: store.id,
                levels: store.restrictedAtLevel,
            }));

        if (deliveryType === DELIVERY_TYPES.TERRITORIES)
            return territories.filter(isLockedByAccount).map(territory => ({
                label: territory.countryName ?? territory.territoryName,
                value: territory.id,
                levels: territory.restrictedAtLevel,
                icon: <CountryFlag countryCode={territory.territoryCodeA2} />,
            }));

        return [];
    }, [deliveryType, stores, territories]);

    // Reset selected values on the sidecar open/close
    useEffect(() => {
        const updatedSelection = options
            .filter(
                ({ levels }) =>
                    levels.includes(RestrictionLevel.Product) &&
                    levels.includes(RestrictionLevel.Account)
            )
            .map(({ value }) => value);

        setSelectedIds(updatedSelection);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [isOpen]);

    const handleSelectionChange = (selected: RestrictionOption[]) => {
        const ids = selected.map(({ value }) => value);
        setSelectedIds(ids);
    };

    const handleClose = () => onClose();

    const handleConfirm = () => {
        restrictProductLevel(selectedIds, deliveryType);
        handleClose();
    };

    return (
        <Sidecar
            isOpen={isOpen}
            onRequestClose={handleClose}
            title={$t(`${INTL_PREFIX}.title`)}
            confirmTitle={$t(`${INTL_PREFIX}.restrict`)}
            onConfirm={handleConfirm}
            confirmDisabled={false}
        >
            <div className={`${CLASS_NAME}-message`}>
                {$t(`${INTL_PREFIX}.message`, {
                    restrictionType: restrictionType,
                })}
            </div>

            <div className={`${CLASS_NAME}-wrapper`}>
                <ListBox
                    testId={`${CLASS_NAME}-list-box`}
                    options={options}
                    selectedValue={selectedIds}
                    filterPlaceholder={$t(`${INTL_PREFIX}.searchValue`)}
                    onChange={handleSelectionChange}
                    height={420}
                    multi
                />
            </div>
        </Sidecar>
    );
};

export default RestrictFurtherSidecar;
