import React, { useEffect, useState } from 'react';
import { __, sprintf } from '@wordpress/i18n';
import { useSettings } from '../useSettings';
import { api } from '../api';
import { Card, Button, Badge, Notice, Switch, Segmented, Field, PageState } from './ui';

/**
 * GDPR / consent settings — the whole consent manager on one screen.
 *
 * Left: posture, layout, categories, texts. Right: a live mock of the banner
 * that re-renders from the same values, so nobody has to open the front end
 * in a private window to see what a wording change looks like.
 */
export default function ConsentPanel() {
	const { data, s, update, save, busy, saved, error } = useSettings('/settings/analytics');
	if (!data) return <PageState error={error} />;

	const region = s.consent_region || 'eu';

	return (
		<div className="grid gap-4">
			{error && <Notice tone="serious">{error}</Notice>}

			<Card
				title={__('GDPR / consent manager', 'ai-rank-suite')}
				subtitle={__('Categories, regional behaviour and Google Consent Mode v2 — one banner for EU opt-in and US opt-out', 'ai-rank-suite')}
				action={
					<div className="flex items-center gap-2">
						{saved && <Badge tone="good">✓ {__('Saved', 'ai-rank-suite')}</Badge>}
						<Switch
							checked={!!s.consent_enabled}
							onChange={(v) => update({ consent_enabled: v })}
							label={s.consent_enabled ? __('Banner on', 'ai-rank-suite') : __('Banner off', 'ai-rank-suite')}
						/>
					</div>
				}
			>
				<div className="grid gap-5 lg:grid-cols-[minmax(0,1.15fr)_minmax(0,1fr)] items-start">
					<div className="grid gap-4">
						<Field label={__('Legal posture', 'ai-rank-suite')} hint={__('EU: nothing non-essential runs until the visitor opts in. US: tracking runs, a persistent “Do not sell or share” link lets visitors opt out (CCPA/CPRA). Auto: an EU/UK/CH language or CDN country header selects EU, everything else US — a proxy, not geolocation.', 'ai-rank-suite')}>
							<Segmented
								value={region}
								onChange={(v) => update({ consent_region: v })}
								options={[
									{ id: 'eu', label: __('EU opt-in', 'ai-rank-suite') },
									{ id: 'us', label: __('US opt-out', 'ai-rank-suite') },
									{ id: 'auto', label: __('Auto by visitor', 'ai-rank-suite') },
								]}
							/>
						</Field>

						<div className="grid gap-3 sm:grid-cols-3">
							<Field label={__('Layout', 'ai-rank-suite')}>
								<Segmented value={s.consent_layout || 'card'} onChange={(v) => update({ consent_layout: v })} options={[{ id: 'card', label: __('Card', 'ai-rank-suite') }, { id: 'bar', label: __('Bar', 'ai-rank-suite') }]} />
							</Field>
							<Field label={__('Position', 'ai-rank-suite')}>
								<Segmented value={s.consent_position || 'right'} onChange={(v) => update({ consent_position: v })} options={[{ id: 'left', label: __('Left', 'ai-rank-suite') }, { id: 'right', label: __('Right', 'ai-rank-suite') }]} />
							</Field>
							<Field label={__('Theme', 'ai-rank-suite')}>
								<Segmented value={s.consent_theme || 'auto'} onChange={(v) => update({ consent_theme: v })} options={[{ id: 'auto', label: __('Auto', 'ai-rank-suite') }, { id: 'light', label: __('Light', 'ai-rank-suite') }, { id: 'dark', label: __('Dark', 'ai-rank-suite') }]} />
							</Field>
						</div>

						<div className="grid gap-2.5 ars-r-md p-3.5" style={{ background: 'var(--ars-surface-2)' }}>
							<div className="font-semibold text-[13px]">{__('Categories & signals', 'ai-rank-suite')}</div>
							<Switch checked label={__('Necessary — always on', 'ai-rank-suite')} disabled onChange={() => {}} />
							<Switch checked label={__('Analytics — GA4, Matomo, Clarity', 'ai-rank-suite')} disabled onChange={() => {}} />
							<Switch
								checked={!!s.consent_marketing}
								onChange={(v) => update({ consent_marketing: v })}
								label={__('Marketing — show a category for ad and remarketing pixels you add via snippets', 'ai-rank-suite')}
							/>
							<Switch
								checked={!!s.consent_gcm}
								onChange={(v) => update({ consent_gcm: v })}
								label={__('Google Consent Mode v2 — default denied under opt-in, updated live on choice, so GA4 keeps modelled data', 'ai-rank-suite')}
							/>
							<Switch
								checked={!!s.consent_reopen}
								onChange={(v) => update({ consent_reopen: v })}
								label={__('Persistent reopen control (🍪 button in EU, “Do not sell or share” link in US)', 'ai-rank-suite')}
							/>
						</div>

						<div className="grid gap-3 sm:grid-cols-2">
							<Field label={__('Title', 'ai-rank-suite')}>
								<input type="text" value={s.consent_title || ''} onChange={(e) => update({ consent_title: e.target.value })} />
							</Field>
							<Field label={__('Privacy policy URL', 'ai-rank-suite')} hint={__('Empty = WordPress\' privacy page', 'ai-rank-suite')}>
								<input type="url" placeholder="https://…/privacy" value={s.consent_policy || ''} onChange={(e) => update({ consent_policy: e.target.value })} />
							</Field>
						</div>
						<Field label={__('Message', 'ai-rank-suite')}>
							<textarea rows={3} value={s.consent_message || ''} onChange={(e) => update({ consent_message: e.target.value })} />
						</Field>
						<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
							{[
								['consent_accept', __('Accept button', 'ai-rank-suite')],
								['consent_reject', __('Reject button', 'ai-rank-suite')],
								['consent_save', __('Save button', 'ai-rank-suite')],
								['consent_manage', __('Manage button', 'ai-rank-suite')],
								['consent_dns', __('US opt-out link', 'ai-rank-suite')],
							].map(([k, label]) => (
								<Field key={k} label={label}>
									<input type="text" value={s[k] || ''} onChange={(e) => update({ [k]: e.target.value })} />
								</Field>
							))}
							<Field label={__('Remember choice for (days)', 'ai-rank-suite')}>
								<input type="number" min={1} max={730} value={s.consent_expiry ?? 180} onChange={(e) => update({ consent_expiry: Number(e.target.value) })} />
							</Field>
						</div>

						<div>
							<Button onClick={save} busy={busy}>{__('Save', 'ai-rank-suite')}</Button>
						</div>
					</div>

					{/* Live preview — same strings, same tone. */}
					<div className="grid gap-2">
						<div className="t-caption">{__('Preview', 'ai-rank-suite')} · {region === 'us' ? __('US opt-out', 'ai-rank-suite') : region === 'auto' ? __('Auto (EU shown)', 'ai-rank-suite') : __('EU opt-in', 'ai-rank-suite')}</div>
						<div
							className="ars-r-lg p-6"
							style={{
								background: s.consent_theme === 'dark' ? '#131318' : 'var(--ars-canvas)',
								minHeight: 300,
								display: 'flex',
								alignItems: 'flex-end',
								justifyContent: s.consent_layout === 'bar' ? 'stretch' : s.consent_position === 'left' ? 'flex-start' : 'flex-end',
							}}
						>
							<div
								style={{
									background: s.consent_theme === 'dark' ? '#1c1c23' : '#fff',
									color: s.consent_theme === 'dark' ? '#e9e9ef' : '#16161e',
									border: `1px solid ${s.consent_theme === 'dark' ? '#34343f' : '#e4e5ea'}`,
									borderRadius: 16,
									padding: '18px 18px 14px',
									boxShadow: '0 12px 40px rgba(0,0,0,.22)',
									width: s.consent_layout === 'bar' ? '100%' : 340,
									maxWidth: '100%',
								}}
							>
								<div style={{ fontWeight: 700, fontSize: 15, marginBottom: 4 }}>{s.consent_title || __('We value your privacy', 'ai-rank-suite')}</div>
								<div style={{ fontSize: 12.5, opacity: 0.75, marginBottom: 12 }}>
									{s.consent_message || '…'}{' '}
									<span style={{ color: 'var(--ars-brand)', textDecoration: 'underline' }}>{__('Privacy policy', 'ai-rank-suite')}</span>
								</div>
								<div className="flex gap-2 flex-wrap">
									<span className="ars-btn ars-btn-primary" style={{ pointerEvents: 'none' }}>{s.consent_accept || __('Accept all', 'ai-rank-suite')}</span>
									<span className="ars-btn ars-btn-ghost" style={{ pointerEvents: 'none' }}>{s.consent_reject || __('Reject all', 'ai-rank-suite')}</span>
									<span className="ars-btn ars-btn-ghost" style={{ pointerEvents: 'none', borderColor: 'transparent', opacity: 0.7 }}>{s.consent_manage || __('Manage', 'ai-rank-suite')}</span>
								</div>
							</div>
						</div>
						{region === 'us' && (
							<div className="t-caption">
								{sprintf(__('US mode also prints a persistent “%s” link.', 'ai-rank-suite'), s.consent_dns || __('Do not sell or share my personal information', 'ai-rank-suite'))}
							</div>
						)}
					</div>
				</div>
			</Card>

			<ConsentRecord s={s} update={update} save={save} />
		</div>
	);
}

/**
 * Proof of consent.
 *
 * Article 7(1) puts the burden on the site to demonstrate that consent was
 * given. A cookie in the visitor's browser demonstrates nothing — the site
 * cannot produce it, and the visitor can clear it. This is the record the
 * site can actually show, and the control that invalidates it when the
 * policy text changes, because consent to one policy is not consent to a
 * different one.
 *
 * Nothing here identifies anybody: the address and user agent are stored as
 * salted hashes, enough to tell two decisions from one browser apart and
 * useless for anything else.
 */
function ConsentRecord({ s, update, save }) {
	const [log, setLog] = useState(null);
	const [busy, setBusy] = useState('');
	const [error, setError] = useState(null);

	const load = () => api.get('/consent/log').then(setLog).catch((e) => setError(e.message));
	useEffect(() => {
		load();
	}, []);

	const run = async (name, fn) => {
		setBusy(name);
		setError(null);
		try {
			await fn();
		} catch (e) {
			setError(e.message);
		} finally {
			setBusy('');
		}
	};

	const version = Number(s.consent_version || 1);

	return (
		<Card
			title={__('Proof of consent', 'ai-rank-suite')}
			subtitle={__('An anonymous technical event log: what the banner reported, when, under which policy version. The endpoint that records it is public by necessity — the banner runs before any login — so treat this as an operational record, not as legal proof of consent.', 'ai-rank-suite')}
			action={
				<Switch
					checked={s.consent_log !== false}
					onChange={(v) => {
						update({ consent_log: v });
						save({ consent_log: v });
					}}
					label={__('Keep a record', 'ai-rank-suite')}
				/>
			}
		>
			{error && <Notice tone="serious">{error}</Notice>}

			{s.consent_log === false ? (
				<p className="m-0 text-[13px]" style={{ color: 'var(--ars-ink-2)' }}>
					{__('No record is kept. The banner still works and still gates the tags — but if anyone asks the site to demonstrate that a visitor agreed, there will be nothing to show.', 'ai-rank-suite')}
				</p>
			) : !log ? (
				<span className="t-caption">{__('Reading the record…', 'ai-rank-suite')}</span>
			) : log.total === 0 ? (
				<p className="m-0 text-[13px]" style={{ color: 'var(--ars-ink-2)' }}>
					{__('Nothing recorded yet. The first visitor who answers the banner appears here — the record is written on their choice, not on their visit.', 'ai-rank-suite')}
				</p>
			) : (
				<div className="grid gap-4">
					<div className="grid gap-2 sm:grid-cols-4">
						{[
							{ label: __('Decisions', 'ai-rank-suite'), value: log.total, tone: 'var(--ars-ink)' },
							{ label: __('Accepted all', 'ai-rank-suite'), value: log.accepted, tone: 'var(--ars-good)' },
							{ label: __('Rejected all', 'ai-rank-suite'), value: log.rejected, tone: 'var(--ars-serious)' },
							{ label: __('Chose their own', 'ai-rank-suite'), value: log.custom, tone: 'var(--ars-brand)' },
						].map((t) => (
							<div key={t.label} className="ars-r-md px-3 py-2.5" style={{ background: 'var(--ars-surface-2)' }}>
								<div className="t-num text-[19px] font-bold" style={{ color: t.tone }}>
									{Number(t.value).toLocaleString()}
								</div>
								<div className="t-caption">{t.label}</div>
							</div>
						))}
					</div>

					<div className="flex items-center gap-2 flex-wrap">
						<Badge tone={log.rate >= 50 ? 'good' : 'neutral'}>{sprintf(__('%s%% accepted everything', 'ai-rank-suite'), log.rate)}</Badge>
						<Badge tone="neutral">{sprintf(__('%s allowed analytics', 'ai-rank-suite'), log.analytics.toLocaleString())}</Badge>
						{log.marketing > 0 && <Badge tone="neutral">{sprintf(__('%s allowed marketing', 'ai-rank-suite'), log.marketing.toLocaleString())}</Badge>}
						{log.first_at && <span className="t-caption">{sprintf(__('since %s', 'ai-rank-suite'), log.first_at.slice(0, 10))}</span>}
					</div>

					{log.stale > 0 && (
						<Notice tone="warning">
							{sprintf(__('%s of these were given under an older policy version. Those visitors are being asked again — their old answer no longer counts, which is the correct behaviour after the cookie policy changes.', 'ai-rank-suite'), log.stale.toLocaleString())}
						</Notice>
					)}
				</div>
			)}

			<div className="grid gap-3 mt-4 pt-4" style={{ borderTop: '1px solid var(--ars-line)' }}>
				<div className="flex items-center justify-between gap-3 flex-wrap">
					<div className="min-w-0">
						<div className="font-semibold text-[13px]">{sprintf(__('Policy version %d', 'ai-rank-suite'), version)}</div>
						<div className="t-caption">
							{__('Raise this after changing the cookie policy or adding a tag. Everyone who agreed to the old text is asked again; everyone else is left alone.', 'ai-rank-suite')}
						</div>
					</div>
					<Button
						variant="ghost"
						busy={busy === 'bump'}
						onClick={() =>
							run('bump', async () => {
								const next = version + 1;
								update({ consent_version: next });
								await save({ consent_version: next });
								await load();
							})
						}
					>{__('Ask everyone again', 'ai-rank-suite')}</Button>
				</div>

				<div className="flex items-center gap-2 flex-wrap">
					<Button
						variant="ghost"
						busy={busy === 'csv'}
						onClick={() =>
							run('csv', async () => {
								// Paged by id, 2,000 rows a call, until the server has no next
								// page: the record is complete however large it has grown.
								const parts = [];
								let after = 0;
								for (let guard = 0; guard < 2000; guard++) {
									const r = await api.get(`/consent/log/csv?after=${after}&per_page=2000`);
									parts.push(r.csv || '');
									if (r.next === null || r.next === undefined) break;
									after = r.next;
								}
								// A data: URL would be blocked in some admin setups; a Blob
								// is the reliable way to hand a file to the browser.
								const url = URL.createObjectURL(new Blob(parts, { type: 'text/csv' }));
								const a = document.createElement('a');
								a.href = url;
								a.download = 'consent-record.csv';
								a.click();
								URL.revokeObjectURL(url);
							})
						}
					>{__('Export the record (CSV)', 'ai-rank-suite')}</Button>
					<Button
						variant="ghost"
						busy={busy === 'clear'}
						onClick={() => {
							if (!window.confirm(__('Delete every recorded decision? The log cannot be rebuilt.', 'ai-rank-suite'))) return;
							run('clear', async () => setLog(await api.del('/consent/log')));
						}}
					>{__('Delete the record', 'ai-rank-suite')}</Button>
					<span className="t-caption">
						{sprintf(__('Kept for %s days, then deleted automatically.', 'ai-rank-suite'), Number(s.consent_log_days || 365).toLocaleString())}
					</span>
				</div>
			</div>
		</Card>
	);
}
