// External dependencies.
import React, { ReactElement } from 'react';

import {
	TextContainer,
	TextAreaContainer,
	ToggleContainer,
	SelectContainer,
	UploadContainer,
	ColorPickerContainer,
	RangeContainer,
} from '@divi/field-library';

import {
	FieldContainer
} from '@divi/module';

import { convertSimpleOptions, convertGroupedOptions } from './utils';

interface CustomControlProps {
	control: any;
	currentAttr: string;
	attr?: any;
	attributes?: any;
	getValue?: Function;
	prefix?: string;
	condition?: any;
}

class CustomControl extends React.Component<CustomControlProps> {

	normalizeConditionValue( value: any ) {
		if ( 'on' === value || 'true' === value || 1 === value || '1' === value ) {
			return true;
		}

		if ( 'off' === value || 'false' === value || 0 === value || '0' === value ) {
			return false;
		}

		return value;
	}

	isEnabled() {

		if ( ! this.props.condition ) {
			return true;
		}

		for ( var field in this.props.condition ) {

			var compare        = this.props.condition[ field ];
			var checked        = true;
			var isNotEqualCond = field.includes( '!' );

			if ( isNotEqualCond ) {
				field = field.replace( '!', '' );
			}

			if ( this.props.prefix ) {
				field = this.props.prefix + field;
			}

			var fieldVal = this.props.getValue ? this.props.getValue( field, this.props.attr, this.props.attributes ) : undefined;
			fieldVal = this.normalizeConditionValue( fieldVal );

			if ( isNotEqualCond ) {
				if ( Array.isArray( compare ) ) {
					checked = ! compare.map( item => this.normalizeConditionValue( item ) ).includes( fieldVal );
				} else {
					checked = fieldVal != this.normalizeConditionValue( compare );
				}
			} else {
				if ( Array.isArray( compare ) ) {
					checked = compare.map( item => this.normalizeConditionValue( item ) ).includes( fieldVal );
				} else {
					checked = fieldVal == this.normalizeConditionValue( compare );
				}
			}

			if ( ! checked ) {
				return false;
			}

		}

		return true;
	}

	render() {

		const {
			control,
			currentAttr
		} = this.props;

		if ( ! this.isEnabled() ) {
			return null;
		}

		const description = control.description || '';

		switch ( control.type ) {

			case 'select':
			case 'select2':

				let options: any[] = [];

				if ( control.options && control.options.length ) {

					options = [ ...control.options ];

					if ( control.placeholder ) {
						options.unshift( {
							value: '',
							label: control.placeholder,
						} );
					}

				}

				if ( control.groups ) {
					return <React.Fragment>
						<FieldContainer
							attrName={ currentAttr }
							label={ control.label }
							description={ description }
						>
							<SelectContainer
								options={ convertGroupedOptions( control.groups ) }
							/>
						</FieldContainer>
					</React.Fragment>;
				} else {
					return <React.Fragment>
						<FieldContainer
							attrName={ currentAttr }
							label={ control.label }
							description={ description }
						>
							<SelectContainer
								options={ convertSimpleOptions( options ) }
							/>
						</FieldContainer>
					</React.Fragment>;
				}

			case 'color':
				return <React.Fragment>
					<FieldContainer
						attrName={ currentAttr }
						label={ control.label }
						description={ description }
					>
						<ColorPickerContainer />
					</FieldContainer>
				</React.Fragment>;

			case 'media':
				return <React.Fragment>
					<FieldContainer
						attrName={ currentAttr }
						label={ control.label }
						description={ description }
					>
						<UploadContainer />
					</FieldContainer>
				</React.Fragment>;

			case 'range':
				return <React.Fragment>
					<FieldContainer
						attrName={ currentAttr }
						label={ control.label }
						description={ description }
					>
						<RangeContainer
							min={ control.min ?? 0 }
							max={ control.max ?? 100 }
							step={ control.step ?? 1 }
							unit={ [] }
						/>
					</FieldContainer>
				</React.Fragment>;

			case 'raw_html':
				return <React.Fragment>
					<div
						dangerouslySetInnerHTML={ { __html: control.raw || '' } }
					/>
				</React.Fragment>;

			case 'textarea':
				return <React.Fragment>
					<FieldContainer
						attrName={ currentAttr }
						label={ control.label }
						description={ description }
					>
						<TextAreaContainer />
					</FieldContainer>
				</React.Fragment>;

			case 'switcher':
				return <React.Fragment>
					<FieldContainer
						attrName={ currentAttr }
						label={ control.label }
						description={ description }
					>
						<ToggleContainer />
					</FieldContainer>
				</React.Fragment>;

			case 'number':
				return <React.Fragment>
					<FieldContainer
						attrName={ currentAttr }
						label={ control.label }
						description={ description }
					>
						<TextContainer />
					</FieldContainer>
				</React.Fragment>;

			default:
				return <React.Fragment>
					<FieldContainer
						attrName={ currentAttr }
						label={ control.label }
						description={ description }
					>
						<TextContainer />
					</FieldContainer>
				</React.Fragment>;
		}
	}
}

export default CustomControl;
