import React, { Component } from "react";
import { Text } from "@plusscommunities/pluss-core-app/components";
import _ from "lodash";
import moment from "moment";
import {
	Dimensions,
	Modal,
	TouchableOpacity,
	StyleSheet,
	View,
	Image,
} from "react-native";
import ImageViewer from "react-native-image-zoom-viewer";
import { Icon } from "@rneui/themed";
import { StatusBarHeight, isVideo, get1400 } from "../helper";
import { FontAwesome } from "./Icon";
import { SharingTools } from "./SharingTools";
import { VideoPopup } from "./VideoPopup";
import { ProfilePic } from "./ProfilePic";
import { LoadingIndicator } from "./";

const SCREEN_WIDTH = Dimensions.get("window").width;
const SCREEN_HEIGHT = Dimensions.get("window").height;
const MAX_IMAGE_HEIGHT = SCREEN_HEIGHT * 0.65;

class ImagePopup extends Component {
	constructor(props) {
		super(props);
		this.state = {
			index: 0,
			images: [],
			showFullscreenVideo: false,
			currentVideoUrl: "",
			imageDimensions: {},
			isLoadingDimensions: false,
		};
	}

	componentDidMount() {
		this.setupUrls();
	}

	componentDidUpdate(prevProps) {
		const { visible, index } = this.props;
		if (!prevProps.visible && visible) this.setupUrls();
		if (prevProps.index !== index) this.setState({ index });
	}

	setupUrls = async () => {
		if (!this.props.images) return;

		const images = this.props.images.map((image) => {
			if (typeof image === "string") {
				return {
					url: get1400(image),
					original: image,
					isVideo: isVideo(image),
				};
			}
			return {
				url: get1400(image?.uri),
				original: image?.uri,
				isVideo: isVideo(image?.uri),
				date: image?.date,
				user: image?.user,
				caption: image?.caption,
			};
		});

		this.setState({ isLoadingDimensions: true });

		const dimensions = {};
		await Promise.all(
			images.map(async (image) => {
				if (!image.url) return;
				try {
					const { width, height } = await new Promise((resolve, reject) => {
						Image.getSize(
							image.url,
							(w, h) => resolve({ width: w, height: h }),
							reject,
						);
					});
					dimensions[image.url] = { width, height };
				} catch (err) {
					console.log("Failed to get dimensions for", image.url, err);
					dimensions[image.url] = {
						width: SCREEN_WIDTH,
						height: SCREEN_HEIGHT,
					};
				}
			}),
		);

		this.setState({
			images,
			index: this.state.index || this.props.index || 0,
			imageDimensions: dimensions,
			isLoadingDimensions: false,
		});
	};

	onChange = (index) => {
		this.setState({ index });
	};

	scrollTo(index) {
		this.setState({
			index,
		});
	}

	toggleFullscreenVideo = (url) => {
		if (typeof url !== "string") url = "";
		this.setState({
			showFullscreenVideo: url.length > 0,
			currentVideoUrl: url,
		});
	};

	renderClose() {
		return (
			<TouchableOpacity
				style={styles.menuIconContainer}
				onPress={this.props.onClose}
				activeOpacity={0.6}
			>
				<FontAwesome name="x" style={[styles.menuIcon]} />
			</TouchableOpacity>
		);
	}

	renderImageFooter = (media) => {
		if (!media.user || !media.date) return null;

		let dateText, timeText;
		if (!_.isNil(media.date)) {
			const imageDate = moment(media.date);
			dateText = imageDate.format("MMMM D, YYYY");
			timeText = imageDate.format("hh:mm A");
		}

		return (
			<View style={styles.imageInfoContainer}>
				<ProfilePic Diameter={36} ProfilePic={media?.user?.profilePic} />
				<View style={styles.imageTextContainer}>
					<Text style={styles.imageTextName}>{media?.user?.displayName}</Text>
					<Text
						numberOfLines={2}
						style={styles.iamgeTextDate}
					>{`Uploaded ${dateText} • ${timeText}`}</Text>
				</View>
			</View>
		);
	};

	renderCaption = (media) => {
		if (!media.caption) return null;

		return (
			<View style={styles.captionContainer}>
				<Text numberOfLines={3} style={styles.captionText}>
					{media.caption}
				</Text>
			</View>
		);
	};

	getImageDimensions = (media) => {
		const cachedDimensions = this.state.imageDimensions[media?.url] || {
			width: SCREEN_WIDTH,
			height: SCREEN_HEIGHT,
		};

		const aspectRatio = cachedDimensions.width / cachedDimensions.height;
		let imageWidth = SCREEN_WIDTH;
		let imageHeight = imageWidth / aspectRatio;

		// Cap at 70% of screen height
		if (imageHeight > MAX_IMAGE_HEIGHT) {
			imageHeight = MAX_IMAGE_HEIGHT;
			imageWidth = imageHeight * aspectRatio;
		}

		return { imageWidth, imageHeight };
	};

	renderImage = (props) => {
		const media = this.state.images.find(
			(image) => image.url === props.source.uri,
		);
		const isVideoMedia = !_.isNil(media) && media.isVideo;
		const { imageWidth, imageHeight } = this.getImageDimensions(media);

		return (
			<View style={styles.imageContainer}>
				<Image
					source={{ uri: media?.url }}
					style={{ width: imageWidth, height: imageHeight }}
					resizeMode="contain"
				/>
				{isVideoMedia && (
					<View
						style={[
							styles.videoOverlay,
							{ width: imageWidth, height: imageHeight },
						]}
					>
						<TouchableOpacity
							onPress={this.toggleFullscreenVideo.bind(this, media.original)}
						>
							<Icon
								name="play"
								type="font-awesome"
								iconStyle={styles.videoPlayIcon}
							/>
						</TouchableOpacity>
					</View>
				)}
			</View>
		);
	};

	renderVideoPlayerPopup() {
		const { showFullscreenVideo, currentVideoUrl } = this.state;
		if (!currentVideoUrl) return;

		return (
			<VideoPopup
				uri={currentVideoUrl}
				visible={showFullscreenVideo}
				onClose={this.toggleFullscreenVideo}
			/>
		);
	}

	renderBottomContent = () => {
		const { index, images } = this.state;
		const media = images[index];

		if (!media) return null;

		const hasCaption = !_.isNil(media.caption);
		const hasUserInfo = !_.isNil(media.user) || !_.isNil(media.date);

		if (!hasCaption && !hasUserInfo) return null;

		// Calculate where the image ends (for caption positioning)
		const { imageHeight } = this.getImageDimensions(media);
		const imageTop = (SCREEN_HEIGHT - imageHeight) / 2;
		const imageBottom = imageTop + imageHeight;
		const captionTop = imageBottom + 16;

		return (
			<>
				{/* Caption positioned below the image */}
				{hasCaption && (
					<View style={[styles.captionWrapper, { top: captionTop }]}>
						{this.renderCaption(media)}
					</View>
				)}

				{/* User info anchored to bottom of screen */}
				{hasUserInfo && (
					<View style={styles.userInfoWrapper}>
						{this.renderImageFooter(media)}
					</View>
				)}
			</>
		);
	};

	render() {
		const { visible, onClose } = this.props;
		const { index, images, isLoadingDimensions } = this.state;

		if (_.isEmpty(images)) {
			return null;
		}

		if (isLoadingDimensions) {
			return (
				<Modal
					visible={visible}
					animationType="slide"
					onRequestClose={onClose}
					style={styles.modal}
				>
					<LoadingIndicator visible={true} />
				</Modal>
			);
		}

		const imagesWithSizes = images.map((image) => {
			return {
				...image,
				width: SCREEN_WIDTH,
				height: SCREEN_HEIGHT,
			};
		});

		return (
			<Modal
				visible={visible}
				animationType="slide"
				onRequestClose={onClose}
				style={styles.modal}
			>
				<View style={styles.container}>
					{/* Full screen image viewer */}
					<ImageViewer
						style={styles.imageViewer}
						index={index}
						onChange={this.onChange}
						onSwipeDown={onClose}
						enableSwipeDown
						imageUrls={imagesWithSizes}
						saveToLocalByLongPress={false}
						renderImage={this.renderImage}
						backgroundColor="#000"
					/>

					{/* Absolutely positioned bottom content */}
					{this.renderBottomContent()}

					{/* Overlay controls */}
					{this.renderClose()}
					<SharingTools uri={images[index]?.original} />
				</View>
				{this.renderVideoPlayerPopup()}
			</Modal>
		);
	}
}

const styles = StyleSheet.create({
	modal: {
		backgroundColor: "#000",
	},
	container: {
		flex: 1,
		backgroundColor: "#000",
	},
	imageViewer: {
		flex: 1,
		backgroundColor: "#000",
	},
	imageContainer: {
		flex: 1,
		justifyContent: "center",
		alignItems: "center",
	},
	captionWrapper: {
		position: "absolute",
		left: 16,
		right: 16,
		zIndex: 10,
	},
	userInfoWrapper: {
		position: "absolute",
		bottom: 40, // Safe area padding
		left: 16,
		right: 16,
		zIndex: 10,
	},
	menuIconContainer: {
		position: "absolute",
		top: StatusBarHeight(0),
		right: 0,
		width: 55,
		height: 55,
		zIndex: 3,
	},
	menuIcon: {
		fontSize: 25,
		padding: 15,
		width: 55,
		textAlign: "center",
		color: "#fff",
		zIndex: 3,
	},
	videoOverlay: {
		position: "absolute",
		alignItems: "center",
		justifyContent: "center",
	},
	videoPlayIcon: {
		color: "#fff",
		fontSize: 30,
		textShadowColor: "rgba(0,0,0,0.3)",
		textShadowOffset: { width: 2, height: 2 },
	},
	imageInfoContainer: {
		flexDirection: "row",
		paddingHorizontal: 12,
		paddingVertical: 12,
		gap: 4,
		borderRadius: 8,
		alignItems: "center",
	},
	imageTextContainer: {
		marginLeft: 12,
		flexDirection: "column",
		gap: 4,
		flex: 1,
		justifyContent: "space-around",
	},
	imageTextName: {
		fontFamily: "sf-semibold",
		fontSize: 14,
		color: "#fff",
	},
	iamgeTextDate: {
		fontFamily: "sf-regular",
		fontSize: 12,
		color: "rgba(255, 255, 255, 0.8)",
	},
	captionContainer: {
		borderRadius: 16,
		padding: 0,
		alignItems: "center",
		justifyContent: "center",
	},
	captionText: {
		fontFamily: "sf-regular",
		fontSize: 15,
		color: "#fff",
		textAlign: "center",
		lineHeight: 20,
	},
});

export { ImagePopup };
