/*!
 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
import React from 'react';

import i18n from 'nfvo-utils/i18n/i18n.js';
import Validator from 'nfvo-utils/Validator.js';

import Input from 'nfvo-components/input/validation/Input.jsx';
import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx';
import Form from 'nfvo-components/input/validation/Form.jsx';
import Button from 'sdc-ui/lib/react/Button.js';
import GridSection from 'nfvo-components/grid/GridSection.jsx';
import GridItem from 'nfvo-components/grid/GridItem.jsx';
import {optionsInputValues as  EntitlementPoolsOptionsInputValues, SP_ENTITLEMENT_POOL_FORM, tabIds}  from  './EntitlementPoolsConstants.js';
import {optionsInputValues as LicenseModelOptionsInputValues} from '../LicenseModelConstants.js';
import {validateStartDate, thresholdValueValidation} from '../LicenseModelValidations.js';
import {DATE_FORMAT} from 'sdc-app/onboarding/OnboardingConstants.js';
import {other as optionInputOther} from 'nfvo-components/input/validation/InputOptions.jsx';
import Tabs from 'sdc-ui/lib/react/Tabs.js';
import Tab from 'sdc-ui/lib/react/Tab.js';
import EntitlementPoolsLimits from './EntitlementPoolsLimits.js';
import {limitType, NEW_LIMIT_TEMP_ID} from '../limits/LimitEditorConstants.js';

const EntitlementPoolPropType = React.PropTypes.shape({
	id: React.PropTypes.string,
	name: React.PropTypes.string,
	description: React.PropTypes.string,
	operationalScope: React.PropTypes.shape({
		choices: React.PropTypes.array,
		other: React.PropTypes.string
	}),
	thresholdUnits: React.PropTypes.string,
	thresholdValue: React.PropTypes.number,
	increments: React.PropTypes.string,
	startDate: React.PropTypes.string,
	expiryDate: React.PropTypes.string
});

const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, validateName,
	 thresholdValueValidation, validateStartDate}) => {

	let {name, description, operationalScope, thresholdUnits, thresholdValue,
		increments, startDate, expiryDate} = data;
	return (
		<GridSection>
			<GridItem colSpan={2}>
				<Input
					onChange={name => onDataChanged({name}, SP_ENTITLEMENT_POOL_FORM, {name: validateName})}
					isValid={genericFieldInfo.name.isValid}
					isRequired={true}
					errorText={genericFieldInfo.name.errorText}
					label={i18n('Name')}
					value={name}
					data-test-id='create-ep-name'
					type='text'/>
			</GridItem>
			<GridItem colSpan={2}>
				<InputOptions
					onInputChange={()=>{}}
					isMultiSelect={true}
					onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}},
						SP_ENTITLEMENT_POOL_FORM)}
					onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER],
						other: operationalScope}}, SP_ENTITLEMENT_POOL_FORM)}
					label={i18n('Operational Scope')}
					data-test-id='create-ep-operational-scope'
					type='select'
					multiSelectedEnum={operationalScope && operationalScope.choices}
					otherValue={operationalScope && operationalScope.other}
					values={EntitlementPoolsOptionsInputValues.OPERATIONAL_SCOPE}
					isValid={genericFieldInfo.operationalScope.isValid}
					errorText={genericFieldInfo.operationalScope.errorText} />
			</GridItem>
			<GridItem colSpan={2} stretch>
				<Input
					onChange={description => onDataChanged({description}, SP_ENTITLEMENT_POOL_FORM)}
					isValid={genericFieldInfo.description.isValid}
					errorText={genericFieldInfo.description.errorText}
					label={i18n('Description')}
					value={description}
					data-test-id='create-ep-description'
					type='textarea'/>
			</GridItem>
			<GridItem colSpan={2}>
				<div className='threshold-section'>
					<Input
						onChange={e => {
							// setting the unit to the correct value
							const selectedIndex = e.target.selectedIndex;
							const val = e.target.options[selectedIndex].value;
							onDataChanged({thresholdUnits: val}, SP_ENTITLEMENT_POOL_FORM);
							// TODO make sure that the value is valid too
							if(thresholdValue && thresholdValue !== '') {
								onDataChanged({thresholdValue: thresholdValue}, SP_ENTITLEMENT_POOL_FORM,{thresholdValue : thresholdValueValidation});
							}}

						}
						value={thresholdUnits}
						label={i18n('Threshold Units')}
						data-test-id='create-ep-threshold-units'
						isValid={genericFieldInfo.thresholdUnits.isValid}
						errorText={genericFieldInfo.thresholdUnits.errorText}
						groupClassName='bootstrap-input-options'
						className='input-options-select'
						type='select' >
						{LicenseModelOptionsInputValues.THRESHOLD_UNITS.map(mtype =>
							<option key={mtype.enum} value={mtype.enum}>{`${mtype.title}`}</option>)}
					</Input>

					<Input
						className='entitlement-pools-form-row-threshold-value'
						onChange={thresholdValue => onDataChanged({thresholdValue}, SP_ENTITLEMENT_POOL_FORM,
							{thresholdValue : thresholdValueValidation})}
						label={i18n('Threshold Value')}
						isValid={genericFieldInfo.thresholdValue.isValid}
						errorText={genericFieldInfo.thresholdValue.errorText}
						data-test-id='create-ep-threshold-value'
						value={thresholdValue}
						type='text'/>
				</div>
				<Input
					onChange={increments => onDataChanged({increments}, SP_ENTITLEMENT_POOL_FORM)}
					label={i18n('Increments')}
					value={increments}
					data-test-id='create-ep-increments'
					type='text'/>
				<div className='date-section'>
					<Input
						type='date'
						label={i18n('Start Date')}
						value={startDate}
						dateFormat={DATE_FORMAT}
						startDate={startDate}
						endDate={expiryDate}
						onChange={startDate => onDataChanged(
							{startDate: startDate ? startDate.format(DATE_FORMAT) : ''},
							SP_ENTITLEMENT_POOL_FORM,
							{startDate: validateStartDate}
						)}
						isValid={genericFieldInfo.startDate.isValid}
						errorText={genericFieldInfo.startDate.errorText}
						selectsStart/>	
					<Input
						type='date'
						label={i18n('Expiry Date')}
						value={expiryDate}
						dateFormat={DATE_FORMAT}
						startDate={startDate}
						endDate={expiryDate}
						onChange={expiryDate => {
							onDataChanged({expiryDate: expiryDate ? expiryDate.format(DATE_FORMAT) : ''}, SP_ENTITLEMENT_POOL_FORM);
							onDataChanged({startDate}, SP_ENTITLEMENT_POOL_FORM, {startDate: validateStartDate});
						}}
						isValid={genericFieldInfo.expiryDate.isValid}
						errorText={genericFieldInfo.expiryDate.errorText}
						selectsEnd/>
				</div>							
			</GridItem>									
		</GridSection>
	);
};

class EntitlementPoolsEditorView extends React.Component {

	static propTypes = {
		data: EntitlementPoolPropType,
		previousData: EntitlementPoolPropType,
		EPNames: React.PropTypes.object,
		isReadOnlyMode: React.PropTypes.bool,
		onDataChanged: React.PropTypes.func.isRequired,
		onSubmit: React.PropTypes.func.isRequired,
		onCancel: React.PropTypes.func.isRequired
	};

	static defaultProps = {
		data: {}
	};

	componentDidUpdate(prevProps) {				
		if (this.props.formReady && this.props.formReady !== prevProps.formReady) { // if form validation succeeded -> continue with submit
			this.submit();
		}
	}
	
	state = {		
		selectedTab: tabIds.GENERAL,
		selectedLimit: ''
	};

	render() {
		let {data = {}, onDataChanged, isReadOnlyMode, genericFieldInfo, onCloseLimitEditor, limitsList = []} = this.props;
		const {selectedTab} = this.state;
		const isTabsDisabled = !data.id || !this.props.isFormValid;

		return (
			<div>
			<Tabs 
				type='menu' 
				activeTab={selectedTab} 
				onTabClick={(tabIndex)=>{
					if (tabIndex === tabIds.ADD_LIMIT_BUTTON)  {
						this.onAddLimit();
					} else {
						this.setState({selectedTab: tabIndex});
						this.setState({selectedLimit: ''});
						onCloseLimitEditor();
					}
					
				}} 
				invalidTabs={[]}>
				<Tab tabId={tabIds.GENERAL} data-test-id='general-tab' title={i18n('General')}>
					{
						genericFieldInfo && <Form
							ref='validationForm'
							hasButtons={false}						
							labledButtons={false}
							isReadOnlyMode={isReadOnlyMode}
							isValid={this.props.isFormValid}
							formReady={this.props.formReady}
							onValidateForm={() => this.props.onValidateForm(SP_ENTITLEMENT_POOL_FORM) }
							className='license-model-form entitlement-pools-form'>
							<EntitlementPoolsFormContent
								data={data}
								genericFieldInfo={genericFieldInfo}
								onDataChanged={onDataChanged}
								validateName={(value) => this.validateName(value)}
								validateStartDate={(value, state) => validateStartDate(value, state)}
								thresholdValueValidation={(value, state) => thresholdValueValidation(value, state)}/>
						</Form>
					}
				</Tab>
				<Tab disabled={isTabsDisabled} tabId={tabIds.SP_LIMITS} data-test-id='sp-limits-tab' title={i18n('SP Limits')}>
					{selectedTab === tabIds.SP_LIMITS && 
						<EntitlementPoolsLimits 
							isReadOnlyMode={isReadOnlyMode}
							limitType={limitType.SERVICE_PROVIDER} 
							limitsList={limitsList.filter(item => item.type === limitType.SERVICE_PROVIDER)}
							selectedLimit={this.state.selectedLimit}
							onCloseLimitEditor={() => this.onCloseLimitEditor()}
							onSelectLimit={limit => this.onSelectLimit(limit)}/>}
				</Tab>
				<Tab disabled={isTabsDisabled} tabId={tabIds.VENDOR_LIMITS} data-test-id='vendor-limits-tab' title={i18n('Vendor Limits')}>
					{selectedTab === tabIds.VENDOR_LIMITS && 
						<EntitlementPoolsLimits 
							isReadOnlyMode={isReadOnlyMode}
							limitType={limitType.VENDOR} 
							limitsList={limitsList.filter(item => item.type === limitType.VENDOR)}
							selectedLimit={this.state.selectedLimit}
							onCloseLimitEditor={() => this.onCloseLimitEditor()}
							onSelectLimit={limit => this.onSelectLimit(limit)}/>}
				</Tab>
				{
					selectedTab !== tabIds.GENERAL ?
						<Button
							disabled={this.state.selectedLimit || isReadOnlyMode}
							className='add-limit-button'
							tabId={tabIds.ADD_LIMIT_BUTTON}
							btnType='link'
							iconName='plus'>
							{i18n('Add Limit')}
						</Button>
					:
					<div></div> // Render empty div to not break tabs
				}
			</Tabs>
			<GridSection className='license-model-modal-buttons entitlement-pools-editor-buttons'>
				{!this.state.selectedLimit &&
					<Button btnType='default' disabled={!this.props.isFormValid || isReadOnlyMode} onClick={() => this.submit()} type='reset'>
						{i18n('Save')}
					</Button>
				}
			<Button btnType={this.state.selectedLimit ? 'default' : 'outline'} onClick={() => this.props.onCancel()} type='reset'>
				{i18n('Cancel')}
			</Button>
			</GridSection>	
			</div>
		);
	}

	submit() {
		const {data: entitlementPool, previousData: previousEntitlementPool, formReady} = this.props;

		if (!formReady) {
			this.props.onValidateForm(SP_ENTITLEMENT_POOL_FORM);
		} else {
			this.props.onSubmit({entitlementPool, previousEntitlementPool});
		}

		
	}

	validateName(value) {
		const {data: {id}, EPNames} = this.props;
		const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: EPNames});

		return !isExists ?  {isValid: true, errorText: ''} :
		{isValid: false, errorText: i18n('Entitlement pool by the name \'' + value + '\' already exists. Entitlement pool name must be unique')};
	}

	onSelectLimit(limit) {
		if (limit.id === this.state.selectedLimit) {
			this.setState({selectedLimit: ''});
			return;
		}
		this.setState({selectedLimit: limit.id});
		this.props.onOpenLimitEditor(limit);
	}

	onCloseLimitEditor() {
		this.setState({selectedLimit: ''});
		this.props.onCloseLimitEditor();
	}

	onAddLimit() {
		this.setState({selectedLimit: NEW_LIMIT_TEMP_ID});
		this.props.onOpenLimitEditor();
	}



}

export default EntitlementPoolsEditorView;
