import React, { Component } from "react";
import { Text } from "@plusscommunities/pluss-core-app/components";
import { connect } from "react-redux";
import _ from "lodash";
import { TouchableOpacity, View, ScrollView, StyleSheet } from "react-native";
import { Icon } from "@rneui/themed";
import { Services } from "../config";
import { FormCard } from "./FormCard";
import { FormCardSection } from "./FormCardSection";
import { InlineButton } from "./InlineButton";
import Header from "./Header";
import { Spinner } from "./Spinner";
import {
	TEXT_DARK,
	COLOUR_GREEN,
	BG_GREY,
	INACTIVE_BUTTON,
	TEXT_LIGHT,
	getMainBrandingColourFromState,
} from "../colours";
import { typeActions, profileActions } from "../apis";

class AudienceSelectorPage extends Component {
	constructor(props) {
		super(props);

		this.state = {
			loading: false,
			categories: [
				{
					name: "All Primary Users",
					key: "resident",
				},
				{
					name: "All Staff Users",
					key: "staff",
				},
				{
					name: "All Linked Users",
					key: "family",
				},
			],
			types: [],
			tags: [],
			combinedList: [],
			seeAll: false,
		};
	}

	componentDidMount = async () => {
		try {
			this.setState({ loading: true });
			await this.getUserTypes();
			await this.getUserTags();
			this.setState({
				loading: false,
				combinedList: this.getAvailableAudienceTags(),
			});
		} catch (error) {
			console.error("loading types error", error);
			this.setState({ loading: false });
		}
	};

	getUserTypes = async () => {
		const { data } = await typeActions.getUserTypes(this.props.site);
		data.forEach((e) => {
			e.name = e.category
				? `(${e.category[0].toUpperCase() + e.category.substring(1)}) ${e.displayName}`
				: e.displayName;
			e.key = e.typeName;
		});
		// console.log('getUserTypes', data);
		this.setState({ types: data });
	};

	getUserTags = async () => {
		const { data } = await profileActions.getUserTagsBySite(this.props.site);
		data.forEach((e) => {
			e.name = e.Title;
			e.key = e.Id;
		});
		// console.log('getUserTags', data);
		this.setState({ tags: data });
	};

	getAvailableAudienceTags = () => {
		const { categories, types, tags } = this.state;
		const { audienceTypeSelection } = this.props;

		const categoryTags = categories.map((c) => {
			const Id = `category_${c.key}`;
			return {
				AudienceType: "Category",
				AudienceTypeSelection: c.key,
				Id,
				Title: c.name,
				Selected: audienceTypeSelection.some((i) => i.Id === Id),
			};
		});
		const userTypeTags = types.map((t) => {
			const Id = `userType_${t.typeName}`;
			return {
				AudienceType: "UserType",
				AudienceTypeSelection: t.typeName,
				Id,
				Title: `User Type: ${t.displayName}`,
				Selected: audienceTypeSelection.some((i) => i.Id === Id),
			};
		});
		const userTagTags = tags.map((t) => {
			const Id = `userTag_${t.Id}`;
			return {
				AudienceType: "UserTags",
				AudienceTypeSelection: t.Id,
				Id,
				Title: `User Tag: ${t.Title}`,
				Selected: audienceTypeSelection.some((i) => i.Id === Id),
			};
		});
		return [...categoryTags, ...userTypeTags, ...userTagTags];
	};

	onPressBack = () => {
		Services.navigation.goBack();
	};

	onSelectAll = () => {
		const newList = [...this.state.combinedList];
		newList.forEach((i) => (i.Selected = false));
		this.setState({ combinedList: newList });
	};

	onSeeAll = () => {
		this.setState({ seeAll: !this.state.seeAll });
	};

	onToggleAudienceOption = (option) => {
		const newList = [...this.state.combinedList];
		const selected = newList.find((i) => i.Id === option.Id);
		if (selected) {
			selected.Selected = !selected.Selected;
			this.setState({ combinedList: newList });
		}
	};

	onDone = () => {
		if (this.props.onChange) {
			const { combinedList } = this.state;
			const selected = combinedList.filter((i) => i.Selected);
			if (selected && selected.length > 0) {
				this.props.onChange("Custom", selected);
			} else {
				this.props.onChange(null, null);
			}
		}
		Services.navigation.goBack();
	};

	renderOption(label, selected, onSelect, key = null, hasUnderline = true) {
		return (
			<TouchableOpacity key={key} onPress={onSelect}>
				<FormCardSection hasUnderline={hasUnderline} hasContent>
					<View style={styles.labelContainer}>
						<Text style={styles.labelText}>{label}</Text>
						<Icon
							name="check-circle"
							type="font-awesome"
							iconStyle={[
								{ color: INACTIVE_BUTTON, fontSize: 20 },
								selected && { color: COLOUR_GREEN },
							]}
						/>
					</View>
				</FormCardSection>
			</TouchableOpacity>
		);
	}

	renderSelectAll() {
		const { combinedList, loading } = this.state;
		const allSelected = !combinedList.find((i) => i.Selected);
		if (loading) return null;

		return (
			<FormCard style={styles.selectAllContainer}>
				{this.renderOption(
					"All Users",
					allSelected,
					this.onSelectAll,
					null,
					false,
				)}
			</FormCard>
		);
	}

	renderSelection() {
		const { loading, combinedList, seeAll } = this.state;
		if (loading) return null;

		const selectedText = combinedList
			.filter((i) => i.Selected)
			.map((i) => i.Title)
			.join(", ");
		const hasSelected = !_.isEmpty(selectedText);

		return (
			<View style={styles.selectionContainer}>
				<View style={styles.selectionContainerInner}>
					<Text style={styles.selectionTitle}>or select from below</Text>
					{hasSelected ? (
						<TouchableOpacity onPress={this.onSeeAll}>
							<Text style={styles.seeAllButton}>
								{seeAll ? "See less" : "See all"}
							</Text>
						</TouchableOpacity>
					) : null}
				</View>
				{hasSelected ? (
					<Text
						style={styles.selectionText}
						numberOfLines={seeAll ? null : 1}
					>{`Current selection: ${selectedText}`}</Text>
				) : null}
			</View>
		);
	}

	renderTips() {
		return (
			<View style={styles.tipContainer}>
				<Text style={styles.tipText}>
					<Text style={{ fontFamily: "sf-semibold" }}>Tip: </Text>
					Group your users using User Tags from your website Community Manager
				</Text>
			</View>
		);
	}

	renderAvailableAudiences() {
		const { loading, combinedList } = this.state;

		return (
			<ScrollView
				style={styles.availableScrollContainer}
				contentContainerStyle={styles.availabelScrollContent}
			>
				<FormCard>
					{combinedList.map((option, index) => {
						const notLast = index < combinedList.length - 1;
						return this.renderOption(
							option.Title,
							option.Selected,
							() => this.onToggleAudienceOption(option),
							index,
							notLast,
						);
					})}
				</FormCard>
				{loading ? <Spinner /> : null}
				{this.renderTips()}
			</ScrollView>
		);
	}

	renderButtons() {
		const { loading } = this.state;

		return (
			<View style={styles.doneButtonContainer}>
				<InlineButton
					color={loading ? INACTIVE_BUTTON : this.props.colourBrandingMain}
					onPress={this.onDone}
					touchableStyle={styles.doneButton}
					fillTouchable
					large
					disabled={loading}
				>
					Done
				</InlineButton>
			</View>
		);
	}

	render() {
		return (
			<View style={styles.container}>
				<Header
					leftIcon="angle-left"
					onPressLeft={this.onPressBack}
					text={"Select Audience"}
				/>
				{this.renderSelectAll()}
				{this.renderSelection()}
				{this.renderAvailableAudiences()}
				{this.renderButtons()}
			</View>
		);
	}
}

const styles = StyleSheet.create({
	container: {
		flex: 1,
		position: "relative",
		backgroundColor: BG_GREY,
	},
	selectAllContainer: {
		marginTop: 20,
	},
	selectionContainer: {
		padding: 20,
	},
	selectionContainerInner: {
		flexDirection: "row",
		justifyContent: "space-between",
	},
	selectionTitle: {
		fontFamily: "sf-bold",
		fontSize: 14,
		color: TEXT_DARK,
	},
	selectionText: {
		fontFamily: "sf-bold",
		fontSize: 14,
		color: TEXT_DARK,
		marginTop: 10,
	},
	seeAllButton: {
		marginLeft: 10,
		fontFamily: "sf-bold",
		fontSize: 14,
		color: TEXT_LIGHT,
	},
	availableScrollContainer: {
		flex: 1,
	},
	availabelScrollContent: {
		flexGrow: 1,
		justifyContent: "space-between",
		flexDirection: "column",
	},
	tipContainer: {
		padding: 10,
	},
	tipText: {
		fontSize: 14,
		fontFamily: "sf-regular",
		color: TEXT_DARK,
	},
	labelContainer: {
		flexDirection: "row",
		justifyContent: "space-between",
	},
	labelText: {
		fontFamily: "sf-medium",
		fontSize: 16,
		color: TEXT_DARK,
	},
	description: {
		marginTop: 5,
		fontSize: 14,
		fontFamily: "sf-regular",
		color: TEXT_DARK,
	},
	doneButtonContainer: {
		backgroundColor: "#fff",
		marginTop: 1,
		flexDirection: "row",
		paddingTop: 10,
		paddingBottom: 20,
	},
	doneButton: {
		flex: 1,
		marginHorizontal: 6,
	},
});

const mapStateToProps = (state) => {
	return {
		colourBrandingMain: getMainBrandingColourFromState(state),
	};
};

export default connect(mapStateToProps, {})(AudienceSelectorPage);
