import * as React from 'react';
import { ShareInvitation } from '@joplin/lib/services/share/reducer';
import { Button, Card, Icon } from 'react-native-paper';
import { _ } from '@joplin/lib/locale';
import { useCallback, useState } from 'react';
import ShareService from '@joplin/lib/services/share/ShareService';
import shim from '@joplin/lib/shim';
import useAsyncEffect from '@joplin/lib/hooks/useAsyncEffect';
import Folder from '@joplin/lib/models/Folder';
import { FolderEntity } from '@joplin/lib/services/database/types';
import Logger from '@joplin/utils/Logger';
import { ViewStyle } from 'react-native';

interface Props {
	invitation: ShareInvitation;
	processing: boolean;
	containerStyle: ViewStyle;
}

const AcceptedIcon = (props: { size: number }) => <Icon {...props} source='account-multiple-check'/>;

const useFolderTitle = (folderId: string) => {
	const [folderTitle, setFolderTitle] = useState(undefined);

	useAsyncEffect(async event => {
		let folder: FolderEntity|null = null;

		// If the share was just accepted, the folder might not exist yet.
		// In this case, check for the shared item multiple times.
		while (!folder && !event.cancelled) {
			folder = await Folder.load(folderId);
			if (folder) {
				setFolderTitle(folder.title);
				break;
			}

			await new Promise<void>(resolve => {
				shim.setTimeout(() => resolve(), 1000);
			});
		}
	}, [folderId]);

	return folderTitle ?? '...';
};

const logger = Logger.create('AcceptedShareItem');

const AcceptedShareItem: React.FC<Props> = props => {
	const invitation = props.invitation;
	const sharer = invitation.share.user;

	const [leaving, setLeaving] = useState(false);
	// The "leave share" button can be briefly visible after leaving a share.
	// When this is the case, keep track of hasLeft to prevent clicking it.
	const [hasLeft, setHasLeft] = useState(false);

	const onLeaveShare = useCallback(async () => {
		try {
			setLeaving(true);
			if (await shim.showConfirmationDialog(_('This will remove the notebook from your collection and you will no longer have access to its content. Do you wish to continue?'))) {
				await ShareService.instance().leaveSharedFolder(invitation.share.folder_id, sharer.id);
				setHasLeft(true);
			}
		} catch (error) {
			logger.error('Failed to leave share', error);
			await shim.showMessageBox(
				_('Error: %s', error),
				{ buttons: [_('OK')] },
			);
		} finally {
			setLeaving(false);
		}
	}, [invitation, sharer]);

	const folderId = invitation.share.folder_id;
	const folderTitle = useFolderTitle(folderId);

	return <Card style={props.containerStyle}>
		<Card.Title
			left={AcceptedIcon}
			title={_('Notebook: %s (%s)', folderTitle, folderId)}
			subtitle={_('Share from %s (%s)', sharer.full_name, sharer.email)}
		/>
		<Card.Actions>
			<Button
				icon='share-off'
				onPress={onLeaveShare}
				disabled={props.processing || leaving || hasLeft}
				loading={leaving || !folderTitle}
			>{_('Leave notebook')}</Button>
		</Card.Actions>
	</Card>;
};

export default AcceptedShareItem;