/**
 * Tours list: antd card grid with filters, search, and import/export.
 */
import { useState, useEffect, useCallback, useRef } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { decodeEntities } from '@wordpress/html-entities';
import {
	App,
	Typography,
	Segmented,
	Input,
	Button,
	Card,
	Tag,
	Dropdown,
	Row,
	Col,
	Empty,
	Skeleton,
	Modal,
} from 'antd';
import {
	PictureOutlined,
	UploadOutlined,
	MoreOutlined,
	PlusOutlined,
} from '@ant-design/icons';

import {
	fetchTours,
	deleteTour,
	fetchTour,
	saveTour,
	exportTour,
	importTour,
} from '../../api';
import { navigate } from '../../App';

const STATUS_TAGS = {
	publish: {
		color: 'success',
		label: __( 'Published', 'vistour-virtual-tour-builder' ),
	},
	draft: {
		color: 'warning',
		label: __( 'Draft', 'vistour-virtual-tour-builder' ),
	},
	private: {
		color: 'error',
		label: __( 'Private', 'vistour-virtual-tour-builder' ),
	},
	pending: {
		color: 'processing',
		label: __( 'Pending', 'vistour-virtual-tour-builder' ),
	},
	future: {
		color: 'processing',
		label: __( 'Scheduled', 'vistour-virtual-tour-builder' ),
	},
};

const tourThumbnail = ( tour ) =>
	tour._embedded?.[ 'wp:featuredmedia' ]?.[ 0 ]?.media_details?.sizes?.medium
		?.source_url ||
	tour._embedded?.[ 'wp:featuredmedia' ]?.[ 0 ]?.source_url ||
	null;

const downloadJson = ( filename, data ) => {
	const blob = new Blob( [ JSON.stringify( data, null, 2 ) ], {
		type: 'application/json',
	} );
	const url = URL.createObjectURL( blob );
	const link = document.createElement( 'a' );
	link.href = url;
	link.download = filename;
	link.click();
	URL.revokeObjectURL( url );
};

const ToursList = () => {
	const { message, modal } = App.useApp();
	const [ tours, setTours ] = useState( null );
	const [ status, setStatus ] = useState( '' );
	const [ search, setSearch ] = useState( '' );
	const fileInput = useRef( null );

	const load = useCallback( () => {
		const query = {};
		if ( search ) {
			query.search = search;
		}
		if ( status ) {
			query.status = status;
		}
		fetchTours( query )
			.then( setTours )
			.catch( ( error ) =>
				message.error(
					error.message ||
						__(
							'Failed to load tours.',
							'vistour-virtual-tour-builder'
						)
				)
			);
	}, [ search, status, message ] );

	useEffect( () => {
		const timer = setTimeout( load, search ? 300 : 0 );
		return () => clearTimeout( timer );
	}, [ load, search ] );

	const confirmDelete = ( tour ) => {
		modal.confirm( {
			title: __( 'Delete tour?', 'vistour-virtual-tour-builder' ),
			content: sprintf(
				/* translators: %s: tour title. */
				__(
					'Delete “%s” permanently? This cannot be undone.',
					'vistour-virtual-tour-builder'
				),
				decodeEntities( tour.title.rendered )
			),
			okText: __( 'Delete', 'vistour-virtual-tour-builder' ),
			okButtonProps: { danger: true },
			onOk: async () => {
				await deleteTour( tour.id );
				setTours( ( current ) =>
					current.filter( ( item ) => item.id !== tour.id )
				);
				message.success(
					__( 'Tour deleted.', 'vistour-virtual-tour-builder' )
				);
			},
		} );
	};

	const duplicate = async ( tour ) => {
		try {
			const full = await fetchTour( tour.id );
			const copy = await saveTour( null, {
				title: sprintf(
					/* translators: %s: tour title. */
					__( '%s (Copy)', 'vistour-virtual-tour-builder' ),
					decodeEntities( full.title.raw || '' )
				),
				status: 'draft',
				meta: {
					_vist360_scenes: full.meta?._vist360_scenes || [],
					_vist360_viewer: full.meta?._vist360_viewer || {},
				},
			} );
			message.success(
				__( 'Tour duplicated.', 'vistour-virtual-tour-builder' )
			);
			navigate( `edit/${ copy.id }` );
		} catch ( error ) {
			message.error( error.message );
		}
	};

	const handleExport = async ( tour ) => {
		try {
			const data = await exportTour( tour.id );
			downloadJson( `tour-${ tour.id }.json`, data );
		} catch ( error ) {
			message.error( error.message );
		}
	};

	const handleImportFile = async ( event ) => {
		const file = event.target.files?.[ 0 ];
		event.target.value = '';
		if ( ! file ) {
			return;
		}
		try {
			const data = JSON.parse( await file.text() );
			const imported = await importTour( data );
			message.success(
				__(
					'Tour imported as draft.',
					'vistour-virtual-tour-builder'
				)
			);
			navigate( `edit/${ imported.id }` );
		} catch ( error ) {
			Modal.error( {
				title: __(
					'Import failed',
					'vistour-virtual-tour-builder'
				),
				content:
					error.message ||
					__(
						'The selected file is not a valid tour export.',
						'vistour-virtual-tour-builder'
					),
			} );
		}
	};

	const menuFor = ( tour ) => ( {
		items: [
			'publish' === tour.status && {
				key: 'view',
				label: __( 'View tour', 'vistour-virtual-tour-builder' ),
				onClick: () => window.open( tour.link, '_blank' ),
			},
			{
				key: 'shortcode',
				label: __(
					'Copy shortcode',
					'vistour-virtual-tour-builder'
				),
				onClick: () => {
					window.navigator.clipboard
						?.writeText( `[vist360_tour id="${ tour.id }"]` )
						.then( () =>
							message.success(
								__(
									'Shortcode copied.',
									'vistour-virtual-tour-builder'
								)
							)
						);
				},
			},
			{
				key: 'duplicate',
				label: __( 'Duplicate', 'vistour-virtual-tour-builder' ),
				onClick: () => duplicate( tour ),
			},
			{
				key: 'export',
				label: __( 'Export JSON', 'vistour-virtual-tour-builder' ),
				onClick: () => handleExport( tour ),
			},
			{ type: 'divider' },
			{
				key: 'delete',
				danger: true,
				label: __( 'Delete', 'vistour-virtual-tour-builder' ),
				onClick: () => confirmDelete( tour ),
			},
		].filter( Boolean ),
	} );

	return (
		<div className="vist360-view">
			<div className="vist360-view__header">
				<div>
					<Typography.Title level={ 2 }>
						{ tours
							? sprintf(
									/* translators: %d: tour count. */
									__(
										'Tours (%d)',
										'vistour-virtual-tour-builder'
									),
									tours.length
							  )
							: __(
									'Tours',
									'vistour-virtual-tour-builder'
							  ) }
					</Typography.Title>
					<Typography.Text type="secondary">
						{ __(
							'Create and manage your 360° virtual tours.',
							'vistour-virtual-tour-builder'
						) }
					</Typography.Text>
				</div>
				<div className="vist360-view__filters">
					<Segmented
						value={ status }
						onChange={ setStatus }
						options={ [
							{
								value: '',
								label: __(
									'All',
									'vistour-virtual-tour-builder'
								),
							},
							{
								value: 'publish',
								label: STATUS_TAGS.publish.label,
							},
							{ value: 'draft', label: STATUS_TAGS.draft.label },
							{
								value: 'private',
								label: STATUS_TAGS.private.label,
							},
						] }
					/>
					<Input.Search
						allowClear
						placeholder={ __(
							'Search tours…',
							'vistour-virtual-tour-builder'
						) }
						onChange={ ( event ) =>
							setSearch( event.target.value )
						}
						style={ { width: 220 } }
					/>
					<Button
						icon={ <UploadOutlined /> }
						onClick={ () => fileInput.current?.click() }
					>
						{ __(
							'Import JSON',
							'vistour-virtual-tour-builder'
						) }
					</Button>
					<input
						ref={ fileInput }
						type="file"
						accept="application/json"
						hidden
						onChange={ handleImportFile }
					/>
				</div>
			</div>

			{ ! tours && (
				<Row gutter={ [ 20, 20 ] }>
					{ [ 1, 2, 3, 4 ].map( ( key ) => (
						<Col
							key={ key }
							xs={ 24 }
							sm={ 12 }
							lg={ 8 }
							xl={ 6 }
							xxl={ 4 }
						>
							<Card>
								<Skeleton active paragraph={ { rows: 2 } } />
							</Card>
						</Col>
					) ) }
				</Row>
			) }

			{ tours && ! tours.length && (
				<Card>
					<Empty
						description={ __(
							'No tours yet — upload a 360° panorama and create your first virtual tour in minutes.',
							'vistour-virtual-tour-builder'
						) }
					>
						<Button
							type="primary"
							icon={ <PlusOutlined /> }
							onClick={ () => navigate( 'templates' ) }
						>
							{ __(
								'Create your first tour',
								'vistour-virtual-tour-builder'
							) }
						</Button>
					</Empty>
				</Card>
			) }

			{ tours && tours.length > 0 && (
				<Row gutter={ [ 20, 20 ] }>
					{ tours.map( ( tour ) => {
						const thumb = tourThumbnail( tour );
						const tag =
							STATUS_TAGS[ tour.status ] || STATUS_TAGS.draft;
						const scenes = tour.meta?._vist360_scenes?.length || 0;
						const views = tour.meta?._vist360_views || 0;

						return (
							<Col
								key={ tour.id }
								xs={ 24 }
								sm={ 12 }
								lg={ 8 }
								xl={ 6 }
								xxl={ 4 }
							>
								<Card
									hoverable
									className="vist360-tour-card"
									cover={
										<button
											type="button"
											className="vist360-tour-card__cover"
											onClick={ () =>
												navigate( `edit/${ tour.id }` )
											}
										>
											{ thumb ? (
												<img src={ thumb } alt="" />
											) : (
												<PictureOutlined />
											) }
											<Tag
												color={ tag.color }
												className="vist360-tour-card__status"
											>
												{ tag.label }
											</Tag>
										</button>
									}
									actions={ [
										<Button
											key="edit"
											size="small"
											onClick={ () =>
												navigate( `edit/${ tour.id }` )
											}
										>
											{ __(
												'Edit',
												'vistour-virtual-tour-builder'
											) }
										</Button>,
										<Dropdown
											key="more"
											menu={ menuFor( tour ) }
											trigger={ [ 'click' ] }
										>
											<Button
												size="small"
												type="text"
												icon={ <MoreOutlined /> }
												aria-label={ __(
													'Tour actions',
													'vistour-virtual-tour-builder'
												) }
											/>
										</Dropdown>,
									] }
								>
									<Card.Meta
										title={
											decodeEntities(
												tour.title.rendered
											) ||
											__(
												'(no title)',
												'vistour-virtual-tour-builder'
											)
										}
										description={ sprintf(
											/* translators: 1: scene count, 2: view count. */
											__(
												'%1$d scenes · %2$d views',
												'vistour-virtual-tour-builder'
											),
											scenes,
											views
										) }
									/>
								</Card>
							</Col>
						);
					} ) }
				</Row>
			) }
		</div>
	);
};

export default ToursList;
