import React, { Component } from 'react';
import { View, TouchableOpacity, Dimensions, Image } from 'react-native';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { color, NixplayIcon as Icon, Loading, Thumbnail, ImageIcon } from 'nixplay-ui-kit';
import { getDimensions } from '~/lib/frames';
import { debounceWrapper, analytics } from '~/lib/utils';
import { frameColors, FRAME_POWER } from '~/store/frameConstants';

import { bezel } from '~/images';

import placeholder from '~/images/home/frame-empty.jpg';
import tutorialBg from '~/images/home/frame-bg.jpg';
import welcomeEn from '~/images/home/frame-welcome-en.png';
import welcomeDe from '~/images/home/frame-welcome-de.png';
import welcomeJap from '~/images/home/frame-welcome-jap.png';

const styles = {
	container: {
		height: '100%',
		width: '100%',
		alignItems: 'center',
		justifyContent: 'center',
		top: 0,
	},
	frame: {
		height: '100%',
		width: '100%',
		zIndex: 2,
	},
	frameImage: {
		height: '100%',
		width: '100%',
		zIndex: 1,
		alignItems: 'center',
		justifyContent: 'center',
		shadowColor: '#000',
		shadowOffset: { width: 0, height: 4 },
		shadowOpacity: 0.4,
		shadowRadius: 4,
	},
	noPhotos: {
		position: 'absolute',
		backgroundColor: color.mistBlue05,
		alignItems: 'center',
		justifyContent: 'center',
	},
	thumbImage: {
		width: '100%',
		height: '100%',
		overflow: 'hidden',
	},
	loadingContainer: {
		height: '100%',
		alignItems: 'center',
		justifyContent: 'center',
	},
};

const TRANSITION_TIME = 5000;

const TouchableOpacityEx = debounceWrapper(TouchableOpacity);

function getBezel(frameModel, frameColor, frameOrientation, bezelLinks) {
	if (frameModel.includes('W07A') ||
		frameModel.includes('W13B') ||
		frameModel.includes('W10B') ||
		frameModel.includes('W13C')) {
		switch (frameColor) {
			case frameColors.BLUE:
				return frameOrientation === 'landscape' ? bezel.seed07BlueLandscape : bezel.seed07BluePortrait;
			case frameColors.MANGO:
				return frameOrientation === 'landscape' ? bezel.seed07MangoLandscape : bezel.seed07MangoPortrait;
			case frameColors.MULBERRY:
				return frameOrientation === 'landscape' ? bezel.seed07MulberryLandscape : bezel.seed07MulberryPortrait;
			default:
				return frameOrientation === 'landscape' ? bezel.seed07BlackLandscape : bezel.seed07BlackPortrait;
		}
	} else if (frameModel.includes('W10J') || frameModel.includes('W10F')) {
		switch (frameColor) {
			case frameColors.BLACK:
				return frameOrientation === 'landscape' ? bezel.seed10FBlackLandscape : bezel.seed10FBlackPortrait;
			case frameColors.WOOD:
				return frameOrientation === 'landscape' ? bezel.seed10FWoodLandscape : bezel.seed10FWoodPortrait;
			default:
				return frameOrientation === 'landscape' ? bezel.seed10FBlackLandscape : bezel.seed10FBlackPortrait;
		}
	} else if (frameModel.includes('W08D') ||
		frameModel.includes('W10A')) {
		switch (frameColor) {
			case frameColors.BLUE:
				return frameOrientation === 'landscape' ? bezel.seed08BlueLandscape : bezel.seed08BluePortrait;
			case frameColors.MANGO:
				return frameOrientation === 'landscape' ? bezel.seed08MangoLandscape : bezel.seed08MangoPortrait;
			case frameColors.MULBERRY:
				return frameOrientation === 'landscape' ? bezel.seed08MulberryLandscape : bezel.seed08MulberryPortrait;
			case frameColors.WOOD:
				return frameOrientation === 'landscape' ? bezel.seed08WoodLandscape : bezel.seed08WoodPortrait;
			case frameColors.WHITE:
				return frameOrientation === 'landscape' ? bezel.seed10WhiteLandscape : bezel.seed10WhitePortrait;
			default:
				return frameOrientation === 'landscape' ? bezel.seed08BlackLandscape : bezel.seed08BlackPortrait;
		}
	} else if (frameModel.includes('W08E')) {
		switch (frameColor) {
			case frameColors.BRONZE:
				return frameOrientation === 'landscape' ? bezel.iris08BronzeLandscape : bezel.iris08BronzePortrait;
			case frameColors.COPPER:
				return frameOrientation === 'landscape' ? bezel.iris08RosegoldLandscape : bezel.iris08RosegoldPortrait;
			case frameColors.SILVER:
				return frameOrientation === 'landscape' ? bezel.iris08SilverLandscape : bezel.iris08SilverPortrait;
			default:
				return frameOrientation === 'landscape' ? bezel.iris08BronzeLandscape : bezel.iris08BronzePortrait;
		}
	} else if (frameModel.includes('W08A') || frameModel.includes('W08B') || frameModel.includes('W12') || frameModel.includes('W15')) {
		return frameOrientation === 'landscape' ? bezel.original12BlackLandscape : bezel.original12BlackPortrait;
	} else if (frameModel.includes('W08C')) {
		return frameOrientation === 'landscape' ? bezel.edge08BlackLandscape : bezel.edge08BlackPortrait;
	} else if (frameModel.includes('W13A')) {
		return frameOrientation === 'landscape' ? bezel.edge13BlackLandscape : bezel.edge13BlackPortrait;
	} else if (frameModel.includes('W18')) {
		return frameOrientation === 'landscape' ? bezel.original18BlackLandscape : bezel.original18BlackPortrait;
	} else if (!_.isEmpty(bezelLinks[frameOrientation])) {
		return { uri: bezelLinks[frameOrientation] };
	} else {
		return frameOrientation === 'landscape' ? bezel.original12BlackLandscape : bezel.original12BlackPortrait;
	}
}

function getPlaceHolderIcon(props) {
	if (props.needUpdate) {
		return 'invalid';
	} else if (!props.isConnected) {
		return 'plug';
	} else if (props.power === FRAME_POWER.OFF) {
		return 'sleep';
	} else if (props.isConnected && props.noPlaylistAssigned) {
		return 'playlist';
	} else if (props.isConnected && _.isEmpty(props.thumbs)) {
		return 'photo-broken';
	}
	return 'plug';
}

export class Bezel extends Component {
	constructor(props) {
		super(props);

		const { height: deviceHeight, width: deviceWidth } = Dimensions.get('window');
		const height = props.orientation === 'landscape' ? deviceWidth / 2.2 : deviceHeight / 3.2;
		const width = props.orientation === 'landscape' ? deviceHeight / 3.2 : deviceWidth / 2.2;
		const thumbDimensions = { width, height };

		this.state = {
			thumbDimensions,
			thumbnail: this.props.thumbs[0] || { url: '', rotation: 0 },
			counter: 0,
			loading: true,
			bezelSettings: getBezel(props.model, props.color, props.orientation, this.props.bezel),
			opened: false,
		};
		this.onLayout = this.onLayout.bind(this);
		this.startCarousel = this.startCarousel.bind(this);
		this.thumbnailPressed = this.thumbnailPressed.bind(this);
	}

	componentDidMount() {
		if (this.props.power === FRAME_POWER.ON) {
			this.startCarousel();
		}
	}

	componentWillReceiveProps(nextProps) {
		if (this.state.thumbnail.url === '' && nextProps.thumbs[0] && !_.isEmpty(nextProps.thumbs[0].url)) {
			this.setState({ thumbnail: nextProps.thumbs[0] });
		}

		if (nextProps.model !== this.props.model ||
			nextProps.color !== this.props.color ||
			nextProps.orientation !== this.props.orientation) {
			this.setState({
				bezelSettings: getBezel(nextProps.model, nextProps.color, nextProps.orientation, this.props.bezel),
			});
		}

		if (nextProps.carousel !== this.props.carousel && nextProps.power === FRAME_POWER.ON) {
			if (nextProps.carousel) {
				this.startCarousel(this.state.counter);
			}
		} else if (nextProps.power !== this.props.power && nextProps.power === FRAME_POWER.ON) {
			this.startCarousel(this.state.counter);
		}
	}

	shouldComponentUpdate(nextProps, nextState) {
		if ((_.isEqual(this.props, nextProps) && _.isEqual(this.state, nextState)) ||
			!_.isEqual(_.get(this.props, 'currentFrame.meta'), _.get(nextProps, 'currentFrame.meta'))) {
			return false;
		}
		return true;
	}

	componentDidUpdate(prevProps) {
		if (prevProps.playlistId !== this.props.playlistId) {
			this.startCarousel(this.state.counter);
		}
	}

	componentWillUnmount() {
		clearTimeout(this.timer);
	}

	onLayout({ nativeEvent: { layout: { width, height } } }) {
		const bezelSettings = getBezel(this.props.model, this.props.color, this.props.orientation, this.props.bezel);
		const thumbDimensions = getDimensions({
			width,
			height,
			orientation: this.props.orientation,
			dimensions: this.props.dimensions,
		});

		this.setState({
			thumbDimensions,
			loading: false,
			bezelSettings,
		});
	}

	startCarousel(index = 0) {
		if (!_.isEmpty(this.props.thumbs) && index === this.state.counter) {
			const counter = (index < (this.props.thumbs.length - 1)) ? index + 1 : 0;
			const thumbnail = this.props.thumbs[counter] || { url: '', rotation: 0 };
			this.setState({ thumbnail, counter });
			this.timer = setTimeout(() => {
				if (this.props.carousel && this.props.power === FRAME_POWER.ON) {
					this.startCarousel(counter);
				}
			}, TRANSITION_TIME);
		}
		return null;
	}

	thumbnailPressed() {
		analytics.logAction('tap_mini_frame');
		if (!this.state.opened) {
			this.props.openPlaylist(this.props.playlistId);
			this.setState({ opened: true });
			setTimeout(() => this.setState({ opened: false }), 1500);
		}
	}

	renderWelcome = () => {
		const { languageCode } = this.props;
		let imageIcon;
		if (_.startsWith(languageCode, 'de')) {
			imageIcon = welcomeDe;
		} else if (_.startsWith(languageCode, 'ja')) {
			imageIcon = welcomeJap;
		} else {
			imageIcon = welcomeEn;
		}
		return (<ImageIcon
			height={this.state.thumbDimensions.height}
			width={this.state.thumbDimensions.width}
			icon={imageIcon}
			imageSrc={tutorialBg}
			style={{ position: 'absolute' }}
			imageOverlay
			overlayStyle={{ maxHeight: 64, maxWidth: '90%' }}
		/>);
	}

	render() {
		const showNormalCarousel = this.props.isConnected && !_.isEmpty(this.props.thumbs);
		const placeholderIcon = getPlaceHolderIcon(this.props);
		const userHasNoPlaylists = this.props.playlistLength < 1;
		return (
			<View style={styles.container}>
				<TouchableOpacityEx
					style={styles.frame}
					activeOpacity={1}
					onPress={this.thumbnailPressed}
				>
					<Image
						source={this.state.bezelSettings}
						style={styles.frameImage}
						resizeMode="contain"
						fadeDuration={0}
						onLayout={this.onLayout}
						key={this.props.orientation}
					/>
				</TouchableOpacityEx>
				{showNormalCarousel && !this.props.showTutorial && !this.state.loading &&
					<View style={{ position: 'absolute', height: this.state.thumbDimensions.height, width: this.state.thumbDimensions.width }}>
						{this.props.power === FRAME_POWER.OFF && !this.props.needUpdate &&
							<View
								style={[styles.noPhotos, {
									zIndex: 1, position: 'absolute', height: this.state.thumbDimensions.height, width: this.state.thumbDimensions.width,
								}]
								}
								opacity={0.7}
							>
								<Icon name="sleep" testID="Sleep" color="white" size={36} style={{ zIndex: 100 }} />
							</View>
						}
						{!_.isEmpty(this.state.thumbnail.url) &&
							<Thumbnail
								source={{ uri: this.state.thumbnail.url }}
								style={styles.thumbImage}
								resizeMode="cover"
								fadeDuration={1000}
								transform={[{ rotate: `${this.state.thumbnail.rotation}deg` }]}
							/>
						}
						{_.isEmpty(this.state.thumbnail.url) &&
							<View
								style={[styles.loadingContainer, { backgroundColor: color.mistBlue05 }]}
								opacity={0.5}
							>
								<Loading />
							</View>
						}

					</View>

				}
				{((!showNormalCarousel && !this.props.showTutorial && !this.state.loading)
					|| (this.props.needUpdate && this.props.power === FRAME_POWER.OFF)) &&
					<ImageIcon
						height={this.state.thumbDimensions.height}
						width={this.state.thumbDimensions.width}
						icon={placeholderIcon}
						imageSrc={placeholder}
						style={{ position: 'absolute' }}
					/>
				}
				{(this.props.showTutorial || (_.isEmpty(this.props.thumbs) && userHasNoPlaylists)) &&
					this.renderWelcome()
				}
			</View>
		);
	}
}

Bezel.propTypes = {
	bezel: PropTypes.object.isRequired,
	model: PropTypes.string.isRequired,
	color: PropTypes.string.isRequired,
	orientation: PropTypes.string.isRequired,
	thumbs: PropTypes.array.isRequired,
	playlistLength: PropTypes.number,
	carousel: PropTypes.bool,
	power: PropTypes.string.isRequired,
	openPlaylist: PropTypes.func.isRequired,
	isConnected: PropTypes.bool,
	playlistId: PropTypes.number,
	dimensions: PropTypes.object,
	showTutorial: PropTypes.bool,
	needUpdate: PropTypes.bool,
	languageCode: PropTypes.string,
};

Bezel.defaultProps = {
	carousel: true,
	playlistId: -1,
	playlistLength: 0,
	isConnected: false,
	dimensions: { height: 600, width: 800 },
	showTutorial: false,
	needUpdate: false,
	languageCode: '',
};
