import type { FC } from 'react';
import React, { useCallback, useMemo } from 'react';
import { Select } from '@theorchard/suite-components';
import {
    type DeliveryStoreTerritory,
    useOwnershipDeliveryStoresQuery,
} from 'src/data/queries';
import type { DropdownOption, SearchableDropdownOption } from 'src/types';
import type { SetParamsCallback } from 'src/utils/route';

export const CLASSNAME = 'DeliveryStoresDropdown';

interface DeliveryStoreTerritoryOption extends DeliveryStoreTerritory {
    showTerritory: boolean;
}

export interface Props {
    disabled?: boolean;
    onChange?: SetParamsCallback;
    onChangeFilter?: (store: DeliveryStoreTerritory | null) => void;
    placeholder: string;
    storeId?: string;
    territoryCode?: string;
    isFilter?: boolean;
    compact?: boolean;
    width?: number;
}

const createOption = (
    store: DeliveryStoreTerritoryOption
): {
    data: DeliveryStoreTerritoryOption;
    subtitle?: string;
    label: string;
    value: string;
} => ({
    label: store.name,
    value: `${store.id}-${store.territoryCode}`,
    data: store,
    // conditionally include a subtitle if the store has a territory
    ...(store.showTerritory && { subtitle: store.territory }),
});

const DeliveryStoresDropdown: FC<Props> = props => {
    const {
        onChange,
        onChangeFilter,
        disabled,
        territoryCode,
        storeId,
        placeholder,
        isFilter,
        compact,
        width,
    } = props;
    const { data } = useOwnershipDeliveryStoresQuery();
    const storeOptions = useMemo<
        DropdownOption<DeliveryStoreTerritoryOption>[]
    >(
        () =>
            [...(data ?? [])].map(item => {
                // render territory only for services that have multiple territories
                const showTerritory = data.some(
                    t =>
                        t.id === item.id &&
                        t.territoryCode !== item.territoryCode
                );
                return createOption({
                    ...item,
                    showTerritory,
                });
            }),
        [data]
    );

    const handleChange = useCallback(
        (newValue?: SearchableDropdownOption<DeliveryStoreTerritoryOption>) => {
            if (onChange) {
                onChange({
                    store: newValue?.value,
                    territoryCode: newValue?.data?.territoryCode,
                });
            }
        },
        [onChange]
    );

    const handleChangeDropdownFilter = useCallback(
        (newValue?: SearchableDropdownOption<DeliveryStoreTerritoryOption>) => {
            if (onChangeFilter) onChangeFilter(newValue?.data ?? null);
        },
        [onChangeFilter]
    );

    let selectedOption: DropdownOption<DeliveryStoreTerritoryOption> | null =
        null;
    if (storeId && territoryCode) {
        const store = data.filter(x => x.id === storeId);
        const territory = territoryCode
            ? store.find(x => x.territoryCode === territoryCode)
            : null;
        selectedOption = createOption({
            id: storeId,
            name: store[0]?.name ?? '',
            territory: territory?.territory ?? '',
            territoryCode: territory?.territoryCode ?? '',
            showTerritory: true,
        });
    }

    const selectedOptionValue = selectedOption
        ? selectedOption.value
        : undefined;

    return (
        <Select
            testId="Dropdown_deliveryStoresDropdown"
            name="deliveryStoresDropdown"
            onChange={isFilter ? handleChangeDropdownFilter : handleChange}
            options={storeOptions}
            disabled={disabled}
            selectedValue={selectedOptionValue}
            placeholder={placeholder}
            compact={compact}
            showSelectedSubtitle={true}
            width={width}
        ></Select>
    );
};

export default DeliveryStoresDropdown;
