import type { FC } from 'react';
import React, { useState } from 'react';
import {
    Card,
    ListBox,
    LoadingSpinner,
    InfoMessage,
} from '@theorchard/suite-components';
import { GlyphIcon } from '@theorchard/suite-icons';
import cx from 'classnames';
import { groupBy } from 'lodash';
import ListBoxSkeleton from 'src/components/skeletons/ListBoxSkeleton';
import { useLazySubstoresQuery } from 'src/data/queries/substores/substores';
import NotDeliveringLabel from './notDeliveringLabel';
import { formatCountriesOptions } from './utils';
import type {
    RestrictionLevel,
    ContextStoreTerritories,
} from 'src/components/deliveryRestrictionsContext/types';

export interface Props {
    className?: string;
    isLoading?: boolean;
    countryXServiceRestrictions: ContextStoreTerritories[];
}

interface LevelMap {
    [key: string]: RestrictionLevel[];
}

interface CountryOption {
    label: string;
    value: string;
    icon: React.ReactNode;
    levels: RestrictionLevel[];
}

interface CountryOptionWrapper {
    label: string;
    value: string;
    options: CountryOption[];
}

const CLASS_NAME = 'CountryXServicePairing';
const INTL_PREFIX = 'contentReview.productViewDeliveryRestrictions';

export const CountryXServicePairing: FC<Props> = ({
    className,
    isLoading,
    countryXServiceRestrictions,
}) => {
    const [storeId, setStoreId] = useState('');
    const [doLoadSubstores, { loading, data }] = useLazySubstoresQuery({
        storeId: storeId,
    });

    const handleStoreSelect = (value: string | undefined) => {
        setStoreId(value ?? '');
        void doLoadSubstores({
            variables: { storeId: value },
        });
    };

    const countryXServiceRestrictionsByStoreId = groupBy(
        countryXServiceRestrictions,
        'storeId'
    );

    const deliveringStoreOptions = [];

    for (const id in countryXServiceRestrictionsByStoreId) {
        deliveringStoreOptions.push({
            label: countryXServiceRestrictionsByStoreId[id][0].storeName,
            value: countryXServiceRestrictionsByStoreId[id][0].storeId,
        });
    }

    const restrictedCountryCodes = data
        ? countryXServiceRestrictionsByStoreId[storeId]
              .map(c => c.restrictedCountries.map(c0 => c0.territoryCodeA2))
              .flat()
        : [];

    const restrictedCountryCodesLevelMap: LevelMap = {};
    if (data) {
        countryXServiceRestrictionsByStoreId[storeId].map(c =>
            c.restrictedCountries.map(c0 =>
                !restrictedCountryCodesLevelMap[c0.territoryCodeA2]
                    ? (restrictedCountryCodesLevelMap[c0.territoryCodeA2] =
                          c.restrictedAtLevel)
                    : null
            )
        );
    }
    const deliveringCountryOptions = data
        ? formatCountriesOptions(
              data.substores.territories,
              restrictedCountryCodes
          )
        : [];
    const notDeliveringCountryOptions = data
        ? formatCountriesOptions(
              data.substores.territories
                  .filter(item =>
                      restrictedCountryCodes.includes(item.territoryCodeA2)
                  )
                  .map(t => ({
                      ...t,
                      restrictedAtLevel:
                          restrictedCountryCodesLevelMap[t.territoryCodeA2],
                  }))
          )
        : [];

    const countryTotal = data ? data.substores.territories.length : 0;
    const deliveringCount = data
        ? data.substores.territories.length - restrictedCountryCodes.length
        : 0;
    const notDeliveringCount = data ? restrictedCountryCodes.length : 0;

    const filterPlaceholder = $t(`${INTL_PREFIX}.serviceFilterPlaceholder`);

    if (deliveringStoreOptions.length === 0)
        return (
            <div className="serviceXCountryEmptyState">
                <InfoMessage
                    message={$t(
                        `${INTL_PREFIX}.serviceXCountryEmptyStateTitle`
                    )}
                    body={$t(
                        `${INTL_PREFIX}.serviceXCountryEmptyStateSubtitle`
                    )}
                    size="sm"
                />
            </div>
        );

    return (
        <div className={cx(className, CLASS_NAME)} data-testid={CLASS_NAME}>
            <Card suite className={`${CLASS_NAME}-stores`} layout="vertical">
                <Card.Body>
                    <Card.Subtitle>
                        <div className="header-subtext-with-icon">
                            <GlyphIcon name="info" size={16} />
                            <span className="icon">
                                {$t(`${INTL_PREFIX}.info`)}
                            </span>
                        </div>
                    </Card.Subtitle>
                    {isLoading ? (
                        <ListBoxSkeleton
                            name="delivering"
                            height={490}
                            filterPlaceholder={filterPlaceholder}
                        />
                    ) : (
                        <ListBox
                            options={deliveringStoreOptions}
                            height={490}
                            filterPlaceholder={filterPlaceholder}
                            onChange={option =>
                                handleStoreSelect(option?.value)
                            }
                        />
                    )}
                </Card.Body>
            </Card>
            <span className={`${CLASS_NAME}-card-separator-x`}> </span>
            <Card
                suite
                className={`${CLASS_NAME}-delivering`}
                layout="vertical"
            >
                <Card.Header>
                    <Card.Title>{$t(`${INTL_PREFIX}.delivering`)}</Card.Title>
                </Card.Header>
                <Card.Subtitle>
                    <span className="header-subtext">
                        {$t(`${INTL_PREFIX}.countryCount`, {
                            count: deliveringCount,
                            total: countryTotal,
                        })}
                    </span>
                </Card.Subtitle>

                <Card.Body>
                    {loading ? (
                        <div className="text-center p-5">
                            <LoadingSpinner show size={24} />
                        </div>
                    ) : (
                        <ListBox
                            options={deliveringCountryOptions}
                            variant="static"
                            maxHeight={490}
                            filterPlaceholder={$t(
                                `${INTL_PREFIX}.countryFilterPlaceholder`
                            )}
                        />
                    )}
                </Card.Body>
            </Card>
            <Card
                suite
                className={`${CLASS_NAME}-notDelivering`}
                layout="vertical"
            >
                <Card.Header>
                    <Card.Title>
                        {$t(`${INTL_PREFIX}.notDelivering`)}
                    </Card.Title>
                </Card.Header>
                <Card.Subtitle>
                    <span className="header-subtext">
                        {$t(`${INTL_PREFIX}.countryCount`, {
                            count: notDeliveringCount,
                            total: countryTotal,
                        })}
                    </span>
                </Card.Subtitle>
                <Card.Body>
                    {loading ? (
                        <div className="text-center p-5">
                            <LoadingSpinner show size={24} />
                        </div>
                    ) : (
                        <ListBox
                            options={
                                notDeliveringCountryOptions as CountryOptionWrapper[]
                            }
                            variant="static"
                            maxHeight={490}
                            filterPlaceholder={$t(
                                `${INTL_PREFIX}.countryFilterPlaceholder`
                            )}
                            components={{
                                OptionLabel: ({
                                    option: { label, levels },
                                }) => (
                                    <NotDeliveringLabel
                                        label={label}
                                        levels={levels}
                                    />
                                ),
                            }}
                        />
                    )}
                </Card.Body>
            </Card>
        </div>
    );
};
