import { CodeBlockContainer, CodeBlocksActionTypes, INIT_CODEBLOCKS, REMOVE_CODEBLOCK, INSERT_CODEBLOCK, InsertCodeBlockAction, RemoveCodeBlockAction, SetDropZoneZIdxAction, SET_DROPZONE_Z_INDEX } from "./types";
import { cloneDeep, pullAt } from "lodash"


export function codeBlocksReducer(state: Array<CodeBlockContainer> = [], action: CodeBlocksActionTypes): Array<CodeBlockContainer> {
    switch (action.type) {
        case INIT_CODEBLOCKS:
            return Object.assign([], state, action.level.codeviews)
        case REMOVE_CODEBLOCK:
            return reduceRemoveBlock(state, action)
        case INSERT_CODEBLOCK:
            return reduceInsertBlock(state, action)
        default:
            return state
    }
}

const reduceRemoveBlock = (state: Array<CodeBlockContainer>, action: RemoveCodeBlockAction) => {
    let newState = cloneDeep(state)
    pullAt(newState[action.containerIdx].blocks, action.blocksIdx)
    return newState
}

const reduceInsertBlock = (state: Array<CodeBlockContainer>, action: InsertCodeBlockAction) => {
    if (state[action.containerIdx].blocks.length > state[action.containerIdx].nMaxBlocks)
        return state
    if (state[action.containerIdx].blocks.length == state[action.containerIdx].nMaxBlocks
        && !action.overwrite)
        return state
    let newState = cloneDeep(state)
    if (action.overwrite) {
        let bIdx = action.blocksIdx >= state[action.containerIdx].blocks.length ? state[action.containerIdx].blocks.length : action.blocksIdx;
        newState[action.containerIdx].blocks[bIdx] = action.block;
    }
    else {
        newState[action.containerIdx].blocks.splice(action.blocksIdx, 0, action.block)
    }
    return newState
}

export const opDropZoneZIdxReducer = (state: number = -1, action: SetDropZoneZIdxAction) => {
    switch (action.type) {
        case SET_DROPZONE_Z_INDEX:
            return action.zIdx
        default:
            return state
    }

}
