import React, { Component } from "react";
import { Text } from "@plusscommunities/pluss-core-app/components";
import {
	View,
	TouchableOpacity,
	StyleSheet,
	ActivityIndicator,
} from "react-native";
import { Icon } from "@rneui/themed";
import * as DocumentPicker from "expo-document-picker";
import { connect } from "react-redux";
import Config from "../config";
import { fileActions } from "../apis";
import { getValueOrDefault } from "../helper";
import { TEXT_DARK, getMainBrandingColourFromState } from "../colours";

const DEFAULT_DOCUMENT_NAME = "document";

class DocumentUploader extends Component {
	static defaultProps = {
		allowedTypes: ["application/pdf"],
		buttonTitle: "Upload Document",
		buttonStyle: {},
		buttonTextStyle: {},
		onUploadStarted: () => {},
		onUploadSuccess: () => {},
		onUploadFailed: () => {},
		onUploadProgress: null,
		userId: null,
		fileName: null,
		disabled: false,
	};

	state = {
		isUploading: false,
		uploadProgress: 0,
	};

	pickDocument = async () => {
		const { allowedTypes, multiple } = this.props;

		try {
			const result = await DocumentPicker.getDocumentAsync({
				type: allowedTypes,
				copyToCacheDirectory: true,
				multiple: multiple || false,
			});
			// console.log('pickDocument', JSON.stringify(result, null, 2));

			if (!result.canceled) {
				await this.handleDocumentPicked(result);
			}
		} catch (error) {
			console.log("Document picker error:", error);
			this.props.onUploadFailed(null, error.message);
		}
	};

	handleDocumentPicked = async (documentResult) => {
		const { assets } = documentResult;
		const { userId } = this.props;

		try {
			this.setState({ isUploading: true, uploadProgress: 0 });

			// Process each asset in parallel
			const uploadPromises = assets.map(async (asset) => {
				const { name, uri, mimeType } = asset;

				let file, fileExt;
				if (name && name.includes(".")) {
					const lastDotIndex = name.lastIndexOf(".");
					file = name.substring(0, lastDotIndex);
					fileExt = name.substring(lastDotIndex + 1);
				} else {
					// Fallback: extract extension from mimeType
					file = name || "document";
					if (mimeType) {
						const mimeTypeParts = mimeType.split("/");
						// Handle specific MIME type mappings
						if (mimeType === "application/pdf") fileExt = "pdf";
						else if (mimeType.startsWith("image/")) fileExt = mimeTypeParts[1];
						else if (mimeType.startsWith("text/")) fileExt = "txt";
						else fileExt = mimeTypeParts[1] || "pdf";
					} else {
						fileExt = "pdf";
					}
				}

				// Generate a unique filename if not provided
				const fileName = `${getValueOrDefault(this.props.fileName, DEFAULT_DOCUMENT_NAME)}.${fileExt}`;
				const uploadUri = fileActions.getUploadUrl(userId, fileName);
				// console.log('handleDocumentPicked', JSON.stringify({ uploadUri, uri, name, fileName, mimeType, file, fileExt }, null, 2));

				try {
					// Notify parent component that upload has started for this file
					this.props.onUploadStarted(
						uploadUri,
						uri,
						file,
						fileExt.toUpperCase(),
					);

					const res = await fileActions.uploadUserMediaWithProgress(
						uri,
						uploadUri,
						(progress) => {
							if (this.props.onUploadProgress)
								this.props.onUploadProgress(progress);
						},
					);

					const fileUrl = Config.env.baseUploadsUrl + res.key;
					this.props.onUploadSuccess(fileUrl, uploadUri);
					console.log("Upload success", fileUrl);
					return { success: true, url: fileUrl, uploadUri };
				} catch (error) {
					console.error(`Upload failed for ${name}:`, error);
					this.props.onUploadFailed(uploadUri, error.message);
					return { success: false, error, uploadUri };
				}
			});

			// Wait for all uploads to complete
			const results = await Promise.all(uploadPromises);
			return results;
		} catch (error) {
			console.error("Document upload error:", error);
			return [];
		} finally {
			this.setState({ isUploading: false, uploadProgress: 0 });
		}
	};

	renderUploadButton = () => {
		const { buttonTitle, buttonStyle, buttonTextStyle, disabled } = this.props;
		const { isUploading } = this.state;
		const mainColor = getMainBrandingColourFromState(this.props);

		return (
			<TouchableOpacity
				style={[styles.uploadButton, { borderColor: mainColor }, buttonStyle]}
				onPress={this.pickDocument}
				disabled={isUploading || disabled}
				activeOpacity={0.7}
			>
				<View style={styles.buttonContent}>
					{isUploading ? (
						<ActivityIndicator color={mainColor} />
					) : (
						<Icon
							name="attachment"
							type="entypo"
							color={mainColor}
							size={18}
							style={styles.icon}
						/>
					)}
					<Text
						style={[styles.buttonText, { color: mainColor }, buttonTextStyle]}
					>
						{buttonTitle}
					</Text>
				</View>
			</TouchableOpacity>
		);
	};

	renderProgress = () => {
		const { uploadProgress } = this.state;
		if (uploadProgress <= 0 || uploadProgress >= 1) return null;

		return (
			<View style={styles.progressContainer}>
				<View style={styles.progressBar}>
					<View
						style={[styles.progressFill, { width: `${uploadProgress * 100}%` }]}
					/>
				</View>
				<Text style={styles.progressText}>
					{Math.round(uploadProgress * 100)}%
				</Text>
			</View>
		);
	};

	render() {
		return (
			<View style={styles.container}>
				{this.renderUploadButton()}
				{this.renderProgress()}
			</View>
		);
	}
}

const styles = StyleSheet.create({
	container: {
		marginVertical: 10,
	},
	uploadButton: {
		flexDirection: "row",
		alignItems: "center",
		justifyContent: "center",
		paddingVertical: 8,
		paddingHorizontal: 16,
		borderRadius: 6,
		backgroundColor: "#fff",
		borderWidth: 1,
		borderColor: "#007AFF",
	},
	buttonContent: {
		flexDirection: "row",
		alignItems: "center",
	},
	buttonText: {
		color: "#fff",
		fontSize: 16,
		fontWeight: "500",
		marginLeft: 8,
	},
	icon: {
		marginRight: 8,
	},
	progressContainer: {
		marginTop: 8,
		alignItems: "center",
	},
	progressBar: {
		height: 4,
		width: "100%",
		backgroundColor: "#E0E0E0",
		borderRadius: 2,
		overflow: "hidden",
	},
	progressFill: {
		height: "100%",
		backgroundColor: "#4CAF50",
	},
	progressText: {
		marginTop: 4,
		fontSize: 12,
		color: TEXT_DARK,
	},
});

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

export default connect(mapStateToProps)(DocumentUploader);
