import React, { useEffect, useState } from 'react';
import { __, _n, sprintf } from '@wordpress/i18n';
import { api } from '../api';
import { Notice, Button } from './ui';
import { IconRefresh } from './icons';

/**
 * The full page report.
 *
 * Every other tab in this drawer answers part of the question. This one
 * answers the whole of it — is this page done? — as a single list of
 * requirements with a pass or a fail against each, weighted by how much each
 * one actually costs you.
 *
 * The weighting is why the number at the top is worth having. A missing meta
 * description and a missing twitter:card are not the same size of problem, and
 * a scorecard that averages them as if they were is a scorecard nobody should
 * act on.
 */
export default function ReportTab({ postId, onGoTo }) {
	const [data, setData] = useState(null);
	const [error, setError] = useState(null);
	const [busy, setBusy] = useState(false);
	const [only, setOnly] = useState(false);

	const load = () => {
		setBusy(true);
		api
			.get(`/content/${postId}/report`)
			.then(setData)
			.catch((e) => setError(e.message))
			.finally(() => setBusy(false));
	};

	useEffect(() => {
		setData(null);
		load();
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [postId]);

	if (error) return <Notice tone="serious">{error}</Notice>;
	if (!data) return <div className="t-caption p-2">{__('Checking every requirement…', 'ai-rank-suite')}</div>;

	const tone = data.score >= 85 ? 'green' : data.score >= 60 ? 'amber' : 'red';
	const shown = only ? data.items.filter((i) => !i.pass) : data.items;

	return (
		<div className="grid gap-4">
			<div className={`ars-report-head is-${tone}`}>
				<div className="ars-report-score">
					<b className="tabular-nums">{data.score}</b>
					<span>%</span>
				</div>
				<div className="min-w-0">
					<div className="font-semibold text-[13.5px]">
						{data.failed === 0
							? __('Everything checked out', 'ai-rank-suite')
							: sprintf(__('%1$s of %2$s requirements not met', 'ai-rank-suite'), data.failed, data.passed + data.failed)}
					</div>
					<p className="m-0 mt-0.5 text-[12px]" style={{ color: 'var(--ars-ink-2)' }}>
						{sprintf(__('%1$s words · about %2$s min read · %3$s headings · %4$s images · %5$s internal and %6$s external links', 'ai-rank-suite'), data.words.toLocaleString(), data.reading, data.headings, data.images, data.internal, data.external)}
					</p>
					<div className="ars-report-bar mt-2">
						<span style={{ width: `${data.score}%` }} />
					</div>
					<p className="m-0 mt-1 t-caption">
						{sprintf(__('Weighted by consequence — %1$s of %2$s points. A missing description counts for more than a missing card type, because it costs more.', 'ai-rank-suite'), data.earned, data.possible)}
					</p>
					{/*
					  * What the work did.
					  *
					  * Every number on this screen described the page as it is
					  * now, which made an evening spent on it unprovable. This
					  * is the first reading against the latest one, so a person
					  * can see the thing they changed. It appears only once
					  * there are two readings and the score actually moved: a
					  * permanent "±0" is noise.
					  */}
					{!!data.change && data.change.geo !== 0 && (
						<p className="m-0 mt-1 t-caption">
							<span className={data.change.geo > 0 ? 'ars-c-green-ink' : 'ars-c-red-ink'} style={{ fontWeight: 600 }}>
								{data.change.geo > 0 ? `+${data.change.geo}` : data.change.geo}
							</span>
							{' '}
							{sprintf(
								/* translators: 1: date of the first measurement, 2: number of measurements. */
								_n('on the AI score since %1$s, over %2$s measurement.', 'on the AI score since %1$s, over %2$s measurements.', data.change.points, 'ai-rank-suite'),
								new Date(data.change.since * 1000).toLocaleDateString(),
								data.change.points
							)}
						</p>
					)}
				</div>
				<div className="flex flex-col items-end gap-2 shrink-0">
					<Button variant="ghost" busy={busy} onClick={load}>
						<IconRefresh size={13} />{__('Re-check', 'ai-rank-suite')}</Button>
					<label className="flex items-center gap-1.5 text-[12px] cursor-pointer" style={{ color: 'var(--ars-ink-2)' }}>
						<input type="checkbox" checked={only} onChange={(e) => setOnly(e.target.checked)} />{__('Only what failed', 'ai-rank-suite')}</label>
				</div>
			</div>

			{data.sections.map((section) => {
				const items = shown.filter((i) => i.section === section.id);
				if (items.length === 0) return null;
				const failed = items.filter((i) => !i.pass).length;
				return (
					<div key={section.id} className="ars-report-group">
						<div className="ars-report-group-head">
							<div>
								<div className="font-semibold text-[12.5px]">{section.label}</div>
								<div className="t-caption">{section.note}</div>
							</div>
							<span className="flex items-center gap-3">
								{/* The dots were a weight with no key anywhere on the
								    screen — five of them next to one check and three
								    next to another, explained only in a tooltip a
								    phone cannot show. Said once per group instead. */}
								<span className="ars-report-legend">
									<span className="ars-report-weight" aria-hidden>●●●</span>
									{__('= weight in the score', 'ai-rank-suite')}
								</span>
								<span className={`ars-report-tally${failed > 0 ? ' is-bad' : ''}`}>
									{items.length - failed}/{items.length}
								</span>
							</span>
						</div>
						<div>
							{items.map((item) => (
								<div key={item.id} className={`ars-report-row${item.pass ? ' is-pass' : ''}`}>
									<span className="ars-report-mark" aria-hidden>
										{item.pass ? '✓' : '✕'}
									</span>
									<div className="min-w-0">
										<div className="flex items-center gap-2 flex-wrap">
											<span className="font-medium text-[12.5px]">{item.label}</span>
											<span className="ars-report-weight" title={__('How much this counts toward the score', 'ai-rank-suite')}>
												{'●'.repeat(Math.min(5, item.weight))}
											</span>
										</div>
										<p className="m-0 mt-0.5 text-[12px]" style={{ color: 'var(--ars-ink-2)' }}>
											{item.detail}
										</p>
										{item.value && (
											<code className="ars-report-value" title={item.value}>
												{item.value}
											</code>
										)}
									</div>
									{/* Right edge on every row. It used to sit wherever
									    the text above it ended, so in a column of five
									    checks the one action jumped left and right. */}
									{!item.pass && onGoTo && FIXES[item.id] && (
										<button type="button" className="ars-linkbtn ars-report-fix" onClick={() => onGoTo(FIXES[item.id])}>{__('Fix →', 'ai-rank-suite')}</button>
									)}
								</div>
							))}
						</div>
					</div>
				);
			})}

			{only && data.failed === 0 && (
				<Notice tone="good">{__('Nothing failed. Untick the filter to see everything that passed.', 'ai-rank-suite')}</Notice>
			)}
		</div>
	);
}

/** Which tab each failure is actually fixed on. */
const FIXES = {
	title: 'optimize',
	description: 'optimize',
	keyword: 'keywords',
	keyword_title: 'optimize',
	keyword_opening: 'checks',
	canonical: 'advanced',
	indexable: 'advanced',
	snippet_limit: 'advanced',
	schema: 'schema',
	faq: 'faq',
	og_image: 'preview',
	og_title: 'preview',
	tw_card: 'preview',
	llms: 'advanced',
	h1: 'checks',
	structure: 'checks',
	opening: 'checks',
	length: 'checks',
	alt: 'checks',
};
