import React, { useState } from 'react';
import { __, _n, sprintf } from '@wordpress/i18n';
import { Button, Badge } from './ui';

/**
 * The check list, grouped and collapsible.
 *
 * A flat list of twenty-six rows is a list nobody reads to the end. Grouping
 * them by subject — title, then body, then links, then the technical leftovers
 * — with a count of what is still open in each header means the writer can
 * open the one group that concerns them and ignore the rest. Groups that are
 * entirely passing start collapsed, because "all good" needs one line, not
 * seven.
 */

const MARK = {
	pass: { glyph: '✓', tone: 'var(--ars-good)', bg: 'var(--ars-good-tonal)' },
	warn: { glyph: '!', tone: 'var(--ars-warning)', bg: 'var(--ars-warning-tonal)' },
	fail: { glyph: '✕', tone: 'var(--ars-serious)', bg: 'var(--ars-serious-tonal)' },
};

function Row({ check, onFix, fixing }) {
	const [open, setOpen] = useState(false);
	const mark = MARK[check.status] || MARK.warn;
	const hasDetail = check.status !== 'pass' && !!check.fix;

	return (
		<li
			className="px-3 py-2"
			style={{
				borderRadius: 'var(--ars-r-sm)',
				background: check.status === 'pass' ? 'transparent' : 'var(--ars-surface-2)',
			}}
		>
			<div className="flex items-start gap-2.5">
				<span
					aria-hidden
					className="shrink-0 inline-flex items-center justify-center"
					style={{
						width: 17,
						height: 17,
						marginTop: 1,
						borderRadius: 'var(--ars-r-xs)',
						background: mark.bg,
						color: mark.tone,
						fontSize: 11,
						fontWeight: 700,
						lineHeight: 1,
					}}
				>
					{mark.glyph}
				</span>

				<span className="flex-1 min-w-0 text-[13px]" style={{ lineHeight: 1.45 }}>
					{check.label}
				</span>

				<span className="flex items-center gap-1.5 shrink-0">
					{check.ai && check.status !== 'pass' && onFix && (
						<Button variant="ghost" busy={fixing} onClick={() => onFix(check)}>{__('Fix with AI', 'ai-rank-suite')}</Button>
					)}
					{hasDetail && (
						<button
							type="button"
							aria-expanded={open}
							aria-label={open ? __('Hide explanation', 'ai-rank-suite') : __('Why this matters', 'ai-rank-suite')}
							onClick={() => setOpen(!open)}
							className="cursor-pointer inline-flex items-center justify-center"
							style={{
								width: 18,
								height: 18,
								borderRadius: 'var(--ars-r-xs)',
								border: '1px solid var(--ars-border)',
								background: 'var(--ars-surface)',
								color: 'var(--ars-ink-3)',
								fontSize: 11,
								fontWeight: 700,
								lineHeight: 1,
							}}
						>
							?
						</button>
					)}
				</span>
			</div>

			{open && hasDetail && (
				<p className="m-0 mt-1.5 ml-[27px] text-[12px]" style={{ color: 'var(--ars-ink-2)' }}>
					{check.fix}
				</p>
			)}
		</li>
	);
}

export default function CheckList({ checks = [], sections = {}, onFix, fixing = null }) {
	const order = Object.keys(sections).length
		? Object.entries(sections)
		: [['basics', __('Checks', 'ai-rank-suite')]];

	// A check whose section the server does not know about would otherwise
	// vanish silently, which is the worst way for a check to fail.
	const known = new Set(order.map(([id]) => id));
	const orphans = checks.filter((c) => !known.has(c.section));

	const [collapsed, setCollapsed] = useState({});

	const render = (id, label, rows) => {
		if (!rows.length) return null;
		const open = rows.filter((c) => c.status !== 'pass');
		const allGood = open.length === 0;
		// Passing groups start closed; a group with work in it starts open.
		const isOpen = collapsed[id] === undefined ? !allGood : !collapsed[id];

		return (
			<div key={id} className="ars-r-sm" style={{ border: '1px solid var(--ars-border)' }}>
				<button
					type="button"
					aria-expanded={isOpen}
					onClick={() => setCollapsed({ ...collapsed, [id]: isOpen })}
					className="w-full flex items-center gap-2.5 px-3 py-2 cursor-pointer"
					style={{ background: 'var(--ars-surface-2)', border: 0, borderRadius: 'var(--ars-r-sm)' }}
				>
					<span aria-hidden style={{ color: 'var(--ars-ink-3)', width: 10, fontSize: 11 }}>
						{isOpen ? '▾' : '▸'}
					</span>
					<span className="font-semibold text-[13px]">{label}</span>
					{allGood ? (
						<Badge tone="good">✓ {__('All good', 'ai-rank-suite')}</Badge>
					) : (
						<Badge tone={open.some((c) => c.status === 'fail') ? 'serious' : 'warning'}>
							{sprintf(_n('%d to fix', '%d to fix', open.length, 'ai-rank-suite'), open.length)}
						</Badge>
					)}
					<span className="ml-auto t-caption">{rows.length}</span>
				</button>

				{isOpen && (
					<ul className="m-0 p-2 list-none grid gap-1">
						{rows.map((c) => (
							<Row key={c.id} check={c} onFix={onFix} fixing={fixing === c.id} />
						))}
					</ul>
				)}
			</div>
		);
	};

	return (
		<div className="grid gap-2">
			{order.map(([id, label]) => render(id, label, checks.filter((c) => c.section === id)))}
			{render('other', __('Other', 'ai-rank-suite'), orphans)}
		</div>
	);
}
