import React, { useId, useState } from 'react';
import { __ } from '@wordpress/i18n';
import Icon from '../icons/Icon';

export function Card({ title, subtitle, actions, footer, children, className = '', bodyClassName = '', flat = false, as: Element = 'section', ...rest }) {
	return (
		<Element className={['bp-card', flat ? 'bp-card--flat' : '', className].filter(Boolean).join(' ')} {...rest}>
			{title || actions ? (
				<header className="bp-card__header">
					<div style={{ minWidth: 0 }}>
						{title ? <h3 className="bp-card__title">{title}</h3> : null}
						{subtitle ? <p className="bp-card__subtitle">{subtitle}</p> : null}
					</div>
					{actions ? <div className="bp-cluster">{actions}</div> : null}
				</header>
			) : null}
			<div className={['bp-card__body', bodyClassName].filter(Boolean).join(' ')}>{children}</div>
			{footer ? <footer className="bp-card__footer">{footer}</footer> : null}
		</Element>
	);
}

export function Badge({ tone = 'neutral', dot = false, size, children, className = '' }) {
	return (
		<span
			className={[
				'bp-badge',
				tone !== 'neutral' ? `bp-badge--${tone}` : '',
				dot ? 'bp-badge--dot' : '',
				size === 'lg' ? 'bp-badge--lg' : '',
				className,
			]
				.filter(Boolean)
				.join(' ')}
		>
			{children}
		</span>
	);
}

/** Booking / payment status → tone + translated label. */
export function statusMeta(status) {
	const s = String(status || '').toLowerCase();
	const map = {
		pending: { tone: 'warning', label: __('Pending', 'pointly-booking') },
		pending_payment: { tone: 'warning', label: __('Awaiting payment', 'pointly-booking') },
		confirmed: { tone: 'success', label: __('Confirmed', 'pointly-booking') },
		approved: { tone: 'success', label: __('Approved', 'pointly-booking') },
		completed: { tone: 'info', label: __('Completed', 'pointly-booking') },
		cancelled: { tone: 'danger', label: __('Cancelled', 'pointly-booking') },
		failed_payment: { tone: 'danger', label: __('Payment failed', 'pointly-booking') },
		no_show: { tone: 'neutral', label: __('No-show', 'pointly-booking') },
		paid: { tone: 'success', label: __('Paid', 'pointly-booking') },
		unpaid: { tone: 'neutral', label: __('Unpaid', 'pointly-booking') },
		refunded: { tone: 'info', label: __('Refunded', 'pointly-booking') },
		active: { tone: 'success', label: __('Active', 'pointly-booking') },
		inactive: { tone: 'neutral', label: __('Inactive', 'pointly-booking') },
		disabled: { tone: 'neutral', label: __('Disabled', 'pointly-booking') },
	};
	return map[s] || { tone: 'neutral', label: s ? s.replace(/_/g, ' ') : '—' };
}

export function StatusBadge({ status, size }) {
	const meta = statusMeta(status);
	return (
		<Badge tone={meta.tone} dot size={size}>
			{meta.label}
		</Badge>
	);
}

const ALERT_ICONS = { info: 'info', success: 'check-circle', warning: 'alert-triangle', danger: 'alert-circle' };

export function Alert({ tone = 'info', title, children, actions, className = '', live = false }) {
	return (
		<div
			className={['bp-alert', tone !== 'info' ? `bp-alert--${tone}` : '', className].filter(Boolean).join(' ')}
			role={live ? (tone === 'danger' ? 'alert' : 'status') : undefined}
		>
			<Icon name={ALERT_ICONS[tone] || 'info'} className="bp-alert__icon" />
			<div className="bp-alert__body">
				{title ? <div className="bp-alert__title">{title}</div> : null}
				{children ? <div>{children}</div> : null}
			</div>
			{actions ? <div className="bp-cluster">{actions}</div> : null}
		</div>
	);
}

const AVATAR_TONES = ['#e0e7ff', '#dcfce7', '#fef3c7', '#fce7f3', '#e0f2fe', '#ede9fe', '#ffedd5', '#ccfbf1'];
const AVATAR_TEXT = ['#3730a3', '#166534', '#92400e', '#9d174d', '#075985', '#5b21b6', '#9a3412', '#115e59'];

export function initials(name) {
	const parts = String(name || '').trim().split(/\s+/).filter(Boolean);
	if (!parts.length) return '?';
	const first = parts[0][0] || '';
	const last = parts.length > 1 ? parts[parts.length - 1][0] : '';
	return `${first}${last}`.toUpperCase();
}

export function Avatar({ name = '', src, size = 'md', square = false, className = '' }) {
	const [broken, setBroken] = useState(false);
	let hash = 0;
	for (let i = 0; i < name.length; i++) hash = (hash * 31 + name.charCodeAt(i)) >>> 0;
	const idx = hash % AVATAR_TONES.length;
	const style = src && !broken ? undefined : { '--_bg': AVATAR_TONES[idx], '--_fg': AVATAR_TEXT[idx] };
	return (
		<span
			className={['bp-avatar', size !== 'md' ? `bp-avatar--${size}` : '', square ? 'bp-avatar--square' : '', className].filter(Boolean).join(' ')}
			style={style}
			aria-hidden="true"
		>
			{src && !broken ? <img src={src} alt="" loading="lazy" onError={() => setBroken(true)} /> : initials(name)}
		</span>
	);
}

export function Tag({ icon, children }) {
	return (
		<span className="bp-tag">
			{icon ? <Icon name={icon} /> : null}
			{children}
		</span>
	);
}

export function EmptyState({ icon = 'sparkles', title, children, actions, compact = false }) {
	return (
		<div className={['bp-empty', compact ? 'bp-empty--compact' : ''].filter(Boolean).join(' ')}>
			<div className="bp-empty__icon">
				<Icon name={icon} />
			</div>
			{title ? <div className="bp-empty__title">{title}</div> : null}
			{children ? <div className="bp-empty__text">{children}</div> : null}
			{actions ? <div className="bp-empty__actions">{actions}</div> : null}
		</div>
	);
}

/**
 * Skeleton placeholder. Wrap groups in <SkeletonGroup label="…"> so screen
 * readers announce loading once.
 */
export function Skeleton({ width, height, circle = false, block = false, className = '', style }) {
	return (
		<span
			aria-hidden="true"
			className={['bp-skel', circle ? 'bp-skel--circle' : '', block ? 'bp-skel--block' : '', className].filter(Boolean).join(' ')}
			style={{ '--_w': typeof width === 'number' ? `${width}px` : width, '--_h': typeof height === 'number' ? `${height}px` : height, ...style }}
		/>
	);
}

export function SkeletonGroup({ label = __('Loading…', 'pointly-booking'), children, className = '' }) {
	return (
		<div className={className} role="status" aria-live="polite" aria-busy="true">
			<span className="bp-visually-hidden">{label}</span>
			{children}
		</div>
	);
}

export function Stat({ label, value, icon, delta, deltaDir, hint, loading = false }) {
	return (
		<div className="bp-stat">
			<div className="bp-stat__label">
				{icon ? (
					<span className="bp-stat__icon">
						<Icon name={icon} />
					</span>
				) : null}
				{label}
			</div>
			{loading ? <Skeleton width="60%" height={28} /> : <div className="bp-stat__value">{value}</div>}
			{delta && !loading ? (
				<div className={['bp-stat__delta', deltaDir === 'up' ? 'is-up' : deltaDir === 'down' ? 'is-down' : ''].join(' ')}>{delta}</div>
			) : null}
			{hint && !loading ? <div className="bp-text-subtle bp-text-xs">{hint}</div> : null}
		</div>
	);
}

/** Label/value rows; items = [{term, desc, total?}] */
export function DescriptionList({ items = [], className = '' }) {
	return (
		<dl className={['bp-dl', className].filter(Boolean).join(' ')}>
			{items
				.filter((it) => it && it.desc !== undefined && it.desc !== null && it.desc !== '')
				.map((it, i) => (
					<div key={`${it.term}-${i}`} className={['bp-dl__row', it.total ? 'bp-dl__row--total' : ''].filter(Boolean).join(' ')}>
						<dt className="bp-dl__term">{it.term}</dt>
						<dd className="bp-dl__desc" style={{ margin: 0 }}>
							{it.desc}
						</dd>
					</div>
				))}
		</dl>
	);
}

/**
 * Tooltip on hover/focus of its child. The child must be focusable; the text
 * is also exposed through aria-describedby.
 */
export function Tooltip({ text, placement = 'top', children }) {
	const [show, setShow] = useState(false);
	const id = `bp-tt-${useId().replace(/:/g, '')}`;
	const child = React.Children.only(children);
	return (
		<span
			className="bp-tooltip-anchor"
			onMouseEnter={() => setShow(true)}
			onMouseLeave={() => setShow(false)}
			onFocus={() => setShow(true)}
			onBlur={() => setShow(false)}
			onKeyDown={(e) => e.key === 'Escape' && setShow(false)}
		>
			{React.cloneElement(child, { 'aria-describedby': [child.props['aria-describedby'], id].filter(Boolean).join(' ') })}
			<span id={id} role="tooltip" className={['bp-tooltip', placement === 'bottom' ? 'bp-tooltip--bottom' : ''].join(' ')} hidden={!show}>
				{text}
			</span>
		</span>
	);
}
