import type { FC } from 'react';
import React from 'react';
import { Dropdown } from '@theorchard/suite-components';
import cx from 'classnames';
import { map } from 'lodash';
import TruncatedText from '../truncatedText';
import type {
    DropdownOption,
    DropdownProps,
} from '@theorchard/suite-components';
import type { SubaccountMetadataFragment } from 'src/data/queries/reviewQueueSearch/__generated__/ReviewQueueSearch';
import type { AccountFilterOption } from 'src/data/queries/reviewQueueSearch/types';

interface SetParamsCallback {
    (name: string, value: string): void;
}

export type ParamValue = string | number | (string | number)[];

type FormatOptionFunction =
    DropdownProps<LabelDropdownOption>['formatOptionLabel'];

export interface Props extends Omit<DropdownProps, 'options'> {
    filterName: string;
    onFilterChange: SetParamsCallback;
    filterOptions?: AccountFilterOption[];
}

export interface LabelDropdownOption extends DropdownOption {
    subaccountId?: number;
    vendorId?: string | number;
    name?: string;
    vendorName?: string;
}

export const CLASS_NAME = 'DropdownFilter';

const AccountDropdownFilter: FC<Props> = ({
    className,
    filterName,
    filterOptions,
    onFilterChange,
    ...props
}) => {
    const handleDropdownFilterSelection = (
        name: string,
        value: string | undefined
    ) => {
        onFilterChange(filterName, value ?? '');
    };

    const getOptionSubtitle = (label: LabelDropdownOption) => {
        const isSubAccount = !!label.vendorId;
        if (isSubAccount) {
            const [, id] = label.vendorId?.toString().split(':') ?? [];
            return `Subaccount • ${label.vendorName} (${id})`;
        }
        return 'Label';
    };

    const options = map(
        filterOptions,
        ({ id, name: filterOptionName, extra }) => {
            const name = filterOptionName || '';
            if (extra) {
                const subaccountMetadata = extra as SubaccountMetadataFragment;
                return {
                    label: name,
                    value: id.toString(),
                    vendorId: id,
                    vendorName: subaccountMetadata.labelName,
                    isSubAccount: true,
                };
            }
            return { label: name, value: id.toString() };
        }
    );

    const formatOptionLabel: FormatOptionFunction = (option, { context }) => {
        const placement = context === 'value' ? 'bottom' : 'right';

        return (
            <div>
                <div className="LabelFilterName">
                    <TruncatedText
                        value={`${option.label} (${
                            option.value.split(':')[0]
                        })`}
                        placement={placement}
                    />
                </div>

                {option.vendorId && (
                    <div className="LabelFilterSubtitle">
                        <TruncatedText
                            value={getOptionSubtitle(option)}
                            placement={placement}
                        />
                    </div>
                )}

                {!option.vendorId ? (
                    <div className="LabelFilterSubtitle">Label</div>
                ) : null}
            </div>
        );
    };

    return (
        <Dropdown
            {...props}
            name={filterName}
            className={cx(CLASS_NAME, className)}
            isClearable
            onValueChanged={handleDropdownFilterSelection}
            options={options}
            formatOptionLabel={formatOptionLabel}
        />
    );
};

export default AccountDropdownFilter;
