import React, { Component } from 'react';
import _ from 'lodash';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { submit, isSubmitting, SubmissionError } from 'redux-form';
import { View } from 'react-native';
import { Dialogue } from 'nixplay-ui-kit';
import { ModalNameForm } from '~comp/Forms/modalNameForm';
import { ModalForm } from '~comp/Forms/modalForm';
import { Form, TextInput2 } from '~comp/reduxForm';

import i18n from '~/locale/i18n';
import { analytics } from '~/lib/utils';
import {
	NAME_ALBUM_ANALYTICS,
} from '~/store/analyticsConstant';

import {
	CREATE_ALBUM,
	RENAME_ALBUM,
	DELETE_ALBUM,
	DELETE_ALBUM_CONTENT,
	UPDATE_CONTENT_CAPTION,
	SHOW_TOAST_ERROR,
} from '~/store/actionTypes';


export class AlbumActionsComponent extends Component {
	static propTypes = {
		actions: PropTypes.array,
		route: PropTypes.string.isRequired,
		deleteFormMeta: PropTypes.object.isRequired,
		submitDeleteForm: PropTypes.func.isRequired,
		isConnected: PropTypes.bool.isRequired,
		toastError: PropTypes.func.isRequired,
	}

	static defaultProps = {
		actions: [
			CREATE_ALBUM,
			RENAME_ALBUM,
			DELETE_ALBUM,
		],
	}

	constructor(props) {
		super(props);

		this.state = {
			selectedAction: '',
			selectedAlbumId: -1,
			selectedAlbumName: '',
			additionalParams: {},
			onActionSuccess: () => {},
		};

		this.dialogue = this.dialogue.bind(this);
		this.doAction = this.doAction.bind(this);
		this.closeAction = this.closeAction.bind(this);
		this.submitActionForm = this.submitActionForm.bind(this);
		this.actionExists = this.actionExists.bind(this);

		this.onSubmitFail = (errors) => {
			const { _error: error } = errors;
			this.props.toastError({
				text: typeof error.toString === 'function' ? error.toString() : error,
			});
		};
	}

	dialogue(action) {
		switch (action) {
			case DELETE_ALBUM:
				analytics.logAction('open_album_delete');
				return this.deleteDialogue;
			case DELETE_ALBUM_CONTENT:
				analytics.logAction('open_album_delete_content');
				return this.deleteContentDialogue;
			case UPDATE_CONTENT_CAPTION:
				analytics.logAction('open_album_edit_caption');
				return this.captionDialogue;
			default:
				analytics.logAction('open_album_rename');
				return this.modalNameForm;
		}
	}

	doAction(action, albumId, additionalParams, onActionSuccess) {
		if (this.props.actions.indexOf(action) < 0) return;
		this.setState({
			selectedAction: action,
			selectedAlbumId: albumId,
			selectedAlbumName: additionalParams.name,
			additionalParams,
			onActionSuccess,
		}, () => {
			this.dialogue(action).open();
		});
	}

	closeAction(callback, result) {
		this.dialogue(this.state.selectedAction).close();
		this.setState({
			selectedAction: '',
			selectedAlbumId: -1,
			selectedAlbumName: '',
			additionalParams: {},
			onActionSuccess: () => {},
		}, () => {
			if (typeof callback === 'function') callback(result);
		});
	}

	submitActionForm(values, dispatch) {
		return new Promise((resolve, reject) => {
			if (this.props.isConnected) {
				dispatch({
					type: this.state.selectedAction,
					payload: {
						...this.state.additionalParams,
						...values,
						albumId: this.state.selectedAlbumId,
						resolve,
						reject,
					},
				});
			} else {
				reject(new SubmissionError({ _error: i18n.t('common.noInternetConnection') }));
			}
		});
	}

	actionExists(actions) {
		return (_.intersection(this.props.actions, actions)).length > 0;
	}

	render() {
		const { selectedAlbumName, additionalParams } = this.state;

		let checkAndTranslateMyAlbums = '';
		if (additionalParams.name === 'My Uploads' && additionalParams.type === 'Email') {
			checkAndTranslateMyAlbums = i18n.t('common.myUploads');
		} else {
			checkAndTranslateMyAlbums = selectedAlbumName;
		}

		return (
			<View>
				{this.actionExists([CREATE_ALBUM, RENAME_ALBUM]) &&
				<ModalNameForm
					ref={(ref) => { this.modalNameForm = ref; }}
					form={`${this.props.route}NameForm`}
					onRequestClose={this.closeAction}
					onSubmit={this.submitActionForm}
					onSubmitSuccess={() => {
						this.closeAction(this.state.onActionSuccess);
						analytics.logEvent(NAME_ALBUM_ANALYTICS);
					}}
					onSubmitFail={(errors) => {
						this.onSubmitFail(errors);
						this.modalNameForm.reset();
					}}
					onCancel={this.closeAction}
					formTitle={this.state.selectedAction === CREATE_ALBUM ? i18n.t('albums.addNewAlbum') : i18n.t('albums.renameAlbum')}
					placeholder={i18n.t('albums.albumName')}
					initialValues={{ name: this.state.selectedAlbumName }}
					enableReinitialize
				/>}
				{this.actionExists([DELETE_ALBUM]) &&
				<Form
					form={`${this.props.route}DeleteForm`}
					onSubmit={this.submitActionForm}
					onSubmitSuccess={() => {
						this.closeAction(this.state.onActionSuccess);
					}}
					onSubmitFail={this.onSubmitFail}
				>
					<Dialogue
						ref={(ref) => { this.deleteDialogue = ref; }}
						loading={this.props.deleteFormMeta.submitting}
						withClose={false}
						onRequestClose={this.closeAction}
					>
						<Dialogue.Title>{i18n.t('albums.deleteAlbum')}</Dialogue.Title>
						<Dialogue.Description>{i18n.t('albums.deleteConfirmText', { albumName: checkAndTranslateMyAlbums })}</Dialogue.Description>
						<Dialogue.Action onPress={this.closeAction} testID="Cancel">{i18n.t('common.cancel')}</Dialogue.Action>
						<Dialogue.Action onPress={this.props.submitDeleteForm} color="red" testID="Delete">{i18n.t('common.delete')}</Dialogue.Action>
					</Dialogue>
				</Form>}
				{this.actionExists([DELETE_ALBUM_CONTENT]) &&
				<ModalForm
					ref={(ref) => { this.deleteContentDialogue = ref; }}
					form={`${this.props.route}DeleteContentForm`}
					onSubmit={this.submitActionForm}
					onSubmitSuccess={() => {
						this.closeAction(this.state.onActionSuccess);
					}}
					onSubmitFail={(errors) => {
						this.onSubmitFail(errors);
						this.deleteContentDialogue.reset();
					}}
					onCancel={this.closeAction}
					submitText={i18n.t('common.delete')}
					submitColor="red"
				>
					<Dialogue.Title>{i18n.t('common.permanentDelete')}</Dialogue.Title>
					<Dialogue.Description>{i18n.t('contents.deleteConfirmation')}</Dialogue.Description>
				</ModalForm>}
				{this.actionExists([UPDATE_CONTENT_CAPTION]) &&
				<ModalForm
					ref={(ref) => { this.captionDialogue = ref; }}
					form={`${this.props.route}UpdateCaption`}
					initialValues={{ caption: this.state.additionalParams.caption }}
					enableReinitialize
					onSubmit={this.submitActionForm}
					onSubmitSuccess={(result) => {
						this.closeAction(this.state.onActionSuccess, result);
					}}
					onSubmitFail={(errors) => {
						this.onSubmitFail(errors);
						this.captionDialogue.reset();
					}}
					onCancel={this.closeAction}
					submitText={i18n.t('common.ok')}
				>
					<Dialogue.Title>{i18n.t('contents.editCaption')}</Dialogue.Title>
					<Dialogue.Additional>
						<TextInput2 name="caption" testID="Caption" placeholder={i18n.t('contents.caption')} autoFocus multiline maxLength={160} />
					</Dialogue.Additional>
				</ModalForm>}
			</View>
		);
	}
}

const mapStateToProps = (state, ownProps) => {
	const { route } = ownProps;
	return {
		deleteFormMeta: {
			submitting: isSubmitting(`${route}DeleteForm`)(state),
		},
		isConnected: state.network.isConnected,
	};
};

const mapActionsToProps = (dispatch, ownProps) => {
	const { route } = ownProps;
	return {
		submitDeleteForm() {
			dispatch(submit(`${route}DeleteForm`));
		},
		toastError(payload) {
			dispatch({ type: SHOW_TOAST_ERROR, payload });
		},
	};
};


export default connect(
	mapStateToProps,
	mapActionsToProps,
	null,
	{ forwardRef: true },
)(AlbumActionsComponent);
