import React, { useMemo, useState } from 'react';
import { __, sprintf, _n } from '@wordpress/i18n';
import { useSettings } from '../useSettings';
import { api } from '../api';
import { Card, Button, Badge, Notice, Switch, ChipBar, PageState } from '../components/ui';
import LetAiDo from '../components/LetAiDo';
import KnowledgeBase from '../components/KnowledgeBase';
import AiBudget from '../components/AiBudget';

const REGION_ORDER = ['us', 'eu', 'cn', 'any', 'local'];
const REGION_SHORT = { us: 'US', eu: 'EU', cn: 'CN', any: 'Gateway', local: 'Local' };
const REGION_TONE = { us: 'blue', eu: 'green', cn: 'red', any: 'violet', local: 'yellow' };

export default function Ai() {
	const { data, setData, s, update, save: put, run, busy, saved, error } = useSettings('/settings/ai');
	const [apiKey, setApiKey] = useState('');
	const [verify, setVerify] = useState(null);
	const [region, setRegion] = useState('all');
	const [q, setQ] = useState('');
	// Set by the AI setup wizard when it sends somebody here for a key. Without
	// it, "add a key, then come back here" leaves them with no way back.
	const [fromWizard, setFromWizard] = useState(() => {
		try {
			return window.sessionStorage.getItem('airanksuite-ai-wizard-return') === '1';
		} catch {
			return false;
		}
	});

	const providers = data?.providers || [];
	const keyHints = data?.key_hints || {};
	const regions = data?.regions || {};
	const provider = useMemo(
		() => providers.find((p) => p.id === s?.provider) || providers[0] || {},
		[providers, s?.provider]
	);

	const groups = useMemo(() => {
		const term = q.trim().toLowerCase();
		const match = (p) =>
			(region === 'all' || p.region === region) &&
			(!term ||
				p.label.toLowerCase().includes(term) ||
				p.company.toLowerCase().includes(term) ||
				(p.models || []).some((m) => m.toLowerCase().includes(term)));
		return REGION_ORDER.map((r) => ({
			id: r,
			label: regions[r] || r,
			items: providers.filter((p) => p.region === r && match(p)),
		})).filter((g) => g.items.length > 0);
	}, [providers, regions, region, q]);

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

	// The key is write-only: sent when the field has content and cleared from
	// the form afterwards, so it never lingers in a rendered input.
	const save = async () => {
		setVerify(null);
		try {
			const payload = { ...s };
			if (apiKey.trim()) payload.api_key = apiKey.trim();
			await put(payload);
			setApiKey('');
		} catch {
			// put() already recorded the message in `error`.
		}
	};

	const testKey = () => {
		setVerify(null);
		return run(async () => {
			try {
				await api.post('/ai/verify');
				setVerify('ok');
			} catch (e) {
				setVerify('fail');
				throw e;
			}
		});
	};

	// Switching provider clears a model that the new provider cannot serve, and
	// pre-fills the base URL for the ones that need their own endpoint.
	const pick = (p) => {
		const next = { provider: p.id };
		if (!(p.models || []).includes(s.model)) next.model = '';
		next.base_url = p.needsUrl ? s.base_url || p.base : '';
		update(next);
	};

	const count = providers.length;

	const backToWizard = () => {
		try {
			window.sessionStorage.removeItem('airanksuite-ai-wizard-return');
		} catch {
			/* nothing to clear */
		}
		setFromWizard(false);
		window.location.hash = '/ai-wizard';
	};

	return (
		<div className="ars-page">
			{/* Notice renders its children inside a <p>, so the way back is an
			    inline button rather than a row beside the text. */}
			{fromWizard && (
				<Notice tone={data?.has_key ? 'good' : 'info'}>
					{data?.has_key
						? __('A key is stored. You can pick up the AI setup where you left it.', 'ai-rank-suite')
						: __('Add a key below, then return to the AI setup.', 'ai-rank-suite')}{' '}
					<button type="button" className="ars-linkbtn" onClick={backToWizard}>
						{__('Back to AI setup', 'ai-rank-suite')}
					</button>
				</Notice>
			)}

			{/* What the AI can do, and what it is briefed with — before the
			    key field, because those two are what the key is for. */}
			<LetAiDo />
			<AiBudget />
			<KnowledgeBase />

			<Card
				title={__('AI engine', 'ai-rank-suite')}
				subtitle={sprintf(__('Bring your own key — %d providers across the US, Europe, China, gateways and your own servers', 'ai-rank-suite'), count)}
				action={data.has_key ? <Badge tone="good">✓ Key stored {data.key_hint}</Badge> : <Badge tone="neutral">{__('No key', 'ai-rank-suite')}</Badge>}
			>
				<div className="grid gap-4">
					<div>
						<div className="flex items-center justify-between gap-3 flex-wrap mb-2">
							<label className="block font-medium">{__('Provider', 'ai-rank-suite')}</label>
							<div className="flex items-center gap-2 flex-wrap">
								<ChipBar
									value={region}
									onChange={setRegion}
									options={[
										{ id: 'all', label: __('All', 'ai-rank-suite') },
										...REGION_ORDER.filter((r) => providers.some((p) => p.region === r)).map((r) => ({
											id: r,
											label: REGION_SHORT[r] || r,
										})),
									]}
								/>
								<input
									type="search"
									placeholder={__('Search provider or model…', 'ai-rank-suite')}
									value={q}
									onChange={(e) => setQ(e.target.value)}
									className="w-[190px]"
									style={{ height: 30, fontSize: 12.5 }}
								/>
							</div>
						</div>

						<div className="grid gap-3">
							{groups.map((g) => (
								<div key={g.id}>
									<div className="t-overline mb-1.5">{g.label}</div>
									<div className="ars-cardgrid" style={{ ["--min"]: "300px" }}>
										{g.items.map((p) => {
											const on = s.provider === p.id;
											return (
												<button
													key={p.id}
													type="button"
													onClick={() => pick(p)}
													className={`ars-pick${on ? ' is-active' : ''}`}
												>
													<span className="ars-pick-title">
														{p.label}
														<span
															className="ars-tag"
															style={{
																color: `var(--ars-c-${REGION_TONE[p.region] || 'blue'}-ink)`,
																background: `var(--ars-c-${REGION_TONE[p.region] || 'blue'})`,
															}}
														>
															{REGION_SHORT[p.region] || p.region}
														</span>
														{keyHints[p.id] && (
															<span
																className="ars-tag"
																style={{
																	color: 'var(--ars-c-green-ink)',
																	background: 'var(--ars-c-green)',
																}}
																title={`Key stored ${keyHints[p.id]}`}
															>{__('Key', 'ai-rank-suite')}</span>
														)}
														{on && <span style={{ marginLeft: 'auto', color: 'var(--ars-brand)' }}>✓</span>}
													</span>
													<span className="ars-pick-note">{p.note || p.company}</span>
												</button>
											);
										})}
									</div>
								</div>
							))}
							{groups.length === 0 && (
								<p className="m-0 text-[12.5px]" style={{ color: 'var(--ars-ink-3)' }}>{__('No provider matches that search.', 'ai-rank-suite')}</p>
							)}
						</div>
					</div>

					<div className="grid gap-4 sm:grid-cols-2">
						<div>
							<label className="block font-medium mb-1">API key for {provider.label}</label>
							<input
								type="password"
								placeholder={
									keyHints[provider.id]
										? sprintf(__('Stored (%s) — type to replace', 'ai-rank-suite'), keyHints[provider.id])
										: provider.keyHint
								}
								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)' }}>
								One key per engine — each is kept in its own slot, so switching provider never asks you to type it
								again. Encrypted on this site (libsodium), never returned by the API.
								{provider.keyUrl ? (
									<>
										{' '}
										<a href={provider.keyUrl} target="_blank" rel="noreferrer noopener">
											Get a {provider.label} key ↗
										</a>
									</>
								) : null}
							</p>
						</div>

						<div>
							<label className="block font-medium mb-1">{__('Model', 'ai-rank-suite')}</label>
							{(provider.models || []).length > 0 ? (
								<select value={s.model || ''} onChange={(e) => update({ model: e.target.value })}>
									<option value="">Default — {provider.default}</option>
									{provider.models.map((m) => (
										<option key={m} value={m}>
											{m}
										</option>
									))}
									{s.model && !provider.models.includes(s.model) && <option value={s.model}>{s.model}</option>}
								</select>
							) : (
								<input
									type="text"
									placeholder={provider.default || 'model name'}
									value={s.model || ''}
									onChange={(e) => update({ model: e.target.value })}
								/>
							)}
							<p className="m-0 mt-1.5 text-[12px]" style={{ color: 'var(--ars-ink-3)' }}>{__('Any model id the provider accepts also works — type it in.', 'ai-rank-suite')}</p>
						</div>
					</div>

					{provider.needsUrl && (
						<div className="grid gap-4 sm:grid-cols-2">
							<div>
								<label className="block font-medium mb-1">{__('Base URL', 'ai-rank-suite')}</label>
								<input
									type="text"
									placeholder={provider.base || 'https://your-endpoint/v1'}
									value={s.base_url || ''}
									onChange={(e) => update({ base_url: e.target.value })}
								/>
							</div>
							{s.provider === 'azure' && (
								<div>
									<label className="block font-medium mb-1">{__('API version', 'ai-rank-suite')}</label>
									<input
										type="text"
										placeholder="2024-10-21"
										value={s.api_version || ''}
										onChange={(e) => update({ api_version: e.target.value })}
									/>
								</div>
							)}
						</div>
					)}

					<Switch
						checked={!!s.auto_meta}
						onChange={(v) => update({ auto_meta: v })}
						label={__('Auto-generate a meta description when a post is first published (only if none exists)', 'ai-rank-suite')}
					/>

					<div className="flex items-center gap-2 flex-wrap">
						<Button onClick={save} busy={busy}>{__('Save', 'ai-rank-suite')}</Button>
						<Button variant="ghost" onClick={testKey} busy={busy} disabled={!data.has_key}>{__('Test connection', 'ai-rank-suite')}</Button>
						{saved && <Badge tone="good">✓ Saved</Badge>}
						{verify === 'ok' && <Badge tone="good">✓ Connection works</Badge>}
					</div>
					{error && <Notice tone="serious">{error}</Notice>}
				</div>
			</Card>

			<div className="grid gap-4 md:grid-cols-2">
				<Card title={__('What AI powers', 'ai-rank-suite')} subtitle={__('Available once a key is stored', 'ai-rank-suite')}>
					<ul className="m-0 pl-5 grid gap-1.5 text-[13px]" style={{ color: 'var(--ars-ink-2)' }}>
						<li>
							<strong style={{ color: 'var(--ars-ink)' }}>{__('Meta descriptions & summaries', 'ai-rank-suite')}</strong> {__('— per page, in the Content drawer and directly in the block editor sidebar.', 'ai-rank-suite')}
						</li>
						<li>
							<strong style={{ color: 'var(--ars-ink)' }}>{__('FAQ generation', 'ai-rank-suite')}</strong> {__('— grounded question/answer pairs that also feed FAQPage schema and the', 'ai-rank-suite')} <code className="ars-mono">[airanksuite_faq]</code> shortcode.
						</li>
						<li>
							<strong style={{ color: 'var(--ars-ink)' }}>{__('Bulk runs', 'ai-rank-suite')}</strong> {__('— thousands of pages in resumable slices, so a 50,000-product catalogue finishes without a timeout.', 'ai-rank-suite')}
						</li>
						<li>{__('Costs stay on your provider account; every call is one small request per page.', 'ai-rank-suite')}</li>
					</ul>
				</Card>

				<Card title={__('Choosing a provider', 'ai-rank-suite')} subtitle={__('What actually changes', 'ai-rank-suite')}>
					<ul className="m-0 pl-5 grid gap-1.5 text-[13px]" style={{ color: 'var(--ars-ink-2)' }}>
						<li>
							<strong style={{ color: 'var(--ars-ink)' }}>{__('Data residency', 'ai-rank-suite')}</strong> {__('— EU providers keep the request inside Europe; self-hosted keeps it inside your own network.', 'ai-rank-suite')}
						</li>
						<li>
							<strong style={{ color: 'var(--ars-ink)' }}>{__('Market reach', 'ai-rank-suite')}</strong> {__('— the Chinese engines answer the queries Google never sees. If you sell into APAC, test against them.', 'ai-rank-suite')}
						</li>
						<li>
							<strong style={{ color: 'var(--ars-ink)' }}>{__('Cost per 1,000 pages', 'ai-rank-suite')}</strong> {__('— a fast small model is usually the right call for descriptions; save the large ones for FAQs.', 'ai-rank-suite')}
						</li>
						<li>{__('Switching provider changes nothing you have already generated — your content stays.', 'ai-rank-suite')}</li>
					</ul>
				</Card>
			</div>
		</div>
	);
}
