import type { FC } from 'react';
import React, { useEffect, useState, useMemo } from 'react';
import {
    GridTable,
    InfoMessage,
    SearchInput,
    Section,
    Select,
} from '@theorchard/suite-components';
import { CountryFlag, GlyphIcon } from '@theorchard/suite-icons';
import { useDeliveryRestrictionsContext } from 'src/components/deliveryRestrictionsContext/useDeliveryRestrictionsContext';
import {
    COUNTRY,
    RESTRICTION_TYPE_MAP,
    RESTRICTION_TO_DELIVERY_TYPE_MAP,
    EMPTY_CHAR,
} from 'src/constants';
import type { GridTableCellProps } from '@theorchard/suite-components';
import type { DeliveryType } from 'src/components/deliveryRestrictionsContext/types';
import type { DeliveryRestrictions } from 'src/types';

export interface Props {
    items: DeliveryRestrictions[];
    loading: boolean;
    title: string;
    restrictionType: keyof typeof RESTRICTION_TYPE_MAP;
}

export const CLASS_NAME = 'DeliveringTable';
export const INTL_PREFIX = 'contentReview.deliveringTable';
const PAGE_LIMIT = 9;

const DeliveringTable: FC<Props> = ({
    items,
    loading,
    title,
    restrictionType,
}) => {
    const { moveSingle, setSelected, moveSelected } =
        useDeliveryRestrictionsContext();
    const deliveryType = RESTRICTION_TO_DELIVERY_TYPE_MAP[
        restrictionType
    ] as DeliveryType;

    const [filteredItems, setFilteredItems] =
        useState<DeliveryRestrictions[]>(items);
    const [searchValue, setSearchValue] = useState('');
    const [continentValue, setContinentValue] = useState<string>('');
    const continents = useMemo(() => {
        if (restrictionType !== COUNTRY) return new Set<string>();

        return items.reduce((acc, item) => {
            if (item.continent) {
                acc.add(item.continent);
            }
            return acc;
        }, new Set<string>());
    }, [items, restrictionType]);

    const [selectedRows, setSelectedRows] = useState<string[]>([]);

    useEffect(() => {
        setSelectedRows(
            items.filter(item => item.isSelected).map(item => item.id)
        );

        const filtered = items.filter(item => {
            const matchesSearch = searchValue.trim()
                ? restrictionType === COUNTRY
                    ? item.countryName
                          ?.toLowerCase()
                          .includes(searchValue.toLowerCase())
                    : item.name
                          ?.toLowerCase()
                          .includes(searchValue.toLowerCase())
                : true;
            const matchesContinent = continentValue.trim()
                ? item.continent === continentValue
                : true;
            return matchesSearch && matchesContinent;
        });
        setFilteredItems(filtered);
    }, [items, searchValue, continentValue, restrictionType]);

    const handleSelect = (rows: string[]) => {
        setSelectedRows(rows);
        setSelected(deliveryType, rows);
    };

    const DeliveringCell = ({
        data: { name, countryName, territoryCodeA2 },
    }: GridTableCellProps<DeliveryRestrictions>) => (
        <div className="cell-deliveryRestriction">
            {territoryCodeA2 && (
                <CountryFlag countryCode={territoryCodeA2} size={24} />
            )}
            <div className="cell-deliveryRestriction-body">
                <div className="cell-deliveryRestriction-label">
                    {restrictionType === COUNTRY ? countryName : name}
                </div>
            </div>
        </div>
    );

    const termKey =
        restrictionType === 'service' ? 'serviceCount' : 'countryCount';
    const countText = $t(`${INTL_PREFIX}.${termKey}`, {
        count: filteredItems?.length || EMPTY_CHAR,
    });

    return (
        <div className={CLASS_NAME} data-testid={CLASS_NAME}>
            <h4 className="delivery-table-title">
                {$t('common.delivery.delivering')}
            </h4>

            <Section.Filters className="delivery-search-filters">
                <SearchInput
                    onChange={setSearchValue}
                    expanded
                    placeholder={`Search ${restrictionType}...`}
                    placeholderWidth={165}
                />
                {restrictionType === COUNTRY && (
                    <Select
                        placeholder={$t('common.continent')}
                        compact
                        selectedValue={continentValue || undefined}
                        onChange={option =>
                            setContinentValue(option?.value ?? '')
                        }
                        options={Array.from(continents).map(continent => ({
                            label: String(continent),
                            value: String(continent),
                        }))}
                    />
                )}
            </Section.Filters>

            <Section.Table variant="edit">
                <GridTable
                    className={'delivery-table'}
                    paginationText={countText}
                    data={filteredItems}
                    loading={loading}
                    loadingRows={PAGE_LIMIT}
                    bordered
                    rowKey="id"
                    variant="zebra"
                    stickyHeader
                    maxHeight={460}
                    columnDefs={[
                        {
                            name:
                                restrictionType === COUNTRY
                                    ? 'countryName'
                                    : 'name',
                            title: title,
                            Cell: DeliveringCell,
                        },
                    ]}
                    selectable
                    selectedRowKeys={selectedRows}
                    onSelectedRowsChanged={handleSelect}
                    rowActionsHeader={''}
                    rowActions={{
                        move: {
                            icon: <GlyphIcon name="arrowRight" size={12} />,
                            tooltip: $t(`${INTL_PREFIX}.rowActionTooltip`),
                            onClick: row => {
                                moveSingle(deliveryType, row.id);
                            },
                        },
                    }}
                    rowBulkActions={{
                        move: {
                            icon: <GlyphIcon name="arrowRight" size={16} />,
                            tooltip: $t(`${INTL_PREFIX}.bulkActionTooltip`, {
                                restrictionType:
                                    RESTRICTION_TYPE_MAP[
                                        restrictionType
                                    ].toLowerCase(),
                            }),
                            onClick: () => {
                                moveSelected(deliveryType);
                            },
                        },
                    }}
                    emptyStateComponent={
                        <div className="delivery-table-empty-state">
                            <InfoMessage
                                size="sm"
                                illustration="emptyState"
                                message={$t(`${INTL_PREFIX}.emptyState.title`, {
                                    restrictionType:
                                        RESTRICTION_TYPE_MAP[restrictionType],
                                })}
                                body={
                                    <span>
                                        {$t(
                                            `${INTL_PREFIX}.emptyState.description`,
                                            {
                                                restrictionType:
                                                    RESTRICTION_TYPE_MAP[
                                                        restrictionType
                                                    ].toLowerCase(),
                                            }
                                        )}
                                    </span>
                                }
                            />
                        </div>
                    }
                />
            </Section.Table>
        </div>
    );
};

export default DeliveringTable;
