import React, {
    type ChangeEventHandler,
    useContext,
    useEffect,
    useState,
} from 'react';
import { Col, Label, Row } from '@theorchard/suite-components';
import { isEmpty } from 'lodash-es';
import { useParams } from 'react-router-dom';
import { useContractAttachments } from 'src/apollo/queries/contract';
import LabelSearchableSelect from 'src/components/shared/label-searchable-select';
import ProductSearchableSelect from 'src/components/shared/product-searchable-select';
import {
    SET_CONTRACT_TERM_ATTACHMENTS,
    SET_DEFAULT_CONDITION,
    SET_ATTACHMENTS_RELATIONS,
    SET_ERRORS,
} from 'src/constants';
import { ContractTermContext } from 'src/contexts/contract-term-context';
import { ContractTermConditionsList } from './contract-term-conditions-list';
import type { AbacusContractAttachmentsAccount } from 'src/types/abacus-account';

export default function ProductBaseTermsForm() {
    const { contractId, contractTermId } = useParams<{
        contractId: string;
        contractTermId: string;
    }>();
    const { state, dispatch } = useContext(ContractTermContext);
    const { data: contract } = useContractAttachments(contractId);
    const [account, setAccount] = useState(
        {} as AbacusContractAttachmentsAccount
    );
    const setErrors = (attachmentsValidError: string[]) =>
        dispatch({ type: SET_ERRORS, attachmentsValidError, error: [] });

    const getRelatedLabels = () => {
        if (!isEmpty(state.attachmentsRelations)) {
            const { labelIds } = state.attachmentsRelations;
            if (!isEmpty(labelIds)) return labelIds;
        }
        return null;
    };

    const labelChangeHandler: ChangeEventHandler<HTMLInputElement> = e => {
        const {
            target: { value },
        } = e;
        const selectedOptions = value || [];
        let labelId = null;
        const relatedLabelIds = getRelatedLabels();
        if (selectedOptions.length) [labelId] = selectedOptions;
        if (!relatedLabelIds || !relatedLabelIds.includes(labelId)) {
            dispatch({
                type: SET_ATTACHMENTS_RELATIONS,
                attachmentsRelations: { labelIds: [labelId?.toString()] },
            });
            dispatch({ type: SET_CONTRACT_TERM_ATTACHMENTS, attachments: [] });
        }
    };

    const productChangeHandler: ChangeEventHandler<HTMLInputElement> = e => {
        const {
            target: { value },
        } = e;
        const attachments = value || [];
        dispatch({ type: SET_CONTRACT_TERM_ATTACHMENTS, attachments });
    };

    useEffect(() => {
        if (state.attachments.length > 0 && state.conditions.length === 0)
            dispatch({ type: SET_DEFAULT_CONDITION });
    }, [state.attachments]);

    useEffect(() => {
        if (contract && contract.abacusContract)
            setAccount(contract.abacusContract.account);
    }, [contract]);

    return (
        <div className="ContractProductTermsForm-block">
            <Row className="BaseRateHorizontalRow">
                <Col sm={2}>
                    <Label text="Label" />
                </Col>
                <Col sm={5}>
                    <LabelSearchableSelect
                        onChange={labelChangeHandler}
                        vendorCatalogIds={getRelatedLabels()}
                        isMultiSelect={false}
                    />
                </Col>
            </Row>
            {getRelatedLabels() && (
                <Row
                    className="BaseRateHorizontalRow"
                    data-testid="productSearchTestId"
                >
                    <Col sm={2}>
                        <Label text="Product" />
                    </Col>
                    <Col sm={5}>
                        <ProductSearchableSelect
                            accountId={account ? account.accountId : ''}
                            contractTermId={contractTermId}
                            contractId={contractId}
                            onChange={productChangeHandler}
                            productUpcs={state.attachments}
                            labelIds={getRelatedLabels()}
                            setErrors={setErrors}
                        />
                    </Col>
                </Row>
            )}
            {(state.attachments.length > 0 || state.conditions.length > 0) && (
                <ContractTermConditionsList />
            )}
        </div>
    );
}
