import React, { useEffect, useMemo, useState } from 'react';
import { __, _n, sprintf } from '@wordpress/i18n';
import { api } from '../api';
import { Button, Badge, Notice, LengthMeter, Segmented } from './ui';
import { IconRefresh, IconExternal, IconShield } from './icons';
import { copyText } from '../copy';

/**
 * The <head> of one page, in full.
 *
 * Every other SEO plugin writes these tags and then never shows them again —
 * you find out what shipped by reading view-source. This tab is the whole tag
 * list with three things view-source cannot give you: why each tag is there,
 * whether it is within its limit, and (on request) a comparison against the
 * head the server actually delivered, which is the only way a duplicate
 * canonical from a theme ever becomes visible.
 */

const STATUS = {
	ok: { tone: 'good', label: 'ok' },
	missing: { tone: 'serious', label: 'missing' },
	empty: { tone: 'neutral', label: __('not set', 'ai-rank-suite') },
	long: { tone: 'warning', label: __('too long', 'ai-rank-suite') },
	off: { tone: 'neutral', label: __('switched off', 'ai-rank-suite') },
	delegated: { tone: 'warning', label: __('other plugin', 'ai-rank-suite') },
};

export default function HeadTab({ postId, initial = null, onLoad, onGoTo }) {
	const [data, setData] = useState(initial);
	const [error, setError] = useState(null);
	const [live, setLive] = useState(null);
	const [liveBusy, setLiveBusy] = useState(false);
	const [view, setView] = useState('tags');
	const [copied, setCopied] = useState(false);
	const [open, setOpen] = useState({});

	const load = () => {
		setError(null);
		api
			.get(`/content/${postId}/head`)
			.then((next) => {
				setData(next);
				onLoad?.(next);
			})
			.catch((e) => setError(e.message));
	};

	// The drawer usually has this already — refetch only when it does not, so
	// switching to this tab is instant rather than a second spinner.
	useEffect(() => {
		setLive(null);
		if (initial) {
			setData(initial);
			return;
		}
		setData(null);
		load();
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [postId, initial]);

	const fetchLive = async () => {
		setLiveBusy(true);
		try {
			setLive(await api.get(`/content/${postId}/head/live`));
		} catch (e) {
			setLive({ ok: false, reason: e.message });
		} finally {
			setLiveBusy(false);
		}
	};

	const byGroup = useMemo(() => {
		if (!data) return [];
		return data.groups
			.map((g) => ({ ...g, tags: data.tags.filter((t) => t.group === g.id) }))
			.filter((g) => g.tags.length > 0);
	}, [data]);

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

	const c = data.counts || {};

	const copy = async () => {
		if (await copyText(data.source)) {
			setCopied(true);
			setTimeout(() => setCopied(false), 1800);
		}
	};

	return (
		<div className="grid gap-4">
			{/* Summary strip — what state the head is in, in one line. */}
			<div className="ars-head-strip">
				<div className="ars-head-stat">
					<b>{data.tags.filter((t) => t.status === 'ok').length}</b>
					<span>tags in order</span>
				</div>
				{c.missing > 0 && (
					<div className="ars-head-stat is-bad">
						<b>{c.missing}</b>
						<span>missing</span>
					</div>
				)}
				{c.long > 0 && (
					<div className="ars-head-stat is-warn">
						<b>{c.long}</b>
						<span>over length</span>
					</div>
				)}
				{c.empty > 0 && (
					<div className="ars-head-stat">
						<b>{c.empty}</b>
						<span>optional, unset</span>
					</div>
				)}
				<div className="ml-auto flex items-center gap-2">
					<Segmented
						value={view}
						onChange={setView}
						options={[
							{ id: 'tags', label: __('Tags', 'ai-rank-suite') },
							{ id: 'source', label: __('Source', 'ai-rank-suite') },
							{ id: 'live', label: __('Live check', 'ai-rank-suite') },
						]}
					/>
					<button type="button" className="ars-move" title={__('Reload', 'ai-rank-suite')} onClick={load}>
						<IconRefresh size={12} />
					</button>
				</div>
			</div>

			{data.coexist && (
				<Notice tone="warning">
					{data.coexist} is active on this site, so some of these surfaces are written by it rather than by AI Rank Suite.
					Rows marked <b>other plugin</b> are the ones it owns — nothing here is duplicated, which is the point.
				</Notice>
			)}

			{view === 'tags' && (
				<>
					{data.issues.length > 0 && (
						<div className="grid gap-1.5">
							{data.issues.map((issue, i) => (
								<div key={i} className={`ars-head-issue is-${issue.level}`}>
									<span aria-hidden className="ars-head-issue-mark">
										{issue.level === 'error' ? '✕' : issue.level === 'warn' ? '!' : 'i'}
									</span>
									<div>
										<div className="font-semibold text-[12.5px]">{issue.title}</div>
										<div className="text-[12px] mt-0.5" style={{ color: 'var(--ars-ink-2)' }}>
											{issue.text}
										</div>
									</div>
								</div>
							))}
						</div>
					)}

					{byGroup.map((group) => (
						<div key={group.id} className="ars-head-group">
							<div className="ars-head-group-head">
								<div>
									<div className="font-semibold text-[12.5px]">{group.label}</div>
									<div className="t-caption">{group.note}</div>
								</div>
								<span className="t-caption tabular-nums">{group.tags.length}</span>
							</div>
							<div className="ars-head-rows">
								{group.tags.map((tag) => {
									const key = `${group.id}:${tag.key}`;
									const isOpen = !!open[key];
									const meta = STATUS[tag.status] || STATUS.ok;
									return (
										<div key={tag.key} className={`ars-head-row is-${tag.status}`}>
											<button
												type="button"
												className="ars-head-row-main"
												onClick={() => setOpen({ ...open, [key]: !isOpen })}
												aria-expanded={isOpen}
											>
												<span className="ars-head-key" title={tag.key}>
													{tag.label}
												</span>
												<span className="ars-head-val">
													{tag.value ? (
														tag.block ? (
															sprintf(__('%s characters of JSON-LD', 'ai-rank-suite'), tag.value.length.toLocaleString())
														) : (
															tag.value
														)
													) : (
														<i style={{ color: 'var(--ars-ink-3)' }}>—</i>
													)}
												</span>
												{tag.limit > 0 && tag.value && (
													<span className="ars-head-len tabular-nums">
														{tag.length}/{tag.limit}
													</span>
												)}
												<Badge tone={meta.tone}>{meta.label}</Badge>
											</button>

											{isOpen && (
												<div className="ars-head-row-body">
													{tag.why && <p className="m-0 text-[12px]">{tag.why}</p>}
													{tag.note && (
														<p className="m-0 text-[12px]" style={{ color: 'var(--ars-ink-3)' }}>
															{tag.note}
														</p>
													)}
													{tag.limit > 0 && tag.value && (
														<LengthMeter
															value={tag.value}
															kind={tag.limit > 100 ? 'desc' : 'title'}
														/>
													)}
													{tag.block && tag.value && (
														<pre className="ars-head-pre">{tag.value.slice(0, 4000)}</pre>
													)}
													<div className="flex items-center gap-2 flex-wrap">
														<code className="ars-head-code">{tag.key}</code>
														<span className="t-caption">
															written by{' '}
															{tag.owner === 'airs'
																? 'AI Rank Suite'
																: tag.owner === 'wp'
																	? 'WordPress'
																	: tag.owner}
														</span>
														{onGoTo && jump(tag.key) && (
															<button
																type="button"
																className="ars-linkbtn"
																onClick={() => onGoTo(jump(tag.key))}
															>{__('Edit this →', 'ai-rank-suite')}</button>
														)}
													</div>
												</div>
											)}
										</div>
									);
								})}
							</div>
						</div>
					))}
				</>
			)}

			{view === 'source' && (
				<div className="grid gap-2">
					<div className="flex items-center gap-2">
						<Button variant="ghost" onClick={copy}>
							{copied ? '✓ ' + __('Copied', 'ai-rank-suite') : __('Copy source', 'ai-rank-suite')}
						</Button>
						<a
							href={data.url}
							target="_blank"
							rel="noreferrer"
							className="inline-flex items-center gap-1 text-[12px]"
						>{__('Open the page', 'ai-rank-suite')}<IconExternal size={11} />
						</a>
						<span className="ml-auto t-caption">{data.source.split('\n').length} lines</span>
					</div>
					<pre className="ars-head-pre is-tall">{data.source || '(nothing would be written)'}</pre>
					<p className="m-0 t-caption">
						{__('This is what AI Rank Suite writes. The finished head will also contain whatever your theme and other plugins add — use the live check to see the whole thing.', 'ai-rank-suite')}
					</p>
				</div>
			)}

			{view === 'live' && (
				<div className="grid gap-3">
					<div className="flex items-center gap-2 flex-wrap">
						<Button onClick={fetchLive} busy={liveBusy}>
							<IconShield size={13} />{__('Fetch the real head', 'ai-rank-suite')}</Button>
						<span className="t-caption">
							Requests {data.url} and reads what came back — the only way to catch a second plugin writing the same
							tag.
						</span>
					</div>

					{live && !live.ok && <Notice tone="warning">{live.reason}</Notice>}

					{live && live.ok && (
						<>
							<div className="ars-head-strip">
								<div className="ars-head-stat">
									<b>{live.tags.length}</b>
									<span>tags on the page</span>
								</div>
								<div className={`ars-head-stat${live.duplicates.length ? ' is-bad' : ''}`}>
									<b>{live.duplicates.length}</b>
									<span>duplicated</span>
								</div>
								<div className={`ars-head-stat${live.drift.length ? ' is-warn' : ''}`}>
									<b>{live.drift.length}</b>
									<span>differ from plan</span>
								</div>
								<div className="ars-head-stat">
									<b>{live.jsonld}</b>
									<span>{__('JSON-LD blocks', 'ai-rank-suite')}</span>
								</div>
							</div>

							{live.duplicates.length > 0 && (
								<div className="grid gap-1.5">
									<div className="t-overline">{__('Written more than once', 'ai-rank-suite')}</div>
									{live.duplicates.map((d) => (
										<div key={d.key} className="ars-head-issue is-error">
											<span aria-hidden className="ars-head-issue-mark">
												✕
											</span>
											<div>
												<div className="font-semibold text-[12.5px]">
													{d.key} appears {d.count} times
												</div>
												<div className="text-[12px] mt-0.5" style={{ color: 'var(--ars-ink-2)' }}>
													{__('Two sources are writing this tag. Crawlers pick one, and which one is not something you control — usually the theme or a second SEO plugin. Switch the duplicate off at its source.', 'ai-rank-suite')}
												</div>
											</div>
										</div>
									))}
								</div>
							)}

							{live.drift.length > 0 && (
								<div className="grid gap-1.5">
									<div className="t-overline">{__('Different from what we write', 'ai-rank-suite')}</div>
									{live.drift.map((d, i) => (
										<div key={i} className="ars-head-drift">
											<div className="font-semibold text-[12px]">{d.label}</div>
											<div className="ars-head-drift-row">
												<span className="t-caption">planned</span>
												<code>{d.planned}</code>
											</div>
											<div className="ars-head-drift-row">
												<span className="t-caption">live</span>
												<code>{d.live || <i>absent</i>}</code>
											</div>
										</div>
									))}
									<p className="m-0 t-caption">
										{__('A difference here is almost always a page cache serving an older head. If it survives a cache purge, something else is overwriting the tag.', 'ai-rank-suite')}
									</p>
								</div>
							)}

							{live.duplicates.length === 0 && live.drift.length === 0 && (
								<Notice tone="good">{__('The head on the page matches what this plugin writes, and nothing is duplicated.', 'ai-rank-suite')}</Notice>
							)}
						</>
					)}
				</div>
			)}
		</div>
	);
}

/** Which tab edits a given tag, for the "Edit this" shortcut. */
function jump(key) {
	if (key === 'title' || key === 'name:description') return 'optimize';
	if (key.startsWith('property:og') || key.startsWith('name:twitter')) return 'preview';
	if (key === 'name:robots' || key.startsWith('rel:canonical')) return 'advanced';
	if (key === 'application/ld+json') return 'schema';
	return null;
}
