import type { Dispatch, SetStateAction } from 'react';
import React from 'react';
import { Label } from '@theorchard/suite-components';
import { Page } from '@theorchard/suite-frontend';
import { INCLUDED_EXCLUDED_OPTIONS_MAPPING } from 'src/apollo/type-constants/contract';
import AccountSelect from 'src/components/contract-list/account-select';
import { ContractStatusMultiSelect } from 'src/components/shared/contract-status-multi-select';
import { ContractTypeDropdown } from 'src/components/shared/contract-type-dropdown';
import { IncludedExcludedSelect } from 'src/components/shared/included-excluded-select';
import { SearchField } from 'src/components/shared/search-field';
import RunControllerMultiSelect from '../shared/run-controller-multi-select';
import type { ListViewItem } from '@theorchard/suite-components';
import type {
    AbacusContractStatus,
    AbacusContractType,
} from 'src/apollo/definitions/globalTypes';
import type { AbacusContractListQueryParams } from 'src/types/abacus-contract';

export interface ContractFiltersPropTypes {
    changeHandler: (params: object) => void;
    clearContractSearchField: boolean;
    filterValues: {
        contractType: AbacusContractType | null;
        searchTerm: string;
        accountIds: number[] | null;
        isExcludedFromAccountingRun: boolean | null;
        contractStatuses: AbacusContractStatus[] | null;
        runControllerIds: number[] | null;
    };
    setFilterValues: Dispatch<SetStateAction<AbacusContractListQueryParams>>;
    selectedAccount: string | number;
    setSelectedAccount: Dispatch<SetStateAction<string | number>>;
}

export const ContractFilters: React.FC<ContractFiltersPropTypes> = ({
    changeHandler,
    clearContractSearchField,
    filterValues,
    setFilterValues,
    selectedAccount,
    setSelectedAccount,
}) => {
    const setChangeHandler = (value: string) =>
        changeHandler({ target: { name: 'searchTerm', value } });

    const getValueForIncludedExcludedRun = (value: boolean | null) =>
        value != null
            ? Object.keys(INCLUDED_EXCLUDED_OPTIONS_MAPPING).find(
                  key => INCLUDED_EXCLUDED_OPTIONS_MAPPING[key] === value
              )
            : '';

    return (
        <Page>
            <Page.Row>
                <div className="ContractFiltersRow">
                    <div className="ContractSearchFilter">
                        <Label text="Contract" />
                        <SearchField
                            placeholder="Filter by Contract Name or ID"
                            onHandleChange={setChangeHandler}
                            searchInputName="contractName"
                            states={filterValues}
                            setStates={setFilterValues}
                            clearSearchField={clearContractSearchField}
                            validatePattern={null}
                            value={filterValues.searchTerm}
                        />
                    </div>
                    <div className="AccountFilter">
                        <Label text="Account" />
                        <AccountSelect
                            selectedAccount={selectedAccount}
                            setSelectedAccount={setSelectedAccount}
                            changeHandler={changeHandler}
                        />
                    </div>
                    <div className="ContractTypeFilter">
                        <ContractTypeDropdown
                            compact={true}
                            fieldTextMaxWidth={250}
                            onChange={(e: ListViewItem | undefined) =>
                                changeHandler({
                                    target: {
                                        name: 'contractType',
                                        value: e?.value || null,
                                    },
                                })
                            }
                            value={filterValues?.contractType || ''}
                        />
                    </div>
                    <div className="ContractStatusFilter">
                        <ContractStatusMultiSelect
                            compact={true}
                            onChange={(e: ListViewItem[] | undefined) =>
                                changeHandler({
                                    target: {
                                        name: 'contractStatuses',
                                        value:
                                            e &&
                                            e.map(
                                                ({ value }: ListViewItem) =>
                                                    value
                                            ),
                                    },
                                })
                            }
                            value={filterValues?.contractStatuses || []}
                        />
                    </div>
                    <div className="IncludedExcludedInRunFilter">
                        <IncludedExcludedSelect
                            compact={true}
                            fieldTextMaxWidth={350}
                            onChange={(e: ListViewItem | undefined) =>
                                changeHandler({
                                    target: {
                                        name: 'isExcludedFromAccountingRun',
                                        value: e?.value || null,
                                    },
                                })
                            }
                            placeholder="Included/Excluded in Run"
                            value={getValueForIncludedExcludedRun(
                                filterValues?.isExcludedFromAccountingRun
                            )}
                        />
                    </div>
                    <div className="RunControllerFilter">
                        <RunControllerMultiSelect
                            compact={true}
                            onChange={(e: ListViewItem[] | undefined) =>
                                changeHandler({
                                    target: {
                                        name: 'runControllerIds',
                                        value:
                                            e &&
                                            e.map(({ value }: ListViewItem) =>
                                                parseInt(value)
                                            ),
                                    },
                                })
                            }
                            placeholder="Run Controller"
                            value={
                                filterValues?.runControllerIds?.map(
                                    runControllerId =>
                                        runControllerId.toString()
                                ) || []
                            }
                        />
                    </div>
                </div>
            </Page.Row>
        </Page>
    );
};
