import type { ActivityField } from '@/admin/api/activities';
import { __ } from '@wordpress/i18n';
import { Expand, Image, Music, Pencil, Trash2, Video, X } from 'lucide-react';
import { createPortal } from 'react-dom';
import { useEffect, useState } from 'react';

// WP media global
declare const wp: {
	media: (options: {
		title?: string;
		button?: { text: string };
		multiple?: boolean;
		library?: { type?: string };
	}) => {
		on: (event: string, cb: () => void) => void;
		open: () => void;
		state: () => {
			get: (key: string) => {
				first: () => { toJSON: () => { url: string; filename: string } };
			};
		};
	};
};

type MediaField = Extract<ActivityField, { type: 'image' | 'video' | 'audio' }>;

const MEDIA_META: Record<
	'image' | 'video' | 'audio',
	{ icon: React.ElementType; addLabel: string; sub: string; libraryType: string }
> = {
	image: {
		icon: Image,
		addLabel: __('Add Image', 'allcoach'),
		sub: __('Click to select from media library', 'allcoach'),
		libraryType: 'image',
	},
	video: {
		icon: Video,
		addLabel: __('Add Video', 'allcoach'),
		sub: __('Click to select from media library', 'allcoach'),
		libraryType: 'video',
	},
	audio: {
		icon: Music,
		addLabel: __('Add Audio', 'allcoach'),
		sub: __('Click to select from media library', 'allcoach'),
		libraryType: 'audio',
	},
};

function openWpMedia(
	libraryType: string,
	title: string,
	onSelect: (url: string, filename: string) => void,
) {
	if (typeof wp === 'undefined' || typeof wp.media !== 'function') {
		console.error('wp.media is not available. Ensure wp_enqueue_media() is called.');
		return;
	}

	const frame = wp.media({
		title,
		button: { text: __('Use this file', 'allcoach') },
		multiple: false,
		library: { type: libraryType },
	});

	frame.on('select', () => {
		const attachment = frame.state().get('selection').first().toJSON();
		onSelect(attachment.url, attachment.filename);
	});

	frame.open();
}

type Props = {
	field: MediaField;
	onChange: (f: ActivityField) => void;
};

const WpMediaBlock = ({ field, onChange }: Props) => {
	const meta = MEDIA_META[field.type];
	const Icon = meta.icon;
	const hasMedia = !!field.url;
	const [lightbox, setLightbox] = useState(false);

	useEffect(() => {
		if (!lightbox) return;
		const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setLightbox(false); };
		document.addEventListener('keydown', onKey);
		return () => document.removeEventListener('keydown', onKey);
	}, [lightbox]);

	const handleOpen = () => {
		openWpMedia(meta.libraryType, meta.addLabel, (url, filename) => {
			// Use filename as default title only if title is currently empty
			const title = field.title || filename;
			onChange({ ...field, url, title } as ActivityField);
		});
	};

	const handleRemove = () => {
		onChange({ ...field, url: '', title: '' } as ActivityField);
	};

	return (
		<div className="rounded-[9px] border border-gray-200 bg-white transition-colors focus-within:border-teal-400">
			{/* Header row */}
			<div className="group/title flex items-center gap-3 px-4 py-3">
				<div className="relative flex min-w-0 flex-1 items-center">
					<input
						value={field.title ?? ''}
						onChange={(e) => onChange({ ...field, title: e.target.value } as ActivityField)}
						placeholder={
							field.url
								? (field.url.split('/').pop()?.split('?')[0] ?? meta.addLabel)
								: meta.addLabel
						}
						className="min-w-0 flex-1 rounded-md bg-transparent py-0.5 pl-2 pr-6 text-[13px] font-semibold text-gray-800 outline-none placeholder:font-normal placeholder:text-gray-400 hover:bg-gray-100 focus:bg-gray-100"
					/>
					<Pencil className="pointer-events-none absolute right-1.5 size-3 text-gray-400 opacity-0 transition-opacity group-hover/title:opacity-100" />
				</div>
				{hasMedia && (
					<div className="ml-auto flex shrink-0 items-center gap-1">
						{field.type === 'image' && (
							<button
								type="button"
								onClick={() => setLightbox(true)}
								className="flex items-center justify-center rounded-md p-1 text-gray-400 hover:bg-gray-100 hover:text-gray-600"
								title={__('View full size', 'allcoach')}
							>
								<Expand className="size-3.5" />
							</button>
						)}
						<button
							type="button"
							onClick={handleOpen}
							className="flex items-center gap-1.5 rounded-md px-2.5 py-1 text-[11px] font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-700"
						>
							<Pencil className="size-3" />
							{__('Replace', 'allcoach')}
						</button>
						<button
							type="button"
							onClick={handleRemove}
							className="flex items-center gap-1.5 rounded-md px-2.5 py-1 text-[11px] font-medium text-red-400 hover:bg-red-50 hover:text-red-600"
						>
							<Trash2 className="size-3" />
							{__('Remove', 'allcoach')}
						</button>
					</div>
				)}
			</div>

			{/* Media content */}
			<div className="border-t border-gray-100">
				{!hasMedia ? (
					<button
						type="button"
						onClick={handleOpen}
						className="group/m flex w-full flex-col items-center gap-2 p-8 text-center transition-colors hover:bg-gray-50"
					>
						<Icon className="size-6 text-gray-300 transition-colors group-hover/m:text-teal-400" />
						<div className="text-[13px] font-medium text-gray-500">{meta.addLabel}</div>
						<div className="text-[11px] text-gray-400">{meta.sub}</div>
					</button>
				) : (
					<>
						{field.type === 'image' && (
							<img
								src={field.url}
								alt={field.title ?? ''}
								className="max-h-64 w-full object-cover"
							/>
						)}
						{field.type === 'video' && (
							<video src={field.url} controls className="w-full" />
						)}
						{field.type === 'audio' && (
							<div className="px-4 py-3">
								<audio src={field.url} controls className="w-full" />
							</div>
						)}
					</>
				)}
			</div>

			{/* Lightbox */}
			{lightbox && field.type === 'image' && createPortal(
				<div
					className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/60 p-8"
					onClick={() => setLightbox(false)}
				>
					<div
						className="relative max-h-[80vh] w-full max-w-3xl overflow-hidden rounded-xl bg-white shadow-2xl"
						onClick={(e) => e.stopPropagation()}
					>
						<button
							type="button"
							onClick={() => setLightbox(false)}
							className="absolute top-3 right-3 z-10 flex size-7 items-center justify-center rounded-full bg-black/40 text-white hover:bg-black/60"
						>
							<X className="size-3.5" />
						</button>
						<img
							src={field.url}
							alt={field.title ?? ''}
							className="max-h-[80vh] w-full object-contain"
						/>
						{field.title && (
							<div className="border-t border-gray-100 px-4 py-2.5 text-[12px] text-gray-500">
								{field.title}
							</div>
						)}
					</div>
				</div>,
				document.body,
			)}
		</div>
	);
};

export default WpMediaBlock;
