const React = require('react');
const { connect } = require('react-redux');
const { Header } = require('./Header.min.js');
const { SideBar } = require('./SideBar.min.js');
const { NoteList } = require('./NoteList.min.js');
const { NoteText } = require('./NoteText.min.js');
const { PromptDialog } = require('./PromptDialog.min.js');
const { Setting } = require('lib/models/setting.js');
const { Tag } = require('lib/models/tag.js');
const { Note } = require('lib/models/note.js');
const { Folder } = require('lib/models/folder.js');
const { themeStyle } = require('../theme.js');
const { _ } = require('lib/locale.js');
const layoutUtils = require('lib/layout-utils.js');
const { bridge } = require('electron').remote.require('./bridge');

class MainScreenComponent extends React.Component {

	componentWillMount() {
		this.setState({
			promptOptions: null,
		});
	}

	componentWillReceiveProps(newProps) {
		if (newProps.windowCommand) {
			this.doCommand(newProps.windowCommand);
		}
	}

	toggleVisiblePanes() {
		this.props.dispatch({
			type: 'NOTE_VISIBLE_PANES_TOGGLE',
		});
	}

	async doCommand(command) {
		if (!command) return;

		const createNewNote = async (title, isTodo) => {
			const folderId = Setting.value('activeFolderId');
			if (!folderId) return;

			const note = await Note.save({
				title: title,
				parent_id: folderId,
				is_todo: isTodo ? 1 : 0,
			});
			Note.updateGeolocation(note.id);

			this.props.dispatch({
				type: 'NOTE_SELECT',
				id: note.id,
			});
		}

		let commandProcessed = true;

		if (command.name === 'newNote') {
			if (!this.props.folders.length) {
				bridge().showErrorMessageBox(_('Please create a notebook first.'));
				return;
			}

			this.setState({
				promptOptions: {
					label: _('Note title:'),
					onClose: async (answer) => {
						if (answer) await createNewNote(answer, false);
						this.setState({ promptOptions: null });
					}
				},
			});
		} else if (command.name === 'newTodo') {
			if (!this.props.folders.length) {
				bridge().showErrorMessageBox(_('Please create a notebook first'));
				return;
			}

			this.setState({
				promptOptions: {
					label: _('To-do title:'),
					onClose: async (answer) => {
						if (answer) await createNewNote(answer, true);
						this.setState({ promptOptions: null });
					}
				},
			});
		} else if (command.name === 'newNotebook') {
			this.setState({
				promptOptions: {
					label: _('Notebook title:'),
					onClose: async (answer) => {
						if (answer) {
							let folder = null;
							try {
								folder = await Folder.save({ title: answer }, { userSideValidation: true });		
							} catch (error) {
								bridge().showErrorMessageBox(error.message);
								return;
							}

							this.props.dispatch({
								type: 'FOLDER_SELECT',
								id: folder.id,
							});
						}

						this.setState({ promptOptions: null });
					}
				},
			});
		} else if (command.name === 'setTags') {
			const tags = await Tag.tagsByNoteId(command.noteId);
			const tagTitles = tags.map((a) => { return a.title });

			this.setState({
				promptOptions: {
					label: _('Add or remove tags:'),
					description: _('Separate each tag by a comma.'),
					value: tagTitles.join(', '),
					onClose: async (answer) => {
						if (answer !== null) {
							const tagTitles = answer.split(',').map((a) => { return a.trim() });
							await Tag.setNoteTagsByTitles(command.noteId, tagTitles);
						}
						this.setState({ promptOptions: null });
					}
				},
			});
		} else {
			commandProcessed = false;
		}

		if (commandProcessed) {
			this.props.dispatch({
				type: 'WINDOW_COMMAND',
				name: null,
			});
		}
	}

	render() {
		const style = this.props.style;
		const theme = themeStyle(this.props.theme);
		const promptOptions = this.state.promptOptions;
		const folders = this.props.folders;
		const notes = this.props.notes;

		const headerStyle = {
			width: style.width,
		};

		const rowHeight = style.height - theme.headerHeight;

		const sideBarStyle = {
			width: Math.floor(layoutUtils.size(style.width * .2, 150, 300)),
			height: rowHeight,
			display: 'inline-block',
			verticalAlign: 'top',
		};

		const noteListStyle = {
			width: Math.floor(layoutUtils.size(style.width * .2, 150, 300)),
			height: rowHeight,
			display: 'inline-block',
			verticalAlign: 'top',
		};

		const noteTextStyle = {
			width: Math.floor(layoutUtils.size(style.width - sideBarStyle.width - noteListStyle.width, 0)),
			height: rowHeight,
			display: 'inline-block',
			verticalAlign: 'top',
		};

		const promptStyle = {
			width: style.width,
			height: style.height,
		};

		const headerButtons = [];

		headerButtons.push({
			title: _('New note'),
			iconName: 'fa-file-o',
			enabled: !!folders.length,
			onClick: () => { this.doCommand({ name: 'newNote' }) },
		});
				
		headerButtons.push({
			title: _('New to-do'),
			iconName: 'fa-check-square-o',
			enabled: !!folders.length,
			onClick: () => { this.doCommand({ name: 'newTodo' }) },
		});

		headerButtons.push({
			title: _('New notebook'),
			iconName: 'fa-folder-o',
			onClick: () => { this.doCommand({ name: 'newNotebook' }) },
		});

		headerButtons.push({
			title: _('Layout'),
			iconName: 'fa-columns',
			enabled: !!notes.length,
			onClick: () => {
				this.toggleVisiblePanes();
			},
		});

		return (
			<div style={style}>
				<PromptDialog
					value={promptOptions && promptOptions.value ? promptOptions.value : ''}
					theme={this.props.theme}
					style={promptStyle}
					onClose={(answer) => promptOptions.onClose(answer)}
					label={promptOptions ? promptOptions.label : ''}
					description={promptOptions ? promptOptions.description : null}
					visible={!!this.state.promptOptions} />
				<Header style={headerStyle} showBackButton={false} buttons={headerButtons} />
				<SideBar style={sideBarStyle} />
				<NoteList style={noteListStyle} />
				<NoteText style={noteTextStyle} visiblePanes={this.props.noteVisiblePanes} />
			</div>
		);
	}

}

const mapStateToProps = (state) => {
	return {
		theme: state.settings.theme,
		windowCommand: state.windowCommand,
		noteVisiblePanes: state.noteVisiblePanes,
		folders: state.folders,
		notes: state.notes,
	};
};

const MainScreen = connect(mapStateToProps)(MainScreenComponent);

module.exports = { MainScreen };