/* eslint-disable react/prop-types */
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';

import {
	StyleSheet,
	View,
	TouchableOpacity,
	Animated,
	Dimensions,
	InteractionManager,
	FlatList,
} from 'react-native';
import {
	NixplayIcon,
	color,
	Text,
} from 'nixplay-ui-kit';
import _ from 'lodash';

import setTestID from '~/test/testUtils';
import * as TEST_IDS from '~/store/testIDConstants';

// TODO:
// 1. Fix header style for albums instead of using header height - keembee
// 2. a better approach for rendering the children - keembee

const Screen = {
	height: Dimensions.get('window').height,
	width: Dimensions.get('window').width,
};

const HEADER_HEIGHT = 100;
const THUMB_HEIGHT = Screen.width / 3;

const styles = StyleSheet.create({
	container: {
		flex: 1,
		backgroundColor: color.white,
	},
	touchableContainer: {
		justifyContent: 'flex-end',
		padding: 12,
	},
	iconContainer: {
		flex: 1,
		width: '100%',
		position: 'absolute',
		backgroundColor: color.white,
		top: 0,
		height: 50,
		flexDirection: 'row',
		justifyContent: 'space-between',
	},
	placeholderEmpty: {
		width: THUMB_HEIGHT,
		height: THUMB_HEIGHT,
		margin: 1,
		backgroundColor: color.mistBlue03,
	},
});

class CollapsibleHeader extends PureComponent {
	static propTypes = {
		toggleMode: PropTypes.bool,
		selectMode: PropTypes.bool,
		fetchData: PropTypes.func,
		loadMoreData: PropTypes.func,
		navigation: PropTypes.object,
		count: PropTypes.number,
		title: PropTypes.string,
		subtitle: PropTypes.object,
		rightIconPress: PropTypes.func,
		onRefresh: PropTypes.func,
		refreshing: PropTypes.bool,
		paginate: PropTypes.bool,
		hasMore: PropTypes.bool,
	}

	static defaultProps = {
		toggleMode: false,
		selectMode: false,
		fetchData: () => {},
		loadMoreData: () => {},
		navigation: {},
		count: 1,
		title: '',
		subtitle: {},
		rightIconPress: {},
		onRefresh: () => {},
		refreshing: false,
		paginate: false,
		hasMore: false,
	}

	constructor(props) {
		super(props);

		this.state = {
			isDoneAnimating: false,
			scrollY: new Animated.Value(0),
			opacity: new Animated.Value(0.5), // init opacity 0
		};
	}

	componentDidMount() {
		InteractionManager.runAfterInteractions(() => {
			this.setState({ isDoneAnimating: true }, () => {
				Animated.timing(
					// Uses easing functions
					this.state.opacity, // The value to drive
					{
						toValue: 1,
						duration: 100,
						useNativeDriver: true,
					}, // Configuration
				).start(() => {
					this.fetchData();
				}); // Don't forget start!
			});
		});
	}

	getScale = () => {
		const { scrollY } = this.state;

		return scrollY.interpolate({
			inputRange: [0, 50],
			outputRange: [1.5, 1],
			extrapolate: 'clamp',
		});
	}

	getHeaderHeight = () => {
		const { scrollY } = this.state;

		return scrollY.interpolate({
			inputRange: [0, 50],
			outputRange: [0, -50],
			extrapolateRight: 'clamp',
		});
	}

	goBack = () => {
		this.setState({ isDoneAnimating: false }, () => {
			this.props.navigation.goBack();
		});
	}

	fetchData = () => {
		this.props.fetchData();
	}

	handleLoadMore = () => {
		if (!this.props.hasMore) return;
		this.props.loadMoreData();
	}

	keyExtractor = (item, index) => `${item.id}-${index}`;

	renderPlaceholder = () => (
		<FlatList
			data={_.range(this.props.count > 12 ? 12 : this.props.count)}
			contentContainerStyle={{ paddingTop: HEADER_HEIGHT, marginTop: 25 }}
			scrollEventThrottle={16}
			bounces={false}
			numColumns={3}
			keyExtractor={this.keyExtractor}
			renderItem={() => (
				<View style={styles.placeholderEmpty} />
			)}
		/>

	)

	render() {
		const {
			title,
			subtitle,
			selectMode,
			rightIconPress,
			onRefresh,
			refreshing,
		} = this.props;

		const {
			opacity,
			isDoneAnimating,
		} = this.state;

		const headerHeight = this.getHeaderHeight();
		const scaleLevel = this.getScale();

		return (
			<View style={{ flex: 1 }}>
				{ isDoneAnimating && <Animated.FlatList
					{...this.props}
					ref={(ref) => { this.flatlist = ref; }}
					style={{
						height: Screen.height,
						opacity,
						marginTop: 25,
					}}
					// Start of default FlatList config
					maxToRenderPerBatch={10}
					initialNumToRender={10}
					onEndReached={this.handleLoadMore}
					onEndReachedThreshold={3}
					removeClippedSubviews
					contentContainerStyle={{ paddingTop: HEADER_HEIGHT, marginBottom: 30 }}
					scrollEventThrottle={1}
					numColumns={3}
					refreshing={refreshing}
					onRefresh={onRefresh}
					windowSize={11}
					keyExtractor={this.keyExtractor}
					// End of default Flatlist config

					// data={playlist.slides}
					getItemLayout={(data, index) => (
						{ length: THUMB_HEIGHT, offset: THUMB_HEIGHT * index, index }
					)}
					onScroll={Animated.event(
						[{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
						{
							useNativeDriver: true,
							listener: () => {
								if (isDoneAnimating) {
									this.setState({ isDoneAnimating: true });
								}
							},
						},
					)}
				/> }
				{ !isDoneAnimating && this.renderPlaceholder() }
				{ selectMode ?
					<View style={{
						flex: 1, width: '100%', position: 'absolute', backgroundColor: color.white, top: 0, height: 50, flexDirection: 'row', justifyContent: 'space-between',
					}}
					>
						<TouchableOpacity activeOpacity={0.80} onPress={() => this.goBack()} style={styles.touchableContainer} iconName="more">
							<NixplayIcon name="arrow-left-thick" size={24} color={color.mistBlue04} />
						</TouchableOpacity>
						<TouchableOpacity activeOpacity={0.80} onPress={() => this.openPlaylistActionSheet()} style={styles.touchableContainer} iconName="more">
							<NixplayIcon name="more" size={24} color={color.mistBlue04} />
						</TouchableOpacity>
					</View> :
					<View style={{
						flex: 1, width: '100%', position: 'absolute', backgroundColor: color.white, top: 0, height: 50, flexDirection: 'row', justifyContent: 'space-between',
					}}
					>
						<TouchableOpacity activeOpacity={0.80} onPress={() => this.props.toggleSelectModePressed()} style={styles.touchableContainer} iconName="more">
							<NixplayIcon name="close" size={24} color={color.mistBlue04} />
						</TouchableOpacity>
					</View>
				}
				{
					!selectMode ?
						<View style={styles.iconContainer}>
							<TouchableOpacity activeOpacity={0.80} onPress={() => this.goBack()} style={styles.touchableContainer} iconName="more" {...setTestID(TEST_IDS.NAV_CLOSE)}>
								<NixplayIcon name="arrow-left-thick" size={24} color={color.mistBlue04} />
							</TouchableOpacity>
							<TouchableOpacity activeOpacity={0.80} onPress={() => rightIconPress()} style={styles.touchableContainer} iconName="more" {...setTestID(TEST_IDS.NAV_MORE)}>
								<NixplayIcon name="more" size={24} color={color.mistBlue04} />
							</TouchableOpacity>
						</View> :
						<View style={styles.iconContainer}>
							<TouchableOpacity activeOpacity={0.80} onPress={() => this.props.toggleSelectModePressed()} style={styles.touchableContainer} iconName="more" {...setTestID(TEST_IDS.NAV_XCLOSE)}>
								<NixplayIcon name="close" size={24} color={color.mistBlue04} />
							</TouchableOpacity>
						</View>
				}
				<Animated.View
					style={{
						position: 'absolute',
						top: 0,
						height: HEADER_HEIGHT,
						width: '100%',
						// backgroundColor: color.white,
						transform: [{
							translateY: headerHeight,
						}],
						justifyContent: 'flex-end',
						alignItems: 'center',
						paddingBottom: 8,
					}}
					pointerEvents="none"
				>
					<Animated.View style={{
						transform: [{
							scale: scaleLevel,
						}],
					}}
					>
						<Text
							numberOfLines={1}
							ellipsizeMode="tail"
							style={{
								textAlign: 'center',
								color: color.textBlack,
								letterSpacing: 0.3,
								width: Screen.width - 200,
							}}
						>{title}
						</Text>
						{subtitle}
					</Animated.View>
				</Animated.View>
				{this.props.children}
			</View>
		);
	}
}

export default CollapsibleHeader;
