import React, { useContext } from 'react';
import {
    Col,
    Form,
    InputGroup,
    Row,
    MarketSelector,
    getContinents,
} from '@theorchard/suite-components';
import { GlyphIcon } from '@theorchard/suite-icons';
import cx from 'classnames';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { ServiceMultiSelect } from 'src/components/shared/service-multiselect';
import { TransactionTypeMultiSelect } from 'src/components/shared/transaction-type-multiselect';
import {
    CONTRACT_TERM_COMMISSION_PATTERN,
    DELETE_TERM_CONDITION,
    SET_CONTRACT_TERM_CONDITION,
} from 'src/constants';
import { ContractTermContext } from 'src/contexts/contract-term-context';
import type { AbacusNrContractTermCondition } from 'src/types/abacus-contract-term';

export interface NrContractTermConditionFormPropType {
    condition: AbacusNrContractTermCondition;
    dragAndDropCondition: (param1: number, param2: number) => void;
    index: number;
    isDraggable: boolean;
}

export const NrContractTermConditionForm: React.FC<
    NrContractTermConditionFormPropType
> = ({ condition, index, isDraggable }) => {
    const { state, dispatch } = useContext(ContractTermContext);

    const onDelete = (
        termCondition: AbacusNrContractTermCondition,
        termConditionIndex: number
    ) =>
        dispatch({
            type: DELETE_TERM_CONDITION,
            termCondition,
            termConditionIndex,
        });

    const {
        attributes,
        listeners,
        setNodeRef,
        transform,
        transition,
        isDragging,
    } = useSortable({ id: condition.priority });

    const style = isDraggable
        ? { transform: CSS.Transform.toString(transform), transition }
        : undefined;

    const changeHandler = (e: any) => {
        const {
            target: { name, value },
        } = e;

        if (['countries', 'stores', 'transactionTypes'].includes(name)) {
            const newValue = value || [];
            return dispatch({
                type: SET_CONTRACT_TERM_CONDITION,
                index,
                name,
                value: newValue,
            });
        }

        if (
            name === 'commission' &&
            value != '' &&
            !CONTRACT_TERM_COMMISSION_PATTERN.test(value)
        )
            return;

        return dispatch({
            type: SET_CONTRACT_TERM_CONDITION,
            index,
            name,
            value,
        });
    };

    const existingConditions = state.conditions.filter(
        (termCondition: any) => termCondition.contractTermConditionId !== null
    );

    const isDeleteDisabled =
        existingConditions.length === 1 &&
        existingConditions[0].contractTermConditionId ===
            condition.contractTermConditionId;

    return (
        <Row
            className={`NrContractTermsConditionsTable-row ${
                isDragging ? 'isDragging' : ''
            }`}
            id={`condition-${condition.priority}`}
            key={`contract-term-condition-row-${condition.priority}`}
            ref={isDraggable ? setNodeRef : undefined}
            style={style}
            data-testid="contractTermConditionRow"
            {...(isDraggable ? attributes : {})}
            {...(isDraggable ? listeners : {})}
        >
            <Col
                sm="1"
                className={`priorityControl ${isDraggable ? 'draggable' : ''}`}
                data-testid="nrContractTermConditionDragIcon"
            >
                {isDraggable && <GlyphIcon name="drag" size={16} />}
                {condition.priority}
            </Col>
            <Col sm="2">
                <Form.Control
                    data-testid="contractTermConditionName"
                    name="contractTermConditionName"
                    onChange={e => changeHandler(e)}
                    placeholder="Add Name"
                    type="text"
                    value={condition.contractTermConditionName || ''}
                />
            </Col>
            <Col sm="2">
                <TransactionTypeMultiSelect
                    className="transactionTypes"
                    onChange={e =>
                        changeHandler({
                            target: {
                                name: 'transactionTypes',
                                value: e && e.map(({ value }: any) => value),
                            },
                        })
                    }
                    placeholder="All"
                    selectedValue={condition.conditions.transactionTypes}
                    transactionTypes={state.transactionTypes}
                    transactionTypeGroups={state.transactionTypeGroups}
                />
            </Col>
            <Col sm="2">
                <ServiceMultiSelect
                    className="stores"
                    services={state.stores}
                    onChange={e =>
                        changeHandler({
                            target: {
                                name: 'stores',
                                value: e && e.map(({ value }: any) => value),
                            },
                        })
                    }
                    placeholder="All"
                    selectedValue={condition.conditions.stores}
                />
            </Col>
            <Col sm="2">
                <MarketSelector
                    id="countries"
                    quickSelections={[...getContinents()]}
                    onChange={e =>
                        changeHandler({
                            target: {
                                name: 'countries',
                                value: e?.map((c: any) => c.alpha3),
                            },
                        })
                    }
                    name="countries"
                    placeholder="All"
                    selectedValue={condition.conditions.countries}
                    requireApply={false}
                />
            </Col>
            <Col sm="2">
                <InputGroup>
                    <Form.Control
                        data-testid="commission"
                        name="commission"
                        onChange={e => changeHandler(e)}
                        type="text"
                        value={condition.commission || ''}
                    />
                    <InputGroup.Append>
                        <InputGroup.Text>%</InputGroup.Text>
                    </InputGroup.Append>
                </InputGroup>
            </Col>
            <Col sm="1">
                {state.conditions.length > 1 && (
                    <div
                        className={cx({
                            deleteNrTermCondition: true,
                            disableDelete: isDeleteDisabled,
                        })}
                        data-testid="nrContractTermConditionDeleteIcon"
                        onClick={() =>
                            !isDeleteDisabled && onDelete(condition, index)
                        }
                    >
                        <GlyphIcon name="trash" size={16} />
                    </div>
                )}
            </Col>
        </Row>
    );
};

export default NrContractTermConditionForm;
