import React, { useEffect, useState } from 'react';
import { __, _n, sprintf } from '@wordpress/i18n';
import { api } from '../api';
import { Card, Button, Badge, Notice, MetricGrid, LineChart, PageState } from '../components/ui';
import Explain from '../components/Explain';

export default function Bing() {
	const [conn, setConn] = useState(null);
	const [apiKey, setApiKey] = useState('');
	const [stats, setStats] = useState(null);
	const [keywords, setKeywords] = useState(null);
	const [quota, setQuota] = useState(null);
	const [verify, setVerify] = useState(null);
	const [busy, setBusy] = useState(false);
	const [note, setNote] = useState(null);
	const [error, setError] = useState(null);

	const [gsc, setGsc] = useState(null);
	useEffect(() => {
		api.get('/bing').then(setConn).catch((e) => setError(e.message));
		api.get('/gsc/status').then(setGsc).catch(() => setGsc(null));
	}, []);

	// Nothing else is worth requesting until a key exists — three guaranteed
	// 400s on page load look like the feature is broken.
	useEffect(() => {
		if (!conn?.has_key) return;
		api.get('/bing/stats').then(setStats).catch((e) => setError(e.message));
		api.get('/bing/keywords').then(setKeywords).catch(() => {});
		api.get('/bing/quota').then(setQuota).catch(() => {});
	}, [conn?.has_key]);

	if (!conn) return <PageState error={error} />;

	/*
	 * The Google side, next to the Bing side.
	 *
	 * Bing Webmaster Tools can import a site, its verification and its
	 * sitemaps from Google Search Console in one step, which is the whole
	 * setup done at once when the same person owns both. The plugin cannot
	 * trigger that import (Bing offers it only in its own dashboard), so this
	 * puts the property Google knows next to the site Bing expects, says
	 * whether they agree, and opens the import at the right place.
	 */
	const gscHost = (() => {
		const prop = String(gsc?.property || '');
		if (!prop) return '';
		if (prop.startsWith('sc-domain:')) return prop.slice(10);
		try { return new URL(prop).host; } catch (e) { return prop; }
	})();
	const bingHost = (() => { try { return new URL(conn.site).host; } catch (e) { return conn.site; } })();
	const sameSite = gscHost && bingHost && (gscHost === bingHost || gscHost === bingHost.replace(/^www\./, '') || bingHost === gscHost.replace(/^www\./, ''));

	const run = async (fn) => {
		setBusy(true);
		setError(null);
		setNote(null);
		try {
			await fn();
		} catch (e) {
			setError(e.message);
		} finally {
			setBusy(false);
		}
	};

	const saveKey = () =>
		run(async () => {
			setConn(await api.put('/bing', { api_key: apiKey.trim() }));
			setApiKey('');
			setVerify(null);
		});

	const testKey = () =>
		run(async () => {
			const r = await api.post('/bing/verify', {});
			setVerify(r);
			setQuota(await api.get('/bing/quota').catch(() => null));
		});

	const submitRecent = () =>
		run(async () => {
			const r = await api.post('/bing/submit-recent', { limit: 25 });
			setNote(sprintf(_n('%d URL submitted to Bing.', '%d URLs submitted to Bing.', r.submitted, 'ai-rank-suite'), r.submitted));
			setQuota(await api.get('/bing/quota').catch(() => null));
		});

	return (
		<div className="ars-page">
			{gsc && (
				<Card
					title={__('Take it over from Google', 'ai-rank-suite')}
					subtitle={gsc.connected
						? __('The same account owns both: Bing can import the site, its verification and its sitemaps from Search Console in one step.', 'ai-rank-suite')
						: __('Connect Google first; Bing can then import the site from Search Console in one step.', 'ai-rank-suite')}
					action={gsc.connected
						? <a className="ars-btn ars-btn-primary" href="https://www.bing.com/webmasters/import" target="_blank" rel="noreferrer noopener">{__('Import from Search Console at Bing ↗', 'ai-rank-suite')}</a>
						: <Button onClick={() => { window.location.hash = '/search-console'; }}>{__('Connect Google', 'ai-rank-suite')}</Button>}
				>
					{!gsc.connected && (
						<p className="m-0 text-[13px]" style={{ color: 'var(--ars-ink-3)' }}>{__('Once Google is connected, this card shows the Search Console property next to the site Bing expects and opens the import at Bing in one click.', 'ai-rank-suite')}</p>
					)}
					{gsc.connected && (
						<div className="grid gap-2 sm:grid-cols-2 text-[13px]">
							<div><div className="t-caption">{__('Google property', 'ai-rank-suite')}</div><code>{gsc.property}</code></div>
							<div><div className="t-caption">{__('Site Bing expects', 'ai-rank-suite')}</div><code>{conn.site}</code>{' '}{sameSite ? <Badge tone="good">{__('same site', 'ai-rank-suite')}</Badge> : <Badge tone="warning">{__('different host', 'ai-rank-suite')}</Badge>}</div>
							<p className="m-0 sm:col-span-2" style={{ color: 'var(--ars-ink-3)', fontSize: 12.5 }}>
								{__('Sign in at Bing with the same Google account, choose this property, and Bing copies the verification. Then create an API key under Settings → API access and paste it below; from that moment clicks, index coverage and URL submission run here.', 'ai-rank-suite')}
							</p>
						</div>
					)}
				</Card>
			)}
			<Card
				title={__('Bing Webmaster Tools', 'ai-rank-suite')}
				subtitle={__('The index Copilot retrieves from — and the one search plugin authors skip', 'ai-rank-suite')}
				action={
					conn.has_key ? (
						<Badge tone="good">✓ {__('Key stored', 'ai-rank-suite')} {conn.key_hint}</Badge>
					) : (
						<Badge tone="neutral">{__('Not connected', 'ai-rank-suite')}</Badge>
					)
				}
			>
				<div className="grid gap-4">
					<Explain title={__('Why bother with Bing at all', 'ai-rank-suite')} open={!conn.has_key}>
						<p>
							{__('Treating Bing as the small second search engine was defensible until Copilot shipped. Microsoft’s assistant retrieves through the Bing index, and so do several products that licence it. A page Bing has not crawled cannot be cited by anything built on Bing, whatever Google thinks of it.', 'ai-rank-suite')}
						</p>
						<p>
							{__('The API also gives you something Google does not: direct URL submission with a published daily quota. No waiting for a crawl — you push the URL and it enters the index.', 'ai-rank-suite')}
						</p>
					</Explain>

					<div className="grid gap-3 sm:grid-cols-2">
						<div>
							<label className="block font-medium mb-1">{__('API key', 'ai-rank-suite')}</label>
							<input
								type="password"
								placeholder={conn.has_key ? sprintf(__('Stored (%s) — type to replace', 'ai-rank-suite'), conn.key_hint) : __('From Bing Webmaster → Settings → API access', 'ai-rank-suite')}
								value={apiKey}
								onChange={(e) => setApiKey(e.target.value)}
								autoComplete="off"
							/>
							<p className="m-0 mt-1.5 text-[12px]" style={{ color: 'var(--ars-ink-3)' }}>
								{__('Encrypted on this site, never returned by the API.', 'ai-rank-suite')}{' '}
								<a href="https://www.bing.com/webmasters/settings" target="_blank" rel="noreferrer noopener">{__('Get a key ↗', 'ai-rank-suite')}</a>
							</p>
						</div>
						<div>
							<label className="block font-medium mb-1">{__('Registered site', 'ai-rank-suite')}</label>
							<input type="text" value={conn.site} readOnly />
							<p className="m-0 mt-1.5 text-[12px]" style={{ color: 'var(--ars-ink-3)' }}>{__('Bing matches on the exact spelling you registered, including http/https and www.', 'ai-rank-suite')}</p>
						</div>
					</div>

					<div className="flex items-center gap-2 flex-wrap">
						<Button onClick={saveKey} busy={busy}>{__('Save key', 'ai-rank-suite')}</Button>
						<Button variant="ghost" onClick={testKey} busy={busy} disabled={!conn.has_key}>{__('Test connection', 'ai-rank-suite')}</Button>
						{verify?.ok && verify.registered && <Badge tone="good">✓ {__('Connected and site registered', 'ai-rank-suite')}</Badge>}
						{verify?.ok && !verify.registered && (
							<Badge tone="warning">{__('Key works, but this site is not in the account', 'ai-rank-suite')}</Badge>
						)}
					</div>

					{verify?.ok && !verify.registered && (
						<Notice tone="warning">{__('The key is valid but', 'ai-rank-suite')} <code>{verify.site}</code> {__('is not one of the sites it can see', 'ai-rank-suite')}
							{verify.sites.length > 0 ? sprintf(__(': it has %s', 'ai-rank-suite'), verify.sites.join(', ')) : ''}. {__('Add and verify this exact URL in Bing Webmaster Tools — a trailing slash or a missing www counts as a different site.', 'ai-rank-suite')}
						</Notice>
					)}
					{note && <Notice tone="good">{note}</Notice>}
					{error && <Notice tone="serious">{error}</Notice>}
				</div>
			</Card>

			{conn.has_key && stats && (
				<Card
					title={__('Performance on Bing', 'ai-rank-suite')}
					subtitle={__('Clicks, impressions and index coverage', 'ai-rank-suite')}
					action={
						<Button variant="ghost" busy={busy} onClick={() => run(async () => setStats(await api.get('/bing/stats?refresh=1')))}>{__('Refresh', 'ai-rank-suite')}</Button>
					}
				>
					<div className="grid gap-4">
						{/* Four toned tiles became one bordered grid — same numbers,
						    explanation in the `?` hover, no colour: nothing here is
						    an alert. */}
						<MetricGrid
							columns={4}
							metrics={[
								{
									id: 'clicks',
									label: __('Clicks', 'ai-rank-suite'),
									hint: __('Times somebody chose your result on Bing and arrived on the site.', 'ai-rank-suite'),
									value: stats.clicks ?? '—',
								},
								{
									id: 'impressions',
									label: __('Impressions', 'ai-rank-suite'),
									hint: __('Times a page of yours appeared in Bing results.', 'ai-rank-suite'),
									value: stats.impressions ?? '—',
								},
								{
									id: 'ctr',
									label: __('CTR', 'ai-rank-suite'),
									hint: __('Clicks as a share of impressions.', 'ai-rank-suite'),
									value: stats.ctr ?? '—',
									unit: stats.ctr == null ? '' : '%',
								},
								{
									id: 'indexed',
									label: __('Pages indexed', 'ai-rank-suite'),
									hint: __('URLs Bing currently holds in its index — a page not here cannot be cited by anything built on Bing.', 'ai-rank-suite'),
									value: stats.indexed ?? '—',
								},
							]}
						/>
						{stats.rows.length > 1 ? (
							<LineChart
								data={stats.rows.map((r) => ({ label: r.date, value: r.clicks }))}
								height={140}
							/>
						) : (
							<p className="m-0 text-[12.5px]" style={{ color: 'var(--ars-ink-3)' }}>{__('Bing has not returned enough days yet to draw a trend.', 'ai-rank-suite')}</p>
						)}
					</div>
				</Card>
			)}

			{conn.has_key && (
				<Card
					title={__('Push URLs into the index', 'ai-rank-suite')}
					subtitle={
						quota
							? sprintf(__('%1$s submissions left today · %2$s this month', 'ai-rank-suite'), quota.daily, quota.monthly)
							: __('Direct submission — no waiting for a crawl', 'ai-rank-suite')
					}
					action={
						<Button onClick={submitRecent} busy={busy}>{__('Submit 25 newest pages', 'ai-rank-suite')}</Button>
					}
				>
					<p className="m-0 text-[12.5px]" style={{ color: 'var(--ars-ink-2)' }}>
						{__('Worth doing after a migration, a bulk edit, or whenever you publish something you want answered on today. Submissions spend a published daily allowance, so this pushes your most recently modified pages rather than the whole site.', 'ai-rank-suite')}
					</p>
				</Card>
			)}

			{conn.has_key && keywords && keywords.rows.length > 0 && (
				<Card title={__('Queries Bing already shows you for', 'ai-rank-suite')} subtitle={__('Ranked by impressions', 'ai-rank-suite')}>
					<div className="ars-table-wrap"><table className="ars-table">
						<thead>
							<tr>
								<th>{__('Query', 'ai-rank-suite')}</th>
								<th style={{ textAlign: 'right' }}>{__('Clicks', 'ai-rank-suite')}</th>
								<th style={{ textAlign: 'right' }}>{__('Impressions', 'ai-rank-suite')}</th>
								<th style={{ textAlign: 'right' }}>{__('Position', 'ai-rank-suite')}</th>
							</tr>
						</thead>
						<tbody>
							{keywords.rows.slice(0, 50).map((r) => (
								<tr key={r.query}>
									<td>{r.query}</td>
									<td style={{ textAlign: 'right' }}>{r.clicks}</td>
									<td style={{ textAlign: 'right' }}>{r.impressions}</td>
									<td style={{ textAlign: 'right' }}>{r.position ? r.position.toFixed(1) : '—'}</td>
								</tr>
							))}
						</tbody>
					</table></div>
				</Card>
			)}
		</div>
	);
}
