/**
 * WhatsNewPanel
 *
 * Slide-in drawer modelled after the Tracking add-on's DrillPanel.
 * Shows Unread / Read tabs; individual cards can be marked as read.
 * Cards use flat one-liner items (no section headings).
 * No external CSS file — pure Tailwind.
 */

/**
 * WordPress Dependencies
 */
import { __ } from '@wordpress/i18n';
import { useState, useEffect, RawHTML, createPortal } from '@wordpress/element';

/**
 * Internal Dependencies
 */
import { clsx as cx } from '@admin/utils';

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

/**
 * Return a human-readable relative date string using the browser-native
 * Intl.RelativeTimeFormat API.
 *
 * @param {string} dateStr MySQL datetime string from the REST response.
 * @return {string} Relative date text.
 */
function relativeDate( dateStr ) {
	const utc = dateStr.endsWith( 'Z' ) ? dateStr : dateStr + 'Z';
	const diff = Math.floor(
		( Date.now() - new Date( utc ).getTime() ) / 1000
	);
	const rtf = new Intl.RelativeTimeFormat(
		document.documentElement.lang || 'en',
		{ numeric: 'auto' }
	);

	const thresholds = [
		{ limit: 60, unit: 'second', divisor: 1 },
		{ limit: 3600, unit: 'minute', divisor: 60 },
		{ limit: 86400, unit: 'hour', divisor: 3600 },
		{ limit: 604800, unit: 'day', divisor: 86400 },
		{ limit: 2592000, unit: 'week', divisor: 604800 },
		{ limit: Infinity, unit: 'month', divisor: 2592000 },
	];

	const { unit, divisor } = thresholds.find( ( { limit } ) => diff < limit );
	return rtf.format( -Math.floor( diff / divisor ), unit );
}

// ---------------------------------------------------------------------------
// Sub-components
// ---------------------------------------------------------------------------

/**
 * One release card.
 *
 * @param {Object}   props            Component props.
 * @param {Object}   props.release    Release data object.
 * @param {Function} props.onMarkRead Called with release.id when the user marks it as read. Undefined on the Read tab.
 * @return {Object} Release card element.
 */
function ReleaseCard( { release, onMarkRead } ) {
	return (
		<div className="border-b border-[#f0f0f1] pb-5 mb-5 last:border-0 last:pb-0 last:mb-0">
			{ /* Addon Tag Badge */ }
			<div className="mb-2">
				<span className="inline-block rounded-full bg-[#e3f2fd] px-2.5 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-[#1450a3]">
					{ release.addon || __( 'Advanced Ads', 'advanced-ads' ) }
				</span>
			</div>

			{ /* Version Title */ }
			<h3 className="m-0 mb-1 text-[20px] font-bold leading-snug text-[#1d2327]">
				{ release.version }
			</h3>

			{ /* Date Subtitle */ }
			<div className="text-[12px] text-[--color-wp-muted,#787c82] mb-3">
				{ relativeDate( release.synced ) }
			</div>

			{ /* Release Notes */ }
			<div className="[&_div]:m-0 [&_div]:p-0 [&_div>div]:py-1.5 [&_div>div]:text-[12px] [&_div>div]:leading-relaxed [&_div>div]:border-b [&_div>div]:border-[#f0f0f1] [&_div>div:last-child]:border-0 [&_div>div:last-child]:pb-0 [&_strong]:font-semibold [&_h2]:hidden [&_h3]:hidden [&_.aa-tag]:inline-flex [&_.aa-tag]:mr-1 [&_.aa-tag]:items-center [&_.aa-tag]:justify-center [&_.aa-tag]:w-[38px] [&_.aa-tag]:shrink-0 [&_.aa-tag]:rounded [&_.aa-tag]:text-[10px] [&_.aa-tag]:font-bold [&_.aa-tag]:uppercase [&_.aa-tag]:tracking-wide [&_.aa-tag--new]:bg-[#dcfce7] [&_.aa-tag--new]:text-[#166534] [&_.aa-tag--fix]:bg-[#fee2e2] [&_.aa-tag--fix]:text-[#991b1b] [&_.aa-tag--improvement]:bg-[#dbeafe] [&_.aa-tag--improvement]:text-[#1e40af] [&_.aa-tag--update]:bg-[#ede9fe] [&_.aa-tag--update]:text-[#5b21b6]">
				<RawHTML>{ release.content }</RawHTML>
			</div>

			{ /* Mark as Read button — only shown on the Unread tab */ }
			{ onMarkRead && (
				<div className="mt-3 flex justify-start">
					<button
						type="button"
						onClick={ () => onMarkRead( release.id ) }
						className="cursor-pointer rounded border border-[#c3c4c7] bg-[#f6f7f7] px-2.5 py-1 text-[11px] font-medium text-[#3c434a] hover:bg-[#f0f0f1] transition-colors"
					>
						{ __( 'Mark as read', 'advanced-ads' ) }
					</button>
				</div>
			) }
		</div>
	);
}

// ---------------------------------------------------------------------------
// Tab button
// ---------------------------------------------------------------------------

function Tab( { label, count, active, onClick } ) {
	return (
		<button
			type="button"
			onClick={ onClick }
			className={ cx(
				'flex items-center gap-1.5 px-3 py-2 text-[12px] font-medium border-b-2 transition-colors cursor-pointer bg-transparent',
				active
					? 'border-color-primary text-color-primary'
					: 'border-transparent text-[#787c82] hover:text-[#1d2327]'
			) }
		>
			{ label }
			{ count > 0 && (
				<span className="rounded-full px-1.5 py-px text-[10px] font-bold leading-none bg-blue-50 text-[#3c434a]">
					{ count }
				</span>
			) }
		</button>
	);
}

// ---------------------------------------------------------------------------
// Panel
// ---------------------------------------------------------------------------

export function WhatsNewPanel( { unread, read, onClose, onMarkRead } ) {
	const [ visible, setVisible ] = useState( false );
	const [ activeTab, setActiveTab ] = useState( 'unread' );

	useEffect( () => {
		const t = setTimeout( () => setVisible( true ), 50 );
		return () => clearTimeout( t );
	}, [] );

	const handleClose = () => {
		setVisible( false );
		setTimeout( onClose, 300 );
	};

	const releases = activeTab === 'unread' ? unread : read;

	return createPortal(
		<div className="fixed top-8 right-0 bottom-0 left-0 z-[99] flex justify-end">
			{ /* Backdrop */ }
			<div
				role="button"
				tabIndex={ 0 }
				onClick={ handleClose }
				onKeyDown={ ( e ) => {
					if ( e.key === 'Enter' || e.key === ' ' ) {
						handleClose();
					}
				} }
				className={ cx(
					'absolute inset-0 cursor-pointer bg-black/40 transition-opacity duration-200',
					visible ? 'opacity-100' : 'opacity-0'
				) }
			/>

			{ /* Drawer */ }
			<aside
				role="dialog"
				aria-modal="true"
				aria-label={ __( "What's New", 'advanced-ads' ) }
				className={ cx(
					'relative flex h-full w-[min(480px,94vw)] flex-col bg-white shadow-lg',
					'transition-transform duration-300 ease-out',
					visible ? 'translate-x-0' : 'translate-x-full'
				) }
			>
				{ /* Header */ }
				<div className="flex items-center justify-between border-b border-[#e2e4e7] px-5 py-4 shrink-0">
					<h2 className="m-0 text-[17px] font-semibold leading-tight">
						{ __( "What's New?", 'advanced-ads' ) }
					</h2>
					<button
						type="button"
						onClick={ handleClose }
						className="flex h-7 w-7 flex-none cursor-pointer items-center justify-center rounded border border-[#c3c4c7] bg-[#f6f7f7] text-[14px] text-[#787c82] hover:bg-[#f0f0f1]"
						aria-label={ __( 'Close', 'advanced-ads' ) }
					>
						×
					</button>
				</div>

				{ /* Tabs */ }
				<div className="flex gap-1 border-b border-[#e2e4e7] px-5 shrink-0">
					<Tab
						label={ __( 'Unread', 'advanced-ads' ) }
						count={ unread.length }
						active={ activeTab === 'unread' }
						onClick={ () => setActiveTab( 'unread' ) }
					/>
					<Tab
						label={ __( 'Read', 'advanced-ads' ) }
						count={ read.length }
						active={ activeTab === 'read' }
						onClick={ () => setActiveTab( 'read' ) }
					/>
				</div>

				{ /* Content */ }
				<div className="flex-1 overflow-y-auto px-5 py-5">
					{ releases.length > 0 ? (
						releases.map( ( release ) => (
							<ReleaseCard
								key={ release.id }
								release={ release }
								onMarkRead={
									activeTab === 'unread'
									? onMarkRead
									: undefined
								}
							/>
						) )
					) : (
						<p className="text-center text-[13px] text-[#787c82] mt-8">
							{ activeTab === 'unread'
								? __( "You're all caught up!", 'advanced-ads' )
								: __( 'No read entries yet.', 'advanced-ads' ) }
						</p>
					) }
				</div>
			</aside>
		</div>,
		document.body
	);
}
