import React, { useEffect, useState } from 'react';
import type { FC } from 'react';
import {
    getCountries,
    MarketSelector,
    MultiSelect,
    Sidecar,
    Stepper,
} from '@theorchard/suite-components';
import { isNull, values } from 'lodash';
import { useDeliveryRestrictionsContext } from 'src/components/deliveryRestrictionsContext/useDeliveryRestrictionsContext';
import type { Step } from '@theorchard/suite-components';
import './countryServiceSidercar.scss';

export const CLASS_NAME = 'CountryServiceSidecar';
export const INTL_PREFIX = 'contentReview.countryServiceSidecar';

const EMPTY_RESTRICTION = {
    stores: [],
    countries: [],
};

export interface Props {
    isOpen: boolean;
    onClose: () => void;
    editId?: string | null;
}

const CountryServiceSidecar: FC<Props> = ({
    isOpen,
    onClose,
    editId = null,
}) => {
    const {
        stores,
        storeTerritoryGroups,
        addStoreTerritoryGroup,
        editStoreTerritoryGroup,
    } = useDeliveryRestrictionsContext();
    const restriction = editId
        ? storeTerritoryGroups[editId]
        : EMPTY_RESTRICTION;

    const [selectedServiceIds, setSelectedServiceIds] = useState<string[]>(
        restriction.stores
    );
    const [selectedCountryIds, setSelectedCountryIds] = useState<string[]>(
        restriction.countries
    );

    useEffect(() => {
        if (isNull(editId)) return;

        setSelectedServiceIds(storeTerritoryGroups[editId].stores);
        setSelectedCountryIds(storeTerritoryGroups[editId].countries);
    }, [editId, storeTerritoryGroups]);

    const sidecarTitle = $t(`${INTL_PREFIX}.header${editId ? 'Edit' : 'Add'}`);
    const servicesOptions = stores.map(store => ({
        label: store.name,
        value: store.id,
    }));

    const countryOptions = getCountries().map(country => {
        const isDisabled = values(storeTerritoryGroups)
            .reduce((acc, restriction) => {
                const isStoreRestricted = restriction.stores.some(storeId =>
                    selectedServiceIds.includes(storeId)
                );

                return isStoreRestricted
                    ? [...acc, ...restriction.countries]
                    : acc;
            }, [] as string[])
            .includes(country.value);

        return {
            label: country.name,
            value: country.value,
            continent: country.continent,
            disabled: isDisabled,
            subtitle: isDisabled
                ? $t(`${INTL_PREFIX}.countryRestrictedMsg`)
                : null,
        };
    });

    const servicesStep: Step = {
        title: $t(`${INTL_PREFIX}.if`),
        icon: { variant: 'solid', number: 0 },
        body: (
            <div className={`${CLASS_NAME}-services-container`}>
                <div className={`${CLASS_NAME}-label`}>
                    {$t(`${INTL_PREFIX}.services`)}
                </div>

                <MultiSelect
                    className={`${CLASS_NAME}-service-selector`}
                    placeholder={$t(`${INTL_PREFIX}.servicesPlaceholder`)}
                    selectedValue={selectedServiceIds}
                    options={servicesOptions}
                    onChange={selection =>
                        setSelectedServiceIds(
                            selection.map(({ value }) => value)
                        )
                    }
                />
            </div>
        ),
    };

    const countriesStep: Step = {
        title: $t(`${INTL_PREFIX}.then`),
        icon: { variant: 'solid', number: 0 },
        body: (
            <>
                <div className={`${CLASS_NAME}-label`}>
                    {$t(`${INTL_PREFIX}.countries`)}
                </div>

                <MarketSelector
                    initialValue={restriction.countries}
                    countries={countryOptions}
                    requireApply={false}
                    disabled={!selectedServiceIds.length}
                    onChange={selection =>
                        setSelectedCountryIds(
                            selection.map(({ value }) => value)
                        )
                    }
                    defaultListMode="sectioned"
                    sectionGroupSelect
                />
            </>
        ),
    };

    const confirmRestriction = () => {
        if (editId) editRestriction();
        else addRestriction();

        handleClose();
    };

    const addRestriction = () => {
        const newRestrictionGroup = {
            stores: selectedServiceIds,
            countries: selectedCountryIds,
        };

        addStoreTerritoryGroup(newRestrictionGroup);
    };

    const editRestriction = () => {
        const editRestrictionGroup = {
            id: editId!,
            stores: selectedServiceIds,
            countries: selectedCountryIds,
        };

        editStoreTerritoryGroup(editRestrictionGroup);
    };

    const handleClose = () => {
        setSelectedServiceIds([]);
        setSelectedCountryIds([]);
        onClose();
    };

    return (
        <>
            <Sidecar
                isOpen={isOpen}
                onRequestClose={handleClose}
                title={sidecarTitle}
                confirmTitle={$t(`${INTL_PREFIX}.apply`)}
                onConfirm={confirmRestriction}
                confirmDisabled={
                    selectedServiceIds.length === 0 ||
                    selectedCountryIds.length === 0
                }
            >
                <div className={`${CLASS_NAME}-message`}>
                    {$t(`${INTL_PREFIX}.message`)}
                </div>

                <Stepper
                    className={`${CLASS_NAME}-stepper`}
                    layout="vertical"
                    steps={[servicesStep, countriesStep]}
                />
            </Sidecar>
        </>
    );
};

export default CountryServiceSidecar;
