import React, { useEffect, useMemo, useRef, useState } from 'react';
import { __, sprintf } from '@wordpress/i18n';
import { formatDate, formatMoney, formatNumber } from '../core/format';

/**
 * Daily bar chart in plain SVG (no chart library).
 *
 * @param {Array<{day:string, bookings:number, revenue:number}>} data
 * @param {'bookings'|'revenue'} metric
 */
export function BarChart({ data, metric = 'bookings', currency, height = 200 }) {
	const [hover, setHover] = useState(null);
	const wrapRef = useRef(null);
	const [width, setWidth] = useState(720);
	// Render at the real pixel width so text and bars are not stretched.
	useEffect(() => {
		const el = wrapRef.current;
		if (!el || typeof ResizeObserver === 'undefined') return undefined;
		const ro = new ResizeObserver(([entry]) => setWidth(Math.max(280, Math.round(entry.contentRect.width))));
		ro.observe(el);
		return () => ro.disconnect();
	}, []);
	const pad = { top: 12, right: 8, bottom: 26, left: 36 };

	const { max, ticks } = useMemo(() => {
		const rawMax = Math.max(0, ...data.map((d) => Number(d[metric]) || 0));
		const niceMax = rawMax <= 4 ? 4 : Math.ceil(rawMax / 4) * 4;
		return { max: niceMax, ticks: [0, 1, 2, 3, 4].map((i) => (niceMax / 4) * i) };
	}, [data, metric]);

	const innerW = width - pad.left - pad.right;
	const innerH = height - pad.top - pad.bottom;
	const slot = data.length ? innerW / data.length : innerW;
	const barW = Math.max(2, Math.min(28, slot * 0.62));
	const labelEvery = Math.max(1, Math.ceil(data.length / Math.max(2, Math.floor(innerW / 64))));
	const fmt = (v) => (metric === 'revenue' ? formatMoney(v, currency) : formatNumber(v));
	const active = hover !== null ? data[hover] : null;

	const summary = sprintf(
		/* translators: 1: metric name, 2: first day, 3: last day. */
		__('%1$s per day from %2$s to %3$s', 'pointly-booking'),
		metric === 'revenue' ? __('Revenue', 'pointly-booking') : __('Bookings', 'pointly-booking'),
		data[0] ? formatDate(data[0].day) : '',
		data.length ? formatDate(data[data.length - 1].day) : ''
	);

	return (
		<figure className="bp-chart" ref={wrapRef}>
			<svg viewBox={`0 0 ${width} ${height}`} role="img" aria-label={summary} className="bp-chart__svg" width={width} height={height}>
				{ticks.map((t) => {
					const y = pad.top + innerH - (t / max) * innerH;
					return (
						<g key={t}>
							<line x1={pad.left} x2={width - pad.right} y1={y} y2={y} className="bp-chart__grid" />
							<text x={pad.left - 6} y={y + 4} textAnchor="end" className="bp-chart__tick">
								{metric === 'revenue' ? formatNumber(Math.round(t)) : Math.round(t)}
							</text>
						</g>
					);
				})}
				{data.map((d, i) => {
					const v = Number(d[metric]) || 0;
					const h = (v / max) * innerH;
					const x = pad.left + i * slot + (slot - barW) / 2;
					const y = pad.top + innerH - h;
					return (
						<g key={d.day} onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)}>
							<rect x={pad.left + i * slot} y={pad.top} width={slot} height={innerH} fill="transparent" />
							<rect x={x} y={v > 0 ? y : pad.top + innerH - 1} width={barW} height={v > 0 ? Math.max(h, 2) : 1} rx="3" className={hover === i ? 'bp-chart__bar is-active' : 'bp-chart__bar'} />
							{i % labelEvery === 0 ? (
								<text x={pad.left + i * slot + slot / 2} y={height - 8} textAnchor="middle" className="bp-chart__tick">
									{formatDate(d.day, { day: 'numeric', month: 'short' })}
								</text>
							) : null}
						</g>
					);
				})}
			</svg>
			<figcaption className="bp-chart__caption" aria-live="polite">
				{active ? (
					<>
						<strong>{formatDate(active.day, { weekday: 'short', day: 'numeric', month: 'short' })}</strong> · {fmt(active[metric])}
					</>
				) : (
					<span className="bp-text-subtle">{__('Hover a bar for details', 'pointly-booking')}</span>
				)}
			</figcaption>
			<table className="bp-visually-hidden">
				<caption>{summary}</caption>
				<thead>
					<tr>
						<th scope="col">{__('Date', 'pointly-booking')}</th>
						<th scope="col">{metric === 'revenue' ? __('Revenue', 'pointly-booking') : __('Bookings', 'pointly-booking')}</th>
					</tr>
				</thead>
				<tbody>
					{data.map((d) => (
						<tr key={d.day}>
							<td>{formatDate(d.day)}</td>
							<td>{fmt(d[metric])}</td>
						</tr>
					))}
				</tbody>
			</table>
		</figure>
	);
}
