import React, { Component } from "react";
import { connect } from "react-redux";
import {
	Keyboard,
	TextInput,
	View,
	ImageBackground,
	TouchableOpacity,
	Dimensions,
} from "react-native";
import { Icon } from "@rneui/themed";
import { withSafeAreaInsets } from "react-native-safe-area-context";
import _ from "lodash";
import { getApiError } from "../session";
import { getShadowStyle } from "../helper";
import { TEXT_BLUEGREY, TEXT_DARKEST, BG_GREY } from "../colours";
import { Spinner } from "./Spinner";
import ImageUploader from "./ImageUploader";
import { reactionActions } from "../apis";

const SCREEN_HEIGHT = Dimensions.get("window").height;

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

		this.state = {
			commentImageInput: "",
			commentInput: "",
			uploadingCommentImage: false,
			commentsLoading: true,
			addingComment: false,
		};
		this.replyInputRef = React.createRef();
	}

	componentDidMount() {
		if (this.props.commentSection && this.props.commentSection.current) {
			this.setState({
				commentsLoading: this.props.commentSection.current.isLoading(),
			});
		}
	}

	onUploadStarted = () => {
		this.setState({
			uploadingCommentImage: true,
		});
		setTimeout(() => {
			if (!this.props.noScroll) {
				this.props.scrollView?.current?.scrollToEnd({ animated: true });
			}
		}, 500);
	};

	onUploadSuccess = (uri) => {
		this.setState({
			uploadingCommentImage: false,
			commentImageInput: uri.replace("/general/", "/general1400/"),
		});
	};

	onUploadFailed = () => {
		this.setState({
			uploadingCommentImage: false,
			commentImageInput: null,
		});
	};

	focusInput() {
		this.replyInputRef.current.focus();
	}

	loadingStarted() {
		this.setState({
			commentsLoading: true,
		});
	}

	loadingCompleted() {
		this.setState({
			commentsLoading: false,
		});
	}

	shouldShowImageInput() {
		return (
			this.state.uploadingCommentImage ||
			!_.isEmpty(this.state.commentImageInput)
		);
	}

	addComment() {
		setTimeout(() => {
			if (!this.props.noScroll) {
				this.props.scrollView?.current?.scrollToEnd({ animated: true });
			}
		}, 500);
		const text = this.state.commentInput;
		const image = this.state.commentImageInput;
		this.setState({
			addingComment: true,
			commentInput: "",
			commentImageInput: "",
		});
		Keyboard.dismiss();
		if (this.props.commentSection) {
			this.props.commentSection?.current?.startedAddingComment();
		}
		reactionActions
			.addComment(
				this.props.entityId,
				this.props.entityType,
				this.props.entityName,
				this.props.site,
				text,
				image,
				this.props.threadId,
			)
			.then((res) => {
				if (this.props.commentSection) {
					this.props.commentSection?.current?.commentAdded(res.data);
				}
				this.setState({
					addingComment: false,
				});
				setTimeout(() => {
					if (!this.props.noScroll) {
						this.props.scrollView?.current?.scrollToEnd({ animated: true });
					}
				}, 500);
			})
			.catch((err) => {
				console.log(getApiError(err));
			});
	}

	removeImage() {
		this.setState({
			commentImageInput: null,
		});
	}

	showUploadMenu() {
		if (
			this.state.uploadingCommentImage ||
			!_.isEmpty(this.state.commentImageInput)
		) {
			return;
		}
		this.commentImageUploader.showUploadMenu();
	}

	renderImageAttachment() {
		if (
			_.isEmpty(this.state.commentImageInput) &&
			!this.state.uploadingCommentImage
		) {
			return null;
		}
		if (this.state.uploadingCommentImage) {
			return (
				<View
					style={[
						styles.accessoryImage,
						styles.accessoryImageBorder,
						{ borderWidth: 1, borderColor: BG_GREY },
					]}
				>
					<Spinner />
				</View>
			);
		}
		return (
			<ImageBackground
				style={styles.accessoryImage}
				imageStyle={styles.accessoryImageBorder}
				source={{ uri: this.state.commentImageInput }}
			>
				<TouchableOpacity
					style={styles.accessoryImageClose}
					onPress={this.removeImage.bind(this)}
					hitSlop={{ top: 8, right: 8, bottom: 8, left: 8 }}
				>
					<Icon
						name="remove"
						type="font-awesome"
						iconStyle={styles.accessoryImageCloseIcon}
						style={styles.accessoryImageCloseIconContainer}
					/>
				</TouchableOpacity>
			</ImageBackground>
		);
	}

	renderImageUploader() {
		return (
			<ImageUploader
				ref={(ref) => (this.commentImageUploader = ref)}
				onUploadStarted={this.onUploadStarted}
				onUploadSuccess={this.onUploadSuccess}
				onUploadFailed={this.onUploadFailed}
				onLibrarySelected={this.onUploadSuccess}
				quality={0.8}
				allowsEditing={false}
				fileName="commentImage"
				popupTitle="Add Image"
				userId={this.props.user.uid}
				hideLibrary
			/>
		);
	}

	render() {
		if (_.includes(this.props.user.hidden, "addComment")) {
			return null;
		}
		if (this.state.commentsLoading) {
			return null;
		}
		return (
			<View
				style={[
					styles.inputContainer,
					getShadowStyle(),
					{ paddingBottom: 8 + (this.props.insets?.bottom ?? 0) },
					this.props.style,
				]}
			>
				<View
					style={[
						styles.input,
						{
							marginRight:
								_.isEmpty(this.state.commentInput) &&
								_.isEmpty(this.state.commentImageInput)
									? 40
									: 80,
						},
					]}
				>
					<TextInput
						maxFontSizeMultiplier={1.2}
						ref={this.replyInputRef}
						placeholder="Enter your comment here"
						value={this.state.commentInput}
						onFocus={() => {
							if (!this.props.noScroll) {
								this.props.scrollView?.current?.scrollToEnd({ animated: true });
							}
						}}
						onChangeText={(value) => {
							if (!this.props.noScroll) {
								this.props.scrollView?.current?.scrollToEnd({
									animated: false,
								});
							}
							this.setState({
								commentInput: value,
							});
						}}
						style={styles.inputText}
						autoCapitalize="sentences"
						multiline
						autoCorrect
						autoGrow
					/>
				</View>
				{(!_.isEmpty(this.state.commentInput) ||
					!_.isEmpty(this.state.commentImageInput)) &&
					!this.state.addingComment && (
						<TouchableOpacity
							onPress={this.addComment.bind(this)}
							style={[
								styles.sendContainer,
								{
									right: 4,
									padding: 4,
									width: 40,
									height: 40,
								},
							]}
						>
							<Icon
								name="paper-plane"
								type="font-awesome"
								iconStyle={[styles.send, { width: 40 }]}
							/>
						</TouchableOpacity>
					)}
				<TouchableOpacity
					onPress={this.showUploadMenu.bind(this)}
					style={[
						styles.sendContainer,
						{
							right:
								_.isEmpty(this.state.commentInput) &&
								_.isEmpty(this.state.commentImageInput)
									? 4
									: 44,
							padding: 4,
							width: 40,
							height: 40,
						},
					]}
				>
					<Icon
						name="picture-o"
						type="font-awesome"
						iconStyle={[styles.send, { width: 40 }]}
					/>
				</TouchableOpacity>
				{this.renderImageAttachment()}
				{this.renderImageUploader()}
			</View>
		);
	}
}

const styles = {
	accessoryImage: {
		marginTop: 8,
		width: 60,
		height: 60,
	},
	accessoryImageBorder: {
		borderRadius: 2,
	},
	accessoryImageClose: {
		width: 14,
		height: 14,
		borderRadius: 7,
		position: "absolute",
		top: -7,
		right: -7,
		backgroundColor: TEXT_BLUEGREY,
	},
	accessoryImageCloseIconContainer: {
		width: 14,
		height: 14,
		alignItems: "center",
		justifyContent: "center",
	},
	accessoryImageCloseIcon: {
		fontSize: 10,
		color: "#fff",
		textAlign: "center",
	},
	inputContainer: {
		backgroundColor: "#fff",
		paddingVertical: 8,
		paddingHorizontal: 8,
		paddingBottom: 8, // bottom inset added dynamically via props
		flexGrow: 1,
	},
	inputText: {
		color: TEXT_DARKEST,
		fontSize: 14,
		fontFamily: "sf-medium",
	},
	input: {
		fontSize: 14,
		color: TEXT_DARKEST,
		fontFamily: "sf-medium",
		margin: 0,
		backgroundColor: BG_GREY,
		borderRadius: 5,
		padding: 8,
		maxHeight: SCREEN_HEIGHT / 3,
	},
	sendContainer: {
		position: "absolute",
		top: 8,
		right: 8,
		height: 30,
		width: 30,
		alignItems: "center",
		justifyContent: "center",
		backgroundColor: "#fff",
	},
	send: {
		color: TEXT_BLUEGREY,
		fontSize: 24,
		textAlign: "center",
	},
};

const mapStateToProps = (state) => {
	const { user } = state;
	return { user };
};

const commentReply = connect(mapStateToProps, {}, null, { forwardRef: true })(
	withSafeAreaInsets(CommentReply),
);
export { commentReply as CommentReply };
