import React, { useEffect, useState } from 'react';
import { __, _n, sprintf } from '@wordpress/i18n';
import { useSettings } from '../useSettings';
import { api } from '../api';
import { Card, Button, Switch, Badge, Notice, Tabs, Field, MediaPicker, TagInput, CheckGrid, CodeBlock, Gauge, PageState } from '../components/ui';
import Explain from '../components/Explain';
import LocalListings from '../components/LocalListings';
import { IconX, IconPin, IconMap, IconLayers, IconCode, IconSliders, IconLink, IconFile, IconChart, IconExternal } from '../components/icons';

const DAY_LABELS = {
	monday: __('Monday', 'ai-rank-suite'),
	tuesday: __('Tuesday', 'ai-rank-suite'),
	wednesday: __('Wednesday', 'ai-rank-suite'),
	thursday: __('Thursday', 'ai-rank-suite'),
	friday: __('Friday', 'ai-rank-suite'),
	saturday: __('Saturday', 'ai-rank-suite'),
	sunday: __('Sunday', 'ai-rank-suite'),
};

const LANGUAGE_SUGGESTIONS = ['English', 'Deutsch', 'العربية', 'Français', 'Español', 'Italiano', 'Nederlands', 'Türkçe', 'Русский', '中文'];

const TABS = [
	{ id: 'profile', label: __('Profile', 'ai-rank-suite') },
	{ id: 'hours', label: __('Hours', 'ai-rank-suite') },
	{ id: 'locations', label: __('Locations', 'ai-rank-suite') },
	{ id: 'reach', label: __('Reach & services', 'ai-rank-suite') },
	{ id: 'listings', label: __('Listings', 'ai-rank-suite') },
	{ id: 'output', label: __('Output', 'ai-rank-suite') },
];

const TIER_LABEL = { required: __('Required', 'ai-rank-suite'), recommended: __('Recommended', 'ai-rank-suite'), optional: __('Nice to have', 'ai-rank-suite') };
const TIER_TONE = { required: 'red', recommended: 'yellow', optional: 'blue' };

/** A branch inherits every empty field from head office, so nothing is mandatory here. */
const BLANK_LOCATION = {
	name: '',
	business_type: '',
	street: '',
	street2: '',
	postal_code: '',
	city: '',
	region: '',
	country: '',
	phone: '',
	email: '',
	latitude: '',
	longitude: '',
	map_url: '',
	booking_url: '',
	price_range: '',
	image_url: '',
	own_hours: false,
	hours: {},
};

export default function LocalSeo() {
	const { data, s, update, save, run, busy, saved, error, setError, reload } = useSettings('/settings/local-seo');
	// #/local-seo/listings opens that tab directly — the toolbar jump list and
	// the Insights sources strip link here by tab.
	const [tab, setTab] = useState(() => {
		const m = /#\/local-seo\/([a-z-]+)/.exec(window.location.hash || '');
		return m && TABS.some((t) => t.id === m[1]) ? m[1] : 'profile';
	});
	const [preview, setPreview] = useState(null);
	const [geo, setGeo] = useState(null);
	const [openIndex, setOpenIndex] = useState(0);

	// The preview is the answer to "did my change land", so it reloads whenever
	// the page saves rather than only when the tab is first opened.
	useEffect(() => {
		if (tab !== 'output' || !data) return;
		api.get('/local-seo/preview').then(setPreview).catch(() => setPreview(null));
	}, [tab, data]);

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

	const setHours = (day, patch) => update({ hours: { ...s.hours, [day]: { ...s.hours[day], ...patch } } });

	const setLocation = (index, patch) =>
		update({ locations: s.locations.map((l, i) => (i === index ? { ...l, ...patch } : l)) });

	const setList = (key, index, patch) =>
		update({ [key]: (s[key] || []).map((row, i) => (i === index ? { ...row, ...patch } : row)) });

	const addTo = (key, blank) => update({ [key]: [...(s[key] || []), blank] });
	const removeFrom = (key, index) => update({ [key]: (s[key] || []).filter((_, i) => i !== index) });

	const findCoordinates = () =>
		run(async () => {
			setGeo(null);
			const found = await api.post('/local-seo/geocode');
			update({ latitude: found.latitude, longitude: found.longitude });
			setGeo(found.matched || `${found.latitude}, ${found.longitude}`);
		});

	const today = new Date().toISOString().slice(0, 10);
	const completeness = data.completeness || { score: 0, checks: [], required: 0 };
	const missing = completeness.checks.filter((c) => !c.ok);
	const openNow = data.open_now || {};

	return (
		<div className="ars-page">
			{error && <Notice tone="serious">{error}</Notice>}

			<Card
				icon={<IconPin size={16} />} title={__('Local business', 'ai-rank-suite')}
				subtitle={__('One record, published as LocalBusiness schema and reused by every “near me” answer Google, ChatGPT and Perplexity give about you', 'ai-rank-suite')}
				action={
					<div className="flex items-center gap-2">
						{saved && <Badge tone="good">✓ {__('Saved', 'ai-rank-suite')}</Badge>}
						<Switch checked={!!s.enabled} onChange={(v) => update({ enabled: v })} label={__('Publish', 'ai-rank-suite')} />
					</div>
				}
			>
				<div className="ars-local-head">
					<div className="shrink-0">
						<Gauge value={completeness.score} label={__('Profile completeness', 'ai-rank-suite')} />
					</div>

					<div className="grid gap-3 min-w-0">
						<div className="flex items-center gap-2 flex-wrap">
							{s.enabled ? (
								<Badge tone={openNow.open ? 'good' : 'neutral'}>
									{openNow.label}
									{openNow.until ? ` · ${openNow.until}` : ''}
								</Badge>
							) : (
								<Badge tone="warning">{__('Not published — nothing is emitted yet', 'ai-rank-suite')}</Badge>
							)}
							<span className="t-caption">Site timezone: {data.timezone || 'UTC'}</span>
						</div>

						{/*
						 * What is left, as a task rather than a verdict.
						 *
						 * This was a column of red REQUIRED badges — every gap
						 * listed at equal weight, which reads as a punishment
						 * list and gives no idea how much work is actually left
						 * or where to do it. A bar, a count, and one button that
						 * opens the tab holding the next gap.
						 */}
						{missing.length === 0 ? (
							<p className="m-0 text-[13px]" style={{ color: 'var(--ars-ink-2)' }}>{__('Nothing left to fill in. The Output tab shows exactly what search engines and assistants will read.', 'ai-rank-suite')}</p>
						) : (
							(() => {
								// Which tab each check belongs to, so the button can
								// send someone to the field rather than to the page.
								const TAB_OF = {
									hours: 'hours',
									areas: 'reach',
									services: 'reach',
									payment: 'reach',
									locations: 'locations',
								};
								const tabFor = (c) => TAB_OF[c.id] || 'profile';

								/*
								 * Go to the field, not just to its tab.
								 *
								 * This only called setTab, and the field it is
								 * about is usually on the profile tab, which is
								 * the tab already open — so "Fill in street and
								 * number" set the tab to the one you were on,
								 * scrolled nowhere, and did nothing at all that
								 * anybody could see. Reported, fairly, as a dead
								 * button.
								 *
								 * The tab still has to change first for the
								 * cases where the field is elsewhere, and the
								 * scroll waits a frame so the new tab has
								 * rendered before we look for the input.
								 */
								const goToField = (c) => {
									setTab(tabFor(c));
									window.requestAnimationFrame(() => {
										const el = document.querySelector(`[data-airanksuite-field="${c.id}"]`);
										if (!el) return;
										el.scrollIntoView({ behavior: 'smooth', block: 'center' });
										// Focus after the scroll, or the browser jumps twice.
										window.setTimeout(() => el.focus({ preventScroll: true }), 350);
									});
								};
								const req = missing.filter((c) => c.tier === 'required');
								const rec = missing.filter((c) => c.tier === 'recommended');
								const first = req[0] || rec[0] || missing[0];
								const doneReq = (completeness.checks || []).filter((c) => c.tier === 'required' && c.ok).length;
								const totalReq = (completeness.checks || []).filter((c) => c.tier === 'required').length;

								return (
									<div className="grid gap-2.5">
										<div className="flex items-center justify-between gap-3 flex-wrap">
											<span className="text-[13.5px] font-semibold">
												{req.length > 0
													? sprintf(_n('%1$d of %2$d required field filled in', '%1$d of %2$d required fields filled in', totalReq, 'ai-rank-suite'), doneReq, totalReq)
													: __('Every required field is filled in', 'ai-rank-suite')}
											</span>
											<span className="t-caption">
												{req.length > 0 && sprintf(__('%d required', 'ai-rank-suite'), req.length)}
												{req.length > 0 && rec.length > 0 && ' · '}
												{rec.length > 0 && sprintf(__('%d recommended', 'ai-rank-suite'), rec.length)}
											</span>
										</div>

										<div className="ars-local-bar" role="img" aria-label={sprintf(_n('%1$d of %2$d required field', '%1$d of %2$d required fields', totalReq, 'ai-rank-suite'), doneReq, totalReq)}>
											{(completeness.checks || [])
												.filter((c) => c.tier === 'required')
												.map((c) => (
													<span
														key={c.id}
														className={`ars-local-seg${c.ok ? ' is-ok' : ''}`}
														title={c.ok ? c.label : sprintf(__('%s — still empty', 'ai-rank-suite'), c.label)}
													/>
												))}
										</div>

										<div className="flex items-center gap-2 flex-wrap">
											<Button onClick={() => goToField(first)}>
												{/*
													  * The label as written, not lowercased.
													  * "Fill in company name" reads well in
													  * English and is the reason for the
													  * toLowerCase(). German capitalises every
													  * noun, so the same call produced the button
													  * "firmenname ausfüllen" — a spelling mistake
													  * the product made about its own field.
													  */}
												{sprintf(__('Fill in %s', 'ai-rank-suite'), first.label)}
											</Button>
											<span className="t-caption">
												{sprintf(__('Next: %s', 'ai-rank-suite'), first.label)}
												{first.hint ? ` — ${first.hint}` : ''}
											</span>
										</div>
									</div>
								);
							})()
						)}
					</div>
				</div>
			</Card>

			<Tabs tabs={TABS} active={tab} onChange={setTab} />

			{tab === 'profile' && (
				<>
					<Card icon={<IconFile size={16} />} title={__('Identity', 'ai-rank-suite')} subtitle={__('Who the business is, in the words an assistant will repeat', 'ai-rank-suite')}>
						<div className="grid gap-3 sm:grid-cols-2">
							<Field label={__('Business name', 'ai-rank-suite')} hint={__('The name on the shopfront, not the legal entity.', 'ai-rank-suite')}>
								<input type="text" data-airanksuite-field="name" value={s.name || ''} onChange={(e) => update({ name: e.target.value })} />
							</Field>
							<Field label={__('Business type', 'ai-rank-suite')} hint={__('A precise subtype earns a richer result than the generic LocalBusiness.', 'ai-rank-suite')}>
								<select value={s.business_type} onChange={(e) => update({ business_type: e.target.value })}>
									{Object.entries(data.type_groups || {}).map(([group, types]) => (
										<optgroup key={group} label={group}>
											{types.map((t) => (
												<option key={t} value={t}>
													{t}
												</option>
											))}
										</optgroup>
									))}
								</select>
							</Field>
							<Field label={__('Legal name (optional)', 'ai-rank-suite')}>
								<input type="text" value={s.legal_name || ''} onChange={(e) => update({ legal_name: e.target.value })} />
							</Field>
							<Field label={__('Slogan (optional)', 'ai-rank-suite')}>
								<input type="text" value={s.slogan || ''} onChange={(e) => update({ slogan: e.target.value })} />
							</Field>
							<Field
								span
								label={__('Description', 'ai-rank-suite')}
								hint={__('Two or three sentences. This is the passage a chat assistant quotes when someone asks what you do.', 'ai-rank-suite')}
							>
								<textarea
									rows={3}
									value={s.description || ''}
									onChange={(e) => update({ description: e.target.value })}
								/>
							</Field>
							<Field label={__('Founded', 'ai-rank-suite')} hint={__('Year or full date, e.g. 2011 or 2011-04-01.', 'ai-rank-suite')}>
								<input
									type="text"
									value={s.founding_date || ''}
									onChange={(e) => update({ founding_date: e.target.value })}
								/>
							</Field>
						</div>
					</Card>

					<Card icon={<IconMap size={16} />} title={__('Contact', 'ai-rank-suite')} subtitle={__('Used for click-to-call and for the contact block in an AI answer', 'ai-rank-suite')}>
						<div className="grid gap-3 sm:grid-cols-2">
							<Field label={__('Phone', 'ai-rank-suite')} hint={__('International format (+49 …) so a call works from anywhere.', 'ai-rank-suite')}>
								<input type="text" data-airanksuite-field="phone" value={s.phone || ''} onChange={(e) => update({ phone: e.target.value })} />
							</Field>
							<Field label={__('Second phone (optional)', 'ai-rank-suite')}>
								<input
									type="text"
									value={s.phone_secondary || ''}
									onChange={(e) => update({ phone_secondary: e.target.value })}
								/>
							</Field>
							<Field label={__('WhatsApp (optional)', 'ai-rank-suite')}>
								<input type="text" value={s.whatsapp || ''} onChange={(e) => update({ whatsapp: e.target.value })} />
							</Field>
							<Field label={__('Fax (optional)', 'ai-rank-suite')}>
								<input type="text" value={s.fax || ''} onChange={(e) => update({ fax: e.target.value })} />
							</Field>
							<Field label={__('Email', 'ai-rank-suite')}>
								<input type="email" data-airanksuite-field="email" value={s.email || ''} onChange={(e) => update({ email: e.target.value })} />
							</Field>
						</div>
					</Card>

					<Card
						icon={<IconPin size={16} />} title={__('Address', 'ai-rank-suite')}
						subtitle={__('The NAP — name, address, phone — that must match your Google Business Profile character for character', 'ai-rank-suite')}
					>
						<div className="grid gap-3 sm:grid-cols-2">
							<Field label={__('Street and number', 'ai-rank-suite')}>
								<input type="text" data-airanksuite-field="street" value={s.street || ''} onChange={(e) => update({ street: e.target.value })} />
							</Field>
							<Field label={__('Suite / floor (optional)', 'ai-rank-suite')}>
								<input type="text" data-airanksuite-field="street2" value={s.street2 || ''} onChange={(e) => update({ street2: e.target.value })} />
							</Field>
							<Field label={__('Postal code', 'ai-rank-suite')}>
								<input
									type="text"
									value={s.postal_code || ''}
									onChange={(e) => update({ postal_code: e.target.value })}
								/>
							</Field>
							<Field label={__('City', 'ai-rank-suite')}>
								<input type="text" data-airanksuite-field="city" value={s.city || ''} onChange={(e) => update({ city: e.target.value })} />
							</Field>
							<Field label={__('Region / state', 'ai-rank-suite')}>
								<input type="text" data-airanksuite-field="region" value={s.region || ''} onChange={(e) => update({ region: e.target.value })} />
							</Field>
							<Field label={__('Country code', 'ai-rank-suite')} hint={__('Two letters — DE, AE, US.', 'ai-rank-suite')}>
								<input
									type="text"
									maxLength={2}
									value={s.country || ''}
									onChange={(e) => update({ country: e.target.value.toUpperCase() })}
								/>
							</Field>
							<Field label={__('Latitude', 'ai-rank-suite')}>
								<input type="text" value={s.latitude || ''} onChange={(e) => update({ latitude: e.target.value })} />
							</Field>
							<Field label={__('Longitude', 'ai-rank-suite')}>
								<input type="text" value={s.longitude || ''} onChange={(e) => update({ longitude: e.target.value })} />
							</Field>
							<Field span>
								<div className="flex items-center gap-2 flex-wrap">
									<Button variant="ghost" onClick={findCoordinates} busy={busy}>{__('Find coordinates from the address', 'ai-rank-suite')}</Button>
									{geo && <span className="t-caption">Matched: {geo}</span>}
								</div>
							</Field>
						</div>
						<Explain title={__('Why coordinates matter for “near me”', 'ai-rank-suite')}>
							<p>
								{__('A street name is ambiguous — dozens of German towns have a Bahnhofstraße 1. Coordinates remove the guess, which is what decides whether you appear in a map pack for the right town. The lookup uses OpenStreetMap and needs no account; you can also paste the pair from Google Maps by right-clicking your pin.', 'ai-rank-suite')}
							</p>
						</Explain>
					</Card>

					<Card icon={<IconLayers size={16} />} title={__('Images', 'ai-rank-suite')} subtitle={__('Google puts a picture next to a local result — without one, your listing is plain text', 'ai-rank-suite')}>
						<div className="grid gap-4 sm:grid-cols-2">
							<MediaPicker
								label={__('Logo', 'ai-rank-suite')}
								title={__('Select a logo', 'ai-rank-suite')}
								value={s.logo_url}
								onChange={(v) => update({ logo_url: v })}
								hint={__('Square, at least 112×112, on a plain background.', 'ai-rank-suite')}
							/>
							<MediaPicker
								label={__('Photo of the business', 'ai-rank-suite')}
								title={__('Select a photo', 'ai-rank-suite')}
								value={s.image_url}
								onChange={(v) => update({ image_url: v })}
								hint={__('The storefront, the practice, the workshop. At least 1200px wide.', 'ai-rank-suite')}
							/>
						</div>
					</Card>

					<Card icon={<IconChart size={16} />} title={__('Commercial details', 'ai-rank-suite')} subtitle={__('Answers to the questions people ask before they walk in', 'ai-rank-suite')}>
						<div className="grid gap-3 sm:grid-cols-2">
							<Field label={__('Price range', 'ai-rank-suite')} hint={__('Either a symbol scale (€€) or a span (30–90 €).', 'ai-rank-suite')}>
								<input
									type="text"
									value={s.price_range || ''}
									onChange={(e) => update({ price_range: e.target.value })}
								/>
							</Field>
							<Field label={__('Currency', 'ai-rank-suite')} hint={__('ISO code, e.g. EUR, AED, USD.', 'ai-rank-suite')}>
								<input type="text" value={s.currencies || ''} onChange={(e) => update({ currencies: e.target.value })} />
							</Field>
							<Field span label={__('Payment accepted', 'ai-rank-suite')}>
								<CheckGrid
									options={Object.entries(data.payment_methods || {}).map(([key, label]) => ({ key, label }))}
									value={s.payments || []}
									onChange={(v) => update({ payments: v })}
								/>
							</Field>
							<Field label={__('VAT ID', 'ai-rank-suite')}>
								<input type="text" value={s.vat_id || ''} onChange={(e) => update({ vat_id: e.target.value })} />
							</Field>
							<Field label={__('Tax ID', 'ai-rank-suite')}>
								<input type="text" value={s.tax_id || ''} onChange={(e) => update({ tax_id: e.target.value })} />
							</Field>
							<Field label={__('Company registration number', 'ai-rank-suite')}>
								<input
									type="text"
									value={s.registration_id || ''}
									onChange={(e) => update({ registration_id: e.target.value })}
								/>
							</Field>
						</div>
					</Card>
				</>
			)}

			{tab === 'hours' && (
				<>
					<Card
						icon={<IconSliders size={16} />} title={__('Opening hours', 'ai-rank-suite')}
						subtitle={__('Published as openingHoursSpecification and read out verbatim when someone asks whether you are open', 'ai-rank-suite')}
						action={
							<Switch
								checked={!!s.show_open_now}
								onChange={(v) => update({ show_open_now: v })}
								label={__('Live open/closed badge', 'ai-rank-suite')}
							/>
						}
					>
						<div className="grid gap-2">
							{data.days.map((day) => {
								const slot = s.hours[day] || {};
								const hasBreak = !!(slot.break_start || slot.break_end);
								return (
									<div key={day} className="flex items-center gap-3 flex-wrap" style={{ minHeight: 40 }}>
										<span className="font-medium" style={{ minWidth: 100 }}>
											{DAY_LABELS[day]}
										</span>
										<Switch
											checked={!slot.closed}
											onChange={(v) => setHours(day, { closed: !v })}
											label={slot.closed ? 'Closed' : 'Open'}
										/>
										{slot.closed ? (
											<span className="t-caption">{__('No hours published for this day', 'ai-rank-suite')}</span>
										) : (
											<>
												<input
													type="time"
													value={slot.open || ''}
													onChange={(e) => setHours(day, { open: e.target.value })}
													style={{ width: 116 }}
												/>
												<span style={{ color: 'var(--ars-ink-3)' }}>–</span>
												<input
													type="time"
													value={slot.close || ''}
													onChange={(e) => setHours(day, { close: e.target.value })}
													style={{ width: 116 }}
												/>
												{hasBreak ? (
													<>
														<span className="t-caption" style={{ marginLeft: 8 }}>
															{__('closed', 'ai-rank-suite')}
														</span>
														<input
															type="time"
															value={slot.break_start || ''}
															onChange={(e) => setHours(day, { break_start: e.target.value })}
															style={{ width: 116 }}
														/>
														<span style={{ color: 'var(--ars-ink-3)' }}>–</span>
														<input
															type="time"
															value={slot.break_end || ''}
															onChange={(e) => setHours(day, { break_end: e.target.value })}
															style={{ width: 116 }}
														/>
														<button
															type="button"
															aria-label={__('Remove break', 'ai-rank-suite')}
															className="border-0 bg-transparent cursor-pointer"
															style={{ color: 'var(--ars-ink-3)' }}
															onClick={() => setHours(day, { break_start: '', break_end: '' })}
														>
															<IconX size={14} />
														</button>
													</>
												) : (
													<button
														type="button"
														className="border-0 bg-transparent cursor-pointer text-[12px] underline"
														style={{ color: 'var(--ars-ink-3)' }}
														onClick={() => setHours(day, { break_start: '12:00', break_end: '13:00' })}
													>
														+ midday break
													</button>
												)}
											</>
										)}
									</div>
								);
							})}
						</div>
						<Explain title={__('Why a midday break is worth entering', 'ai-rank-suite')}>
							<p>
								{__('A practice that closes between 12 and 13 but publishes 09:00–17:00 tells an assistant it is open at 12:30. Two windows per day is the shape Google expects, and it is what stops someone standing in front of a locked door.', 'ai-rank-suite')}
							</p>
						</Explain>
					</Card>

					<Card
						title={__('Holidays and one-off changes', 'ai-rank-suite')}
						subtitle={__('Dated exceptions override the weekly grid — publish them before the holiday, not after', 'ai-rank-suite')}
						action={
							<Button
								variant="ghost"
								onClick={() =>
									addTo('special_hours', {
										date: new Date().toISOString().slice(0, 10),
										until: '',
										label: '',
										closed: true,
										open: '',
										close: '',
									})
								}
							>
								+ Add date
							</Button>
						}
					>
						{(s.special_hours || []).length === 0 ? (
							<p className="m-0 text-[13px]" style={{ color: 'var(--ars-ink-2)' }}>
								{__('No exceptions yet. Christmas, a public holiday, a week of stocktaking — each one entered here is a question your phone does not have to answer.', 'ai-rank-suite')}
							</p>
						) : (
							
								<div className="ars-table-wrap">
							
									<div className="ars-table-wrap"><table className="ars-table">
									<thead>
										<tr>
											<th className="is-mid">{__('From', 'ai-rank-suite')}</th>
											<th className="is-mid">{__('To (optional)', 'ai-rank-suite')}</th>
											<th>{__('Label', 'ai-rank-suite')}</th>
											<th className="is-narrow">{__('Closed', 'ai-rank-suite')}</th>
											<th className="is-mid">{__('Hours', 'ai-rank-suite')}</th>
											<th className="is-action" />
										</tr>
									</thead>
									<tbody>
										{(s.special_hours || []).map((entry, i) => {
											// A closure that has already happened is not emitted any
											// more, so saying so beats letting the row look active.
											const past = (entry.until || entry.date || '') < today;
											return (
											<tr key={i} style={past ? { opacity: 0.6 } : undefined}>
												<td>
													<input
														type="date"
														value={entry.date || ''}
														onChange={(e) => setList('special_hours', i, { date: e.target.value })}
													/>
												</td>
												<td>
													<input
														type="date"
														value={entry.until || ''}
														onChange={(e) => setList('special_hours', i, { until: e.target.value })}
													/>
												</td>
												<td>
													<div className="flex items-center gap-2">
														<input
															type="text"
															placeholder={__('Christmas Day', 'ai-rank-suite')}
															value={entry.label || ''}
															onChange={(e) => setList('special_hours', i, { label: e.target.value })}
														/>
														{past && <span className="ars-tag shrink-0">{__('Past', 'ai-rank-suite')}</span>}
													</div>
												</td>
												<td className="is-narrow">
													<input
														type="checkbox"
														checked={!!entry.closed}
														onChange={(e) => setList('special_hours', i, { closed: e.target.checked })}
													/>
												</td>
												<td>
													{entry.closed ? (
														<span className="t-caption">{__('Closed all day', 'ai-rank-suite')}</span>
													) : (
														<div className="flex items-center gap-1.5">
															<input
																type="time"
																value={entry.open || ''}
																onChange={(e) => setList('special_hours', i, { open: e.target.value })}
																style={{ width: 104 }}
															/>
															<span style={{ color: 'var(--ars-ink-3)' }}>–</span>
															<input
																type="time"
																value={entry.close || ''}
																onChange={(e) => setList('special_hours', i, { close: e.target.value })}
																style={{ width: 104 }}
															/>
														</div>
													)}
												</td>
												<td className="is-action">
													<button
														type="button"
														aria-label={__('Remove date', 'ai-rank-suite')}
														className="border-0 bg-transparent cursor-pointer"
														style={{ color: 'var(--ars-ink-3)' }}
														onClick={() => removeFrom('special_hours', i)}
													>
														<IconX size={15} />
													</button>
												</td>
											</tr>
											);
										})}
									</tbody>
								</table></div>
							</div>
						)}
					</Card>
				</>
			)}

			{tab === 'locations' && (
				<Card
					icon={<IconMap size={16} />} title={__('Branches', 'ai-rank-suite')}
					subtitle={__('Each branch becomes its own LocalBusiness node, linked back to head office as its parent', 'ai-rank-suite')}
					action={
						<Button
							variant="ghost"
							onClick={() => {
								addTo('locations', { ...BLANK_LOCATION });
								setOpenIndex((s.locations || []).length);
							}}
						>
							+ {__('Add branch', 'ai-rank-suite')}
						</Button>
					}
				>
					{(s.locations || []).length === 0 ? (
						<p className="m-0 text-[13px]" style={{ color: 'var(--ars-ink-2)' }}>
							{__('One location so far. Add branches if you have several — every field left empty inherits from the main profile, so a second surgery in the next town usually needs nothing but a street and a phone number. List them on any page with', 'ai-rank-suite')}{' '}
							<code className="ars-mono">[airanksuite_locations]</code>.
						</p>
					) : (
						<div className="grid gap-2">
							{(s.locations || []).map((loc, i) => {
								const open = openIndex === i;
								return (
									<div key={i} className="ars-r-md" style={{ border: '1px solid var(--ars-border)' }}>
										<div
											className="flex items-center gap-2 px-3 py-2 cursor-pointer"
											style={{ background: 'var(--ars-surface-2)' }}
											onClick={() => setOpenIndex(open ? -1 : i)}
										>
											<span aria-hidden style={{ color: 'var(--ars-ink-3)', width: 12 }}>
												{open ? '▾' : '▸'}
											</span>
											<span className="font-medium">{loc.name || sprintf(__('Branch %d', 'ai-rank-suite'), i + 1)}</span>
											<span className="t-caption truncate">
												{[loc.street, loc.city].filter(Boolean).join(', ') || __('inherits the main address', 'ai-rank-suite')}
											</span>
											{loc.own_hours && <span className="ars-tag">{__('own hours', 'ai-rank-suite')}</span>}
											<button
												type="button"
												aria-label={__('Remove branch', 'ai-rank-suite')}
												className="border-0 bg-transparent cursor-pointer ml-auto"
												style={{ color: 'var(--ars-ink-3)' }}
												onClick={(e) => {
													e.stopPropagation();
													removeFrom('locations', i);
													setOpenIndex(-1);
												}}
											>
												<IconX size={15} />
											</button>
										</div>

										{open && (
											<div className="p-3 grid gap-3">
												<div className="grid gap-3 sm:grid-cols-2">
													<Field label={__('Name', 'ai-rank-suite')}>
														<input
															type="text"
															value={loc.name || ''}
															onChange={(e) => setLocation(i, { name: e.target.value })}
														/>
													</Field>
													<Field label={__('Business type', 'ai-rank-suite')} hint={__('Leave on “Same as main profile” unless this branch is different.', 'ai-rank-suite')}>
														<select
															value={loc.business_type || ''}
															onChange={(e) => setLocation(i, { business_type: e.target.value })}
														>
															<option value="">{__('Same as main profile', 'ai-rank-suite')}</option>
															{Object.entries(data.type_groups || {}).map(([group, types]) => (
																<optgroup key={group} label={group}>
																	{types.map((t) => (
																		<option key={t} value={t}>
																			{t}
																		</option>
																	))}
																</optgroup>
															))}
														</select>
													</Field>
													{[
														['street', __('Street and number', 'ai-rank-suite')],
														['street2', __('Suite / floor', 'ai-rank-suite')],
														['postal_code', __('Postal code', 'ai-rank-suite')],
														['city', __('City', 'ai-rank-suite')],
														['region', __('Region / state', 'ai-rank-suite')],
														['country', __('Country code', 'ai-rank-suite')],
														['phone', __('Phone', 'ai-rank-suite')],
														['email', __('Email', 'ai-rank-suite')],
														['latitude', __('Latitude', 'ai-rank-suite')],
														['longitude', __('Longitude', 'ai-rank-suite')],
														['price_range', __('Price range', 'ai-rank-suite')],
														['map_url', __('Map link', 'ai-rank-suite')],
														['booking_url', __('Booking link', 'ai-rank-suite')],
													].map(([key, label]) => (
														<Field key={key} label={label}>
															<input
																type="text"
																value={loc[key] || ''}
																onChange={(e) => setLocation(i, { [key]: e.target.value })}
															/>
														</Field>
													))}
												</div>

												<MediaPicker
													label={__('Photo of this branch', 'ai-rank-suite')}
													value={loc.image_url}
													onChange={(v) => setLocation(i, { image_url: v })}
													height={72}
												/>

												<Switch
													checked={!!loc.own_hours}
													onChange={(v) =>
														setLocation(i, {
															own_hours: v,
															hours: v && !Object.keys(loc.hours || {}).length ? s.hours : loc.hours,
														})
													}
													label={__('This branch has its own opening hours', 'ai-rank-suite')}
												/>

												{loc.own_hours && (
													<div className="grid gap-2">
														{data.days.map((day) => {
															const slot = (loc.hours || {})[day] || {};
															return (
																<div key={day} className="flex items-center gap-3 flex-wrap" style={{ minHeight: 36 }}>
																	<span className="font-medium" style={{ minWidth: 100 }}>
																		{DAY_LABELS[day]}
																	</span>
																	<Switch
																		checked={!slot.closed}
																		onChange={(v) =>
																			setLocation(i, {
																				hours: { ...loc.hours, [day]: { ...slot, closed: !v } },
																			})
																		}
																		label={slot.closed ? 'Closed' : 'Open'}
																	/>
																	{!slot.closed && (
																		<>
																			<input
																				type="time"
																				value={slot.open || ''}
																				onChange={(e) =>
																					setLocation(i, {
																						hours: { ...loc.hours, [day]: { ...slot, open: e.target.value } },
																					})
																				}
																				style={{ width: 116 }}
																			/>
																			<span style={{ color: 'var(--ars-ink-3)' }}>–</span>
																			<input
																				type="time"
																				value={slot.close || ''}
																				onChange={(e) =>
																					setLocation(i, {
																						hours: { ...loc.hours, [day]: { ...slot, close: e.target.value } },
																					})
																				}
																				style={{ width: 116 }}
																			/>
																		</>
																	)}
																</div>
															);
														})}
													</div>
												)}
											</div>
										)}
									</div>
								);
							})}
						</div>
					)}
				</Card>
			)}

			{tab === 'reach' && (
				<>
					<Card
						icon={<IconMap size={16} />} title={__('Service areas', 'ai-rank-suite')}
						subtitle={__('The towns and districts you travel to — the answer to “do you come to …?”', 'ai-rank-suite')}
					>
						<TagInput
							value={s.areas || []}
							onChange={(v) => update({ areas: v })}
							placeholder={__('Add a town or district and press Enter', 'ai-rank-suite')}
						/>
						<Explain title={__('When service areas matter more than an address', 'ai-rank-suite')}>
							<p>
								{__('A plumber, a mobile physiotherapist or a wedding photographer serves a radius, not a shopfront. Listing those places as areaServed is what lets you appear for a town you have no office in — and it is the only local signal available at all to a business that works from home and publishes no address.', 'ai-rank-suite')}
							</p>
						</Explain>
					</Card>

					<Card title={__('Services', 'ai-rank-suite')} subtitle={__('Named services with prices, published as an offer catalogue', 'ai-rank-suite')}
						action={
							<Button variant="ghost" onClick={() => addTo('services', { name: '', description: '', price: '', currency: '', url: '' })}>
								+ {__('Add service', 'ai-rank-suite')}
							</Button>
						}
					>
						{(s.services || []).length === 0 ? (
							<p className="m-0 text-[13px]" style={{ color: 'var(--ars-ink-2)' }}>
								{__('Nothing listed. “What does a check-up cost?” is one of the most common questions asked of an assistant, and a priced service here is a concrete answer it can give — with your name attached. Render them on a page with', 'ai-rank-suite')}{' '}
								<code className="ars-mono">[airanksuite_services]</code>.
							</p>
						) : (
							<div className="grid gap-2">
								{(s.services || []).map((service, i) => (
									<div key={i} className="ars-r-sm p-3 grid gap-2" style={{ background: 'var(--ars-surface-2)' }}>
										<div className="grid gap-2 sm:grid-cols-[2fr_1fr_1fr_auto]">
											<input
												type="text"
												placeholder={__('Service name', 'ai-rank-suite')}
												value={service.name || ''}
												onChange={(e) => setList('services', i, { name: e.target.value })}
											/>
											<input
												type="text"
												placeholder={__('Price', 'ai-rank-suite')}
												value={service.price || ''}
												onChange={(e) => setList('services', i, { price: e.target.value })}
											/>
											<input
												type="text"
												placeholder={s.currencies || 'EUR'}
												value={service.currency || ''}
												onChange={(e) => setList('services', i, { currency: e.target.value })}
											/>
											<button
												type="button"
												aria-label={__('Remove service', 'ai-rank-suite')}
												className="border-0 bg-transparent cursor-pointer"
												style={{ color: 'var(--ars-ink-3)' }}
												onClick={() => removeFrom('services', i)}
											>
												<IconX size={15} />
											</button>
										</div>
										<div className="grid gap-2 sm:grid-cols-2">
											<input
												type="text"
												placeholder={__('Short description', 'ai-rank-suite')}
												value={service.description || ''}
												onChange={(e) => setList('services', i, { description: e.target.value })}
											/>
											<input
												type="url"
												placeholder={__('Link to the service page (optional)', 'ai-rank-suite')}
												value={service.url || ''}
												onChange={(e) => setList('services', i, { url: e.target.value })}
											/>
										</div>
									</div>
								))}
							</div>
						)}
					</Card>

					<Card
						title={__('Departments and practitioners', 'ai-rank-suite')}
						subtitle={__('A clinic with three specialities, a firm with four partners — each becomes its own node', 'ai-rank-suite')}
						action={
							<Button variant="ghost" onClick={() => addTo('departments', { name: '', business_type: 'LocalBusiness', phone: '', email: '', url: '' })}>
								+ Add department
							</Button>
						}
					>
						{(s.departments || []).length === 0 ? (
							<p className="m-0 text-[13px]" style={{ color: 'var(--ars-ink-2)' }}>
								{__('None yet. Use this when one address houses several distinct practices — an orthodontist inside a dental clinic, a tax adviser inside a law firm — so each can be found on its own terms.', 'ai-rank-suite')}
							</p>
						) : (
							<div className="grid gap-2">
								{(s.departments || []).map((dept, i) => (
									<div key={i} className="grid gap-2 sm:grid-cols-[2fr_1.4fr_1fr_1fr_auto] items-center">
										<input
											type="text"
											placeholder={__('Name', 'ai-rank-suite')}
											value={dept.name || ''}
											onChange={(e) => setList('departments', i, { name: e.target.value })}
										/>
										<select
											value={dept.business_type || 'LocalBusiness'}
											onChange={(e) => setList('departments', i, { business_type: e.target.value })}
										>
											{Object.entries(data.type_groups || {}).map(([group, types]) => (
												<optgroup key={group} label={group}>
													{types.map((t) => (
														<option key={t} value={t}>
															{t}
														</option>
													))}
												</optgroup>
											))}
										</select>
										<input
											type="text"
											placeholder={__('Phone', 'ai-rank-suite')}
											value={dept.phone || ''}
											onChange={(e) => setList('departments', i, { phone: e.target.value })}
										/>
										<input
											type="email"
											placeholder={__('Email', 'ai-rank-suite')}
											value={dept.email || ''}
											onChange={(e) => setList('departments', i, { email: e.target.value })}
										/>
										<button
											type="button"
											aria-label={__('Remove department', 'ai-rank-suite')}
											className="border-0 bg-transparent cursor-pointer"
											style={{ color: 'var(--ars-ink-3)' }}
											onClick={() => removeFrom('departments', i)}
										>
											<IconX size={15} />
										</button>
									</div>
								))}
							</div>
						)}
					</Card>

					<Card icon={<IconLayers size={16} />} title={__('Amenities', 'ai-rank-suite')} subtitle={__('“Is it wheelchair accessible?” is a question with a schema answer', 'ai-rank-suite')}>
						<CheckGrid
							options={Object.entries(data.amenities || {}).map(([key, label]) => ({ key, label }))}
							value={s.amenities || []}
							onChange={(v) => update({ amenities: v })}
						/>
					</Card>

					<div className="grid gap-4 md:grid-cols-2">
						<Card icon={<IconLink size={16} />} title={__('Linked profiles', 'ai-rank-suite')} subtitle={__('Published as sameAs — how an engine confirms you are one entity', 'ai-rank-suite')}>
							<TagInput
								value={s.profiles || []}
								onChange={(v) => update({ profiles: v })}
								placeholder="https://www.google.com/maps/place/…"
							/>
							<Explain title={__('Which links belong here', 'ai-rank-suite')}>
								<p>
									{__('Your Google Business Profile first, then the directories your industry actually uses — Facebook, LinkedIn, Instagram, Jameda, an industry register. Each one is a claim that the entity at that URL and the entity on this site are the same, which is what lets an assistant merge the reviews and the opening hours into a single confident answer.', 'ai-rank-suite')}
								</p>
							</Explain>
						</Card>

						<Card icon={<IconExternal size={16} />} title={__('Languages spoken', 'ai-rank-suite')} subtitle={__('Published as knowsLanguage', 'ai-rank-suite')}>
							<TagInput
								value={s.languages || []}
								onChange={(v) => update({ languages: v })}
								suggestions={LANGUAGE_SUGGESTIONS}
								placeholder={__('Add a language', 'ai-rank-suite')}
							/>
						</Card>
					</div>

					<Card icon={<IconLink size={16} />} title={__('Action links', 'ai-rank-suite')} subtitle={__('Where an assistant sends someone who wants to act', 'ai-rank-suite')}>
						<div className="grid gap-3 sm:grid-cols-2">
							<Field label={__('Booking / appointment URL', 'ai-rank-suite')} hint={__('Emitted as a ReserveAction.', 'ai-rank-suite')}>
								<input
									type="url"
									value={s.booking_url || ''}
									onChange={(e) => update({ booking_url: e.target.value })}
								/>
							</Field>
							<Field label={__('Map URL', 'ai-rank-suite')} hint={__('Leave empty to generate a Google Maps search from the address.', 'ai-rank-suite')}>
								<input type="url" value={s.map_url || ''} onChange={(e) => update({ map_url: e.target.value })} />
							</Field>
							<Field label={__('Menu URL', 'ai-rank-suite')} hint={__('Restaurants and cafés.', 'ai-rank-suite')}>
								<input type="url" value={s.menu_url || ''} onChange={(e) => update({ menu_url: e.target.value })} />
							</Field>
							<Field label={__('Order URL', 'ai-rank-suite')}>
								<input type="url" value={s.order_url || ''} onChange={(e) => update({ order_url: e.target.value })} />
							</Field>
						</div>
					</Card>
				</>
			)}

			{tab === 'listings' && (
				<LocalListings
					record={s}
					onImported={(patch) => {
						// A URL typed for Bing/Apple lands in the form; an import from
						// Google reloads the record so the Profile tab shows it.
						if (patch) update(patch);
						else reload();
					}}
				/>
			)}

			{tab === 'output' && (
				<>
					<Card
						icon={<IconCode size={16} />} title={__('Structured data', 'ai-rank-suite')}
						subtitle={__('Exactly what is printed on your home page — no view-source needed', 'ai-rank-suite')}
						action={
							preview?.test && (
								<a className="ars-url" href={preview.test} target="_blank" rel="noreferrer noopener">{__('Open in Google\'s Rich Results Test ↗', 'ai-rank-suite')}</a>
							)
						}
					>
						{!preview ? (
							<p className="m-0 text-[13px]" style={{ color: 'var(--ars-ink-2)' }}>{__('Loading the preview…', 'ai-rank-suite')}</p>
						) : (
							<div className="grid gap-2.5">
								<div className="flex items-center gap-2 flex-wrap">
									<Badge tone={preview.active ? 'good' : 'warn'}>
										{preview.active ? __('Published on the home page', 'ai-rank-suite') : __('Not published — switch “Publish” on', 'ai-rank-suite')}
									</Badge>
									<span className="t-caption">
										{sprintf(_n('%d node in the graph', '%d nodes in the graph', preview.nodes, 'ai-rank-suite'), preview.nodes)}
									</span>
								</div>
								<CodeBlock code={preview.json} language="json" />
							</div>
						)}
					</Card>

					<Card icon={<IconCode size={16} />} title={__('Shortcodes', 'ai-rank-suite')} subtitle={__('Drop the business data into any page, post or widget', 'ai-rank-suite')}>
						
							<div className="ars-table-wrap">
						
								<div className="ars-table-wrap"><table className="ars-table">
								<thead>
									<tr>
										<th style={{ width: 240 }}>{__('Shortcode', 'ai-rank-suite')}</th>
										<th>{__('What it renders', 'ai-rank-suite')}</th>
									</tr>
								</thead>
								<tbody>
									{[
										['[airanksuite_business_address]', __('Full address block, marked up as <address>', 'ai-rank-suite')],
										['[airanksuite_business_hours]', __('Opening-hours table, including upcoming holiday closures', 'ai-rank-suite')],
										['[airanksuite_business_hours special="no"]', __('The weekly grid only, without exceptions', 'ai-rank-suite')],
										['[airanksuite_business_phone]', __('Click-to-call phone number', 'ai-rank-suite')],
										['[airanksuite_open_now]', __('Live “Open now / Closed” badge in the site timezone', 'ai-rank-suite')],
										['[airanksuite_business_map]', __('Address as a link to your map pin', 'ai-rank-suite')],
										['[airanksuite_services]', __('Your service list with prices', 'ai-rank-suite')],
										['[airanksuite_locations]', __('Every branch, one address block each', 'ai-rank-suite')],
									].map(([code, desc]) => (
										<tr key={code}>
											<td>
												<code className="ars-mono">{code}</code>
											</td>
											<td>{desc}</td>
										</tr>
									))}
								</tbody>
							</table></div>
						</div>
					</Card>

					<Card icon={<IconChart size={16} />} title={__('Profile checklist', 'ai-rank-suite')} subtitle={__('Everything that goes into the score, in one list', 'ai-rank-suite')}>
						
							<div className="ars-table-wrap">
						
								<div className="ars-table-wrap"><table className="ars-table">
								<thead>
									<tr>
										<th style={{ width: 34 }} />
										<th style={{ width: 220 }}>{__('Field', 'ai-rank-suite')}</th>
										<th className="is-mid">{__('Weight', 'ai-rank-suite')}</th>
										<th>{__('Why it matters', 'ai-rank-suite')}</th>
									</tr>
								</thead>
								<tbody>
									{completeness.checks.map((check) => (
										<tr key={check.id}>
											<td style={{ width: 34, color: check.ok ? 'var(--ars-c-green-ink)' : 'var(--ars-ink-3)' }}>
												{check.ok ? '✓' : '○'}
											</td>
											<td style={{ fontWeight: check.ok ? 400 : 600 }}>{check.label}</td>
											<td className="is-mid">
												<span
													className="ars-tag"
													style={{
														color: `var(--ars-c-${TIER_TONE[check.tier]}-ink)`,
														background: `var(--ars-c-${TIER_TONE[check.tier]})`,
													}}
												>
													{TIER_LABEL[check.tier]}
												</span>
											</td>
											<td style={{ color: 'var(--ars-ink-2)' }}>{check.hint || '—'}</td>
										</tr>
									))}
								</tbody>
							</table></div>
						</div>
					</Card>
				</>
			)}

			{/* The form is five tabs deep now; a save button that lives at the bottom
			    of one of them is a save button somebody will miss. */}
			<div className="ars-savebar">
				<Button onClick={save} busy={busy}>{__('Save changes', 'ai-rank-suite')}</Button>
				{saved && <Badge tone="good">✓ {__('Saved', 'ai-rank-suite')}</Badge>}
				<span className="t-caption ml-auto">
					{s.enabled
						? __('Published on the home page as LocalBusiness structured data.', 'ai-rank-suite')
						: __('Not published yet — turn on “Publish” at the top.', 'ai-rank-suite')}
				</span>
			</div>
		</div>
	);
}
