import React, { Component } from 'react';
import _ from 'lodash';
import { View, ViewPropTypes, StyleSheet, FlatList } from 'react-native';
import { Text, TableCellFrame, TableCell, Switch, color } from 'nixplay-ui-kit';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

import i18n from '~/locale/i18n';
import { analytics } from '~/lib/utils';
import { attachLocalizedFrameName } from '~/lib/locale';

import { UPDATE_FRAME_PLAYLIST_ASSIGNMENT, SHOW_TOAST_ERROR } from '~/store/actionTypes';


const styles = StyleSheet.create({
	container: {
		backgroundColor: color.mistBlue01,
		borderTopWidth: 1,
		borderTopColor: color.mistBlue03,
	},
	title: {
		textAlign: 'center',
		paddingTop: 13,
		paddingBottom: 16,
	},
});

export class AssignPlaylistToFrame extends Component {
	static propTypes = {
		...ViewPropTypes,
		allFrames: PropTypes.array.isRequired,
		allFramesLoading: PropTypes.bool.isRequired,
		playlistId: PropTypes.number,
		playlistFrames: PropTypes.array,
		updateFrame: PropTypes.func.isRequired,
		onFramesChange: PropTypes.func,
		isConnected: PropTypes.bool.isRequired,
		toastError: PropTypes.func.isRequired,
		framePairing: PropTypes.object.isRequired,
	}

	static defaultProps = {
		onFramesChange: () => {},
		playlistId: -1,
		playlistFrames: [],
	}

	constructor(props) {
		super(props);

		this.state = {
			framesSwitch: {},
		};

		this.onToggleFrame = this.onToggleFrame.bind(this);
	}

	componentWillMount() {
		this.setInitialValues();
	}

	onToggleFrame(frameId, value) {
		this.setState({
			framesSwitch: {
				...this.state.framesSwitch,
				[frameId]: value,
			},
		}, () => {
			const frameIds = _.filter(
				_.keys(this.state.framesSwitch),
				(k) => this.state.framesSwitch[k] === true,
			);
			this.props.onFramesChange(_.map(frameIds, _.parseInt), frameId, value);
			if (this.props.playlistId !== -1) {
				this.props.updateFrame(frameId, this.props.playlistId, value ? 'add' : 'remove');
				if (value) {
					analytics.logAction('add_playlist_to_frame');
				} else {
					analytics.logAction('remove_playlist_from_frame');
				}
			}
		});
	}

	setInitialValues() {
		const values = {};
		this.props.playlistFrames.forEach((f) => {
			values[f.id] = true;
		});
		this.setState({ framesSwitch: values });
	}

	render() {
		const {
			style,
			allFrames,
			allFramesLoading,
			...others
		} = this.props;
		const opacity = (!_.isEmpty(allFrames)) ? 1 : 0;
		return (
			<View style={[styles.container, style]}>
				<Text style={[styles.title, { opacity }]}>{i18n.t('playlists.assignToFrame')}</Text>
				<FlatList
					{...others}
					data={allFrames}
					keyExtractor={(frame) => `${frame.id}`}
					loading={allFramesLoading}
					renderItem={({ item: frame, index }) => (
						<TableCellFrame
							frame={attachLocalizedFrameName(frame, this.props.framePairing, i18n.locale)}
						>
							<TableCell.Actions>
								<Switch
									name={`frame.assign${index}`}
									testID={`FrameAssign${index}`}
									value={this.state.framesSwitch[frame.id]}
									onValueChange={(v) => { this.onToggleFrame(frame.id, v); }}
									withEye
									disabled={!this.props.isConnected}
								/>
							</TableCell.Actions>
						</TableCellFrame>
					)}
				/>
			</View>
		);
	}
}

const mapStateToProps = (state) => ({
	allFrames: [...state.frames.frames].sort((a, b) => b.id - a.id),
	allFramesLoading: state.frames.meta.loading,
	isConnected: state.network.isConnected,
	framePairing: !_.isEmpty(_.get(state, 'framePairing.specs')) ? _.get(state, 'framePairing.specs') : [],
});

const mapActionsToProps = (dispatch) => ({
	updateFrame(frameId, playlistId, operation) {
		dispatch({
			type: UPDATE_FRAME_PLAYLIST_ASSIGNMENT,
			payload: {
				frameIds: [frameId],
				playlistIds: [playlistId],
				operation,
			},
		});
	},
	toastError(payload) {
		dispatch({ type: SHOW_TOAST_ERROR, payload });
	},
});

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