import {FORM_BUILDER_SCHEMA} from "../schemes";
import {AdditionPropsType} from "../types";
import {DictDeepActionKeyWayType} from "../dependencies";
import {
    arrayFieldComponent,
    blockComponent,
    blockWrapperComponent,
    customFieldWrapperComponent,
    formWrapperComponent,
    inputFieldComponent, reactNodeComponent,
} from "../lib";

const getCustomCompAdditionProps = (keyWay: DictDeepActionKeyWayType | undefined, additionProps: AdditionPropsType) => {
    const deletearrayitem = keyWay && (() => {
        const capturedKeyWay = [...keyWay]
        return () => {
            additionProps.removeErrorField(capturedKeyWay)
            additionProps.deleteArrayItemHook(capturedKeyWay)
        };
    })()

    const getvalue = keyWay && (() => {
        const capturedKeyWay = [...keyWay]
        return () => additionProps.getValue(capturedKeyWay);
    })()

    return {
        deletearrayitem: deletearrayitem,
        getvalue: getvalue,
    }
}

const processingOfKeyWay = (additionProps: AdditionPropsType, getCurArrayIndex: () => number, incrementCurArrayIndex: () => void) => {
    let resKeyWay = additionProps.keyWay
    if (additionProps.arrayKeyWayItemName) {
        resKeyWay = [...resKeyWay, {
            name: additionProps.arrayKeyWayItemName,
            index: getCurArrayIndex()
        }] as DictDeepActionKeyWayType
        incrementCurArrayIndex()
    }
    return [...resKeyWay]
}

const processingAdditionProps = (additionProps: AdditionPropsType, newFields: { [key: string]: any }) => {
    return {
        ...additionProps,
        ...newFields,
    }
}

const formBuilder = (schema: FORM_BUILDER_SCHEMA, additionProps: AdditionPropsType) => {
    let arrayFieldCounter = 0
    const getCurArrayIndex = additionProps.getCurArrayIndex || (() => arrayFieldCounter)
    const incrementCurArrayIndex = additionProps.incrementCurArrayIndex || (() => arrayFieldCounter++)

    const newAdditionProps = processingAdditionProps(additionProps, {
        getCurArrayIndex: getCurArrayIndex,
        incrementCurArrayIndex: incrementCurArrayIndex,
    })

    return schema.map((item, idx) => {
        let keyWay
        let customCompAdditionProps
        switch (item.type) {
            //TODO: надо удалить
            case 'block':
                // Прокидывание arrayKeyWayItemName дальше
                return blockComponent(item, idx, {
                    ...additionProps,
                    // Сброс индексации массива
                    arrayKeyWayItemName: undefined,
                    getCurArrayIndex: undefined,
                    incrementCurArrayIndex: undefined,
                })
            //TODO: надо удалить
            case 'custom_field_wrapper':
                // Прокидывание arrayKeyWayItemName дальше
                return customFieldWrapperComponent(item, idx, {
                    ...additionProps,
                    // Сброс индексации массива
                    arrayKeyWayItemName: undefined,
                    getCurArrayIndex: undefined,
                    incrementCurArrayIndex: undefined,
                })

            // Актуальные блоки, другие будут постепенно выпиливаться
            case 'react_node_component':
                return reactNodeComponent(item, idx, additionProps)
            case 'form_wrapper':
                keyWay = processingOfKeyWay(newAdditionProps, getCurArrayIndex, incrementCurArrayIndex)
                customCompAdditionProps = getCustomCompAdditionProps(keyWay, newAdditionProps)
                return formWrapperComponent(item, idx, {
                    ...newAdditionProps,
                    keyWay: keyWay,
                    customCompAdditionProps: customCompAdditionProps,
                })
            case 'input_field':
                keyWay = processingOfKeyWay(newAdditionProps, getCurArrayIndex, incrementCurArrayIndex)
                customCompAdditionProps = getCustomCompAdditionProps(keyWay, newAdditionProps)
                return inputFieldComponent(item, idx, {
                    ...newAdditionProps,
                    keyWay: keyWay,
                    customCompAdditionProps: customCompAdditionProps,
                })
            case 'array_fields':
                keyWay = processingOfKeyWay(newAdditionProps, getCurArrayIndex, incrementCurArrayIndex)
                customCompAdditionProps = getCustomCompAdditionProps(keyWay, newAdditionProps)
                return arrayFieldComponent(item, idx, {
                    ...newAdditionProps,
                    keyWay: keyWay,
                })
            case "block_wrapper":
                customCompAdditionProps = getCustomCompAdditionProps(undefined, newAdditionProps)
                return blockWrapperComponent(item, idx, {
                    ...newAdditionProps,
                    customCompAdditionProps: customCompAdditionProps,
                })
            default:
                return null
        }
    })
}

export default formBuilder