import {IoTyConstants} from 'constants/IoTy'


let defaultState = {
	arduinoLoaded : false,
	existedCircuitData : [],
	codeData : {},
	steps : [],
	currentStep : 1,
	output : {},
	userSelectedStepOptions : [
		{
			stepId : -1,
			stepType : 'TYPE_CIRCUIT',
			componentId : -1,
			componentOptionId : -1,
			codeId : -1,
			blankId : -1,
			blankOptionId : -1
		}
	],
	thresholdValue : -1,
	pushButtonState : '',
	wifiSettings : {}
}

let defaultSelectedStepOptions = {
	stepId : -1,
	stepType : 'TYPE_CIRCUIT',
	componentId : -1,
	componentOptionId : -1,
	codeId : -1,
	blankId : -1,
	blankOptionId : -1
}
function addLockedStateToSteps (steps) {
  let updatedSteps = steps.map(function (step, index) {
    step.isLocked = (index !== 0);
    return step;
  });
  return updatedSteps;
}

export function IoTyReducer (state = defaultState, action) {
	switch (action.type) {
		case IoTyConstants.ARDUINO_LOADED:
			return Object.assign(
				{},
				state,
				{
					arduinoLoaded : action.arduinoLoaded
				}
			)
		case IoTyConstants.SET_EXISTED_CIRCUIT_DATA:
			return Object.assign(
				{},
				state,
				{
					existedCircuitData : action.existedCircuitData,
					codeData : action.existedCodeData
				}
			)
		case IoTyConstants.SET_NEW_CIRCUIT_DATA:
			let updatedUserSelectedStepOptions = state.userSelectedStepOptions
			let steps = action.steps
			for(let i=0;i<steps.length;i++) {
				steps[i].stepNumber = i+1
				if (i == 0) {
					updatedUserSelectedStepOptions[0].stepId = steps[i].stepId
				}
			}
			steps = addLockedStateToSteps(steps)
			let temp = {
				steps : steps,
				userSelectedStepOptions : updatedUserSelectedStepOptions
			}
			if (action.hasOwnProperty('output')) {
				temp.output = action.output
			}
			return Object.assign(
				{},
				state,
				temp
			)
		/*case IoTyConstants.SET_STEPS:
			let updatedUserSelectedStepOptions = state.userSelectedStepOptions
			let steps = action.steps
			for(let i=0;i<steps.length;i++) {
				steps[i].stepNumber = i+1
				if (i == 0) {
					updatedUserSelectedStepOptions[0].stepId = steps[i].stepId
				}
			}
			steps = addLockedStateToSteps(steps)
			return Object.assign(
				{},
				state,
				{
					steps : steps,
					userSelectedStepOptions : updatedUserSelectedStepOptions
				}
			)
		case IoTyConstants.SET_POSSIBLE_OUTPUTS:
			return Object.assign(
				{},
				state,
				{
					output : action.output
				}
			)*/
		case IoTyConstants.GO_TO_PREV_STEP:
			return Object.assign(
				{},
				state,
				{
					currentStep : state.currentStep - 1
				}
			)
		case IoTyConstants.GO_TO_NEXT_STEP:
			let nextStepDetails = state.steps[state.currentStep === state.steps.length ? state.currentStep-1 : state.currentStep]
			// console.log(nextStepDetails);
			let updatedSelectedStepOptions = {
				...defaultSelectedStepOptions,
				stepId : nextStepDetails.stepId,
				codeId : nextStepDetails.hasOwnProperty('codeBlank') ? nextStepDetails.codeBlank.codeId : -1,
				blankId : nextStepDetails.hasOwnProperty('codeBlank') ? nextStepDetails.codeBlank.blankId : -1
			}
			let existed = false
			for (let i=0;i<state.userSelectedStepOptions.length;i++) {
				if (state.userSelectedStepOptions[i].stepId === updatedSelectedStepOptions.stepId) {
					existed = true
					break
				}
			}
			updatedUserSelectedStepOptions = existed ? state.userSelectedStepOptions : state.userSelectedStepOptions.concat([updatedSelectedStepOptions])
			return Object.assign(
				{},
				state,
				{
					currentStep : state.currentStep + 1,
					userSelectedStepOptions : updatedUserSelectedStepOptions
				}
			)
		case IoTyConstants.GO_TO_STEP:
			nextStepDetails = state.steps[state.currentStep === state.steps.length ? state.currentStep-1 : state.currentStep]
			updatedSelectedStepOptions = {
				...defaultSelectedStepOptions,
				stepId : state.steps[action.step-1].stepId,
				codeId : nextStepDetails.hasOwnProperty('codeBlank') ? nextStepDetails.codeBlank.codeId : -1,
				blankId: nextStepDetails.hasOwnProperty('codeBlank') ? nextStepDetails.codeBlank.blankId : -1
			}
			existed = false
			for (let i=0;i<state.userSelectedStepOptions.length;i++) {
				if (state.userSelectedStepOptions[i].stepId === updatedSelectedStepOptions.stepId) {
					existed = true
					break
				}
			}
			updatedUserSelectedStepOptions = existed ? state.userSelectedStepOptions : state.userSelectedStepOptions.concat([updatedSelectedStepOptions])
			return Object.assign(
				{},
				state,
				{
					currentStep : action.step,
					userSelectedStepOptions : updatedUserSelectedStepOptions
				}
			)
		case IoTyConstants.SELECT_COMPONENT:
			updatedUserSelectedStepOptions = state.userSelectedStepOptions.map(function (userSelectedStepOption, index) {
				if (state.currentStep - 1 === index) {
					return {
						...userSelectedStepOption,
						componentId: Number(action.selectedComponentId),
						componentOptionId : -1
					}
				} else {
					return userSelectedStepOption
				}
			})
			return Object.assign(
				{},
				state,
				{
					userSelectedStepOptions : updatedUserSelectedStepOptions
				}
			)
		case IoTyConstants.SELECT_CIRCUIT_OPTION:
			updatedUserSelectedStepOptions = state.userSelectedStepOptions.map(function (userSelectedStepOption, index) {
				if (state.currentStep - 1 === index) {
					return {
						...userSelectedStepOption,
						componentOptionId: Number(action.selectedCircuitOptionId)
					}
				} else {
					return userSelectedStepOption
				}
			})
			return Object.assign(
				{},
				state,
				{
					userSelectedStepOptions : updatedUserSelectedStepOptions
				}
			)
		case IoTyConstants.SELECT_CODE_OPTION:
			updatedUserSelectedStepOptions = state.userSelectedStepOptions.map(function (userSelectedStepOption, index) {
				if (state.currentStep - 1 === index) {
					return {
						...userSelectedStepOption,
						codeId : state.steps[state.currentStep - 1].codeBlank.codeId,
						blankId : state.steps[state.currentStep - 1].codeBlank.blankId,
						blankOptionId: Number(action.selectedCodeOptionId)
					}
				} else {
					return userSelectedStepOption
				}
			})
			return Object.assign(
				{},
				state,
				{
					userSelectedStepOptions : updatedUserSelectedStepOptions
				}
			)
		case IoTyConstants.SET_CODE_ANSWER:
			updatedUserSelectedStepOptions = state.userSelectedStepOptions.map(function (userSelectedStepOption, index) {
				if (state.currentStep-1 === index) {
					return {
						...userSelectedStepOption,
						blankValue : action.codeAnswer
					}
				} else {
					return userSelectedStepOption
				}
			})
			return Object.assign(
				{},
				state,
				{
					userSelectedStepOptions : updatedUserSelectedStepOptions
				}
			)
		case IoTyConstants.STEP_COMPLETED:
			steps = state.steps.map(function (step, index) {
				if (state.currentStep === index) {
					return {
						...step,
						isLocked : action.isLocked
					}
				} else {
					return step
				}
			}) 
			let currentStepDetails = state.steps[state.currentStep - 1]
			let userSelectedStepOptions = state.userSelectedStepOptions
			let currentStepSelectedOptions = state.userSelectedStepOptions[state.currentStep - 1]
			updatedUserSelectedStepOptions = userSelectedStepOptions.map(function (userSelectedStepOption, index) {
				if (state.currentStep-1 === index) {
					return {
						...userSelectedStepOption,
						stepId : currentStepDetails.stepId,
						stepType : currentStepDetails.stepType
					}
				} else {
					return userSelectedStepOption
				}
			})
			// console.log('userSelectedStepOptions, currentStepSelectedOptions', userSelectedStepOptions, currentStepSelectedOptions);
			return Object.assign(
				{},
				state,
				{
					steps : steps,
					userSelectedStepOptions : updatedUserSelectedStepOptions
				}
			)
		case IoTyConstants.CHANGE_THRESHOLD_VALUE:
			return Object.assign(
				{},
				state,
				{
					thresholdValue : action.thresholdValue
				}
			)
		case IoTyConstants.SET_PUSH_BUTTON_STATE:
			return Object.assign(
				{},
				state,
				{
					pushButtonState : action.pushButtonState
				}
			)
		case IoTyConstants.CONFIG_WIFI:
			return Object.assign(
				{},
				state,
				{
					wifiSettings : action.wifiSettings
				}
			)
		default:
			return state
	}
}
export default {
	IoTyReducer
}