// @flow
import * as React from 'react';
import {
	Container,
	Row,
	Col,
	Button,
	Form,
	FormGroup,
	Label,
	Input,
	InputGroup,
	FormText,
	Collapse,
	Card,
	CardHeader,
	CardBody,
	TabContent, TabPane, Nav, NavItem, NavLink, CardTitle, CardText,
	FormFeedback,
	Alert,
	InputGroupAddon,
} from 'reactstrap';

import { connect } from 'react-redux';

import { getValidLibraryObj as getValidObj } from '@helpers/beat';
import type { BeatObject } from '@helpers/beat';
import { changeObjFieldName, copyObj } from '@helpers';

import * as Selectors from '@store/selectors.js';

import * as Actions from '@store/actions.js';
import ValidSchemaBadge from '../ValidSchemaBadge.jsx';
import CacheInput from '../CacheInput.jsx';
import DeleteInputBtn from '../DeleteInputBtn.jsx';
import TypedField from '../TypedField.jsx';
import TemplateButton from '../EntityTemplateGenerationButton.jsx';

type Props = {
	data: BeatObject,
	libraries: BeatObject[],
	saveFunc: (BeatObject) => any,
	updateFunc: (BeatObject) => any,
};

export class LibraryEditor extends React.Component<Props> {
	constructor(props: Props) {
		super(props);
	}

	setContents = (newContents: any) => {
		this.props.updateFunc({
			...this.props.data,
			contents: newContents
		});
	}

	updateLibraries = (libraries: {}) => {
		this.setContents({...this.props.data.contents, uses: libraries});
	}

	render = () => {
		const data = this.props.data;

		return (
			<div>
				<div className='d-flex'>
					<Button
						className='mx-auto'
						outline
						color='secondary'
						onClick={() => this.props.saveFunc(data)}
					>
						Save Changes (Changes are <ValidSchemaBadge entity='library' obj={data} />)
					</Button>
					<TemplateButton
						data={data}
						entity={'library'}
					/>
				</div>
				<Form onSubmit={(e) => e.preventDefault()}>
					<FormGroup tag='fieldset'>
						<legend>Library Settings</legend>
						<FormGroup>
							<Label for='description'>Short Description</Label>
							<CacheInput
								type='text'
								name='description'
								placeholder='Library description...'
								value={data.contents['description']}
								onChange={e => this.setContents({ ...data.contents, 'description': e.target.value})}
							/>
						</FormGroup>
						<FormGroup>
							<Label>Language</Label>
							<Input
								id='libLanguage'
								type='select'
								className='custom-select'
								value={data.contents.language}
								onChange={() => {}}
							>
								<option value='python'>Python</option>
								<option disabled value='cxx'>C++</option>
								<option disabled value='matlab'>Matlab</option>
								<option disabled value='r'>R</option>
							</Input>
						</FormGroup>
					</FormGroup>
					<FormGroup id='usedLibs'>
						<h4>Libraries Used</h4>
						{
							(Object.entries(data.contents.uses): [string, any][]).map(([name, lib], i) => (
								<TypedField
									key={i}
									name={name}
									type={lib}
									types={this.props.libraries.filter(l => l.name !== data.name).map(l => l.name)}
									existingFields={Object.keys(data.contents.uses)}
									nameUpdateFunc={str => {
										const newLibs = changeObjFieldName(data.contents.uses, name, str);
										this.updateLibraries(newLibs);
									}}
									typeUpdateFunc={str => {
										const newLibs = {
											...data.contents.uses,
											[name]: str
										};
										this.updateLibraries(newLibs);
									}}
									deleteFunc={() => {
										const newLibs = { ...data.contents.uses };
										delete newLibs[name];
										this.updateLibraries(newLibs);
									}}
								/>
							))
						}
						<Button
							outline
							block
							id='newLibrary'
							onClick={e => {
								let newKey = '';
								let v = 0;
								while(true) {
									const tryKey = `lib_${ v }`;
									if(Object.keys(data.contents.uses).includes(tryKey)){
										v++;
										continue;
									}
									newKey = tryKey;
									break;
								}

								this.updateLibraries({
									...data.contents.uses,
									[newKey]: ''
								});
							}}
						>
							Use Another Library
						</Button>
					</FormGroup>
				</Form>
			</div>
		);
	}
}

const mapStateToProps = (state, ownProps) => {
	const libs = Selectors.libraryGet(state);
	const obj = {
		libraries: libs,
		data: libs[ownProps.index] || getValidObj()
	};
	return obj;
};

const mapDispatchToProps = (dispatch, ownProps) => ({
	// replace the obj in the Redux store with the new object
	updateFunc: (obj) => {
		console.log(`dispatching for ${ obj.name }`);
		dispatch(Actions[`libraryUpdate`](obj.name, obj));
	},
});

export default connect(mapStateToProps, mapDispatchToProps)(LibraryEditor);
