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

/**
 * The business as the directories know it.
 *
 * A "near me" answer is assembled from the directories, not from the site:
 * Google Business Profile first, Bing Places for Copilot, Apple Business
 * Connect for Siri and Maps. This tab connects the Google listing through the
 * Places API — the part of the profile the public sees, on a key from Google
 * Cloud that works the same afternoon — compares it field by field with the
 * record on the Profile tab, imports it, and keeps a weekly rating history.
 * Bing and Apple publish no listing API; they are attached by URL, published
 * as sameAs, and kept aligned by Bing's own sync from the Google profile.
 *
 * @param {object}   props
 * @param {object}   props.record   The business record (settings).
 * @param {Function} props.onImported Called after an import so the form reloads.
 */
export default function LocalListings({ record, onImported }) {
	const [data, setData] = useState(null);
	const [error, setError] = useState(null);
	const [key, setKey] = useState('');
	const [query, setQuery] = useState('');
	const [found, setFound] = useState(null);
	const [busy, setBusy] = useState('');
	const [imported, setImported] = useState(null);

	const load = () => api.get('/local-seo/listings').then(setData).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 saveKey = () =>
		run('key', async () => {
			setData(await api.post('/local-seo/listings', { key }));
			setKey('');
		});
	const search = () => run('search', async () => setFound((await api.post('/local-seo/listings/search', { query })).places || []));
	const fetch = (placeId) =>
		run('fetch', async () => {
			setData(await api.post('/local-seo/listings/fetch', { place_id: placeId }));
			setFound(null);
		});
	const doImport = (overwrite) =>
		run(overwrite ? 'overwrite' : 'import', async () => {
			const r = await api.post('/local-seo/listings/import', { overwrite });
			setData(r);
			setImported(r.imported || []);
			onImported && onImported();
		});
	const forget = () => run('forget', async () => setData(await api.del('/local-seo/listings/google')));

	if (!data) return null;

	const g = data.google;
	const mismatches = (data.compare || []).filter((c) => c.match === false);
	const history = (data.history || []).map((h) => ({ label: h.day.slice(5), value: h.reviews, rating: h.rating }));
	const firstR = data.history?.[0];
	const lastR = data.history?.[data.history.length - 1];

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

			{/* Verdict first: connected and consistent, connected with
			    differences, or not connected. */}
			{g ? (
				mismatches.length === 0 ? (
					<Notice tone="good">
						<b>{__('Google Business Profile matches your record', 'ai-rank-suite')}</b> — {__('name, address, phone and website agree with what Google shows.', 'ai-rank-suite')} {g.reviews ? sprintf(__('%1$s ★ from %2$s reviews.', 'ai-rank-suite'), g.rating, g.reviews.toLocaleString()) : ''}
					</Notice>
				) : (
					<Notice tone="warning">
						<b>
							{sprintf(_n('%d field differs between your record and Google', '%d fields differ between your record and Google', mismatches.length, 'ai-rank-suite'), mismatches.length)}
						</b>{' '}
						{/*
						  * The labels as written, again.
						  * Lowercasing them reads naturally mid-sentence in
						  * English — "street and number differs" — and is the
						  * same spelling mistake in German, where every noun is
						  * capitalised. This is the second instance of it; the
						  * button above was the first.
						  */}
						— {mismatches.map((m) => m.label).join(', ')}. {__('To a matching engine a different street spelling is a different business. Fix one side: import Google’s values below, or edit the Profile tab and then correct the Google listing to match.', 'ai-rank-suite')}
					</Notice>
				)
			) : (
				<Notice tone="info">
					<b>{__('No directory is connected yet.', 'ai-rank-suite')}</b> {__('Google Business Profile is where a “near me” answer starts; connect it to check that your record and Google’s agree character for character.', 'ai-rank-suite')}
				</Notice>
			)}

			<div className="grid gap-4 lg:grid-cols-2 items-stretch">
				{/* ---- Google ------------------------------------------------ */}
				<Card
					title={__('Google Business Profile', 'ai-rank-suite')}
					subtitle={__('Read through the Places API — the public listing, live from Google', 'ai-rank-suite')}
					action={
						g ? (
							<span className="flex items-center gap-2">
								<Button variant="ghost" busy={busy === 'fetch'} onClick={() => fetch(g.place_id)}>{__('Refresh', 'ai-rank-suite')}</Button>
								<Button variant="ghost" busy={busy === 'forget'} onClick={forget}>{__('Disconnect', 'ai-rank-suite')}</Button>
							</span>
						) : null
					}
				>
					{!data.has_key ? (
						<div className="grid gap-3">
							<Field
								label={__('Google Places API key', 'ai-rank-suite')}
								hint={__('Google Cloud → APIs & Services → Credentials → API key, with “Places API (New)” enabled. Stored encrypted; the first ~10,000 lookups a month are free.', 'ai-rank-suite')}
							>
								<input type="password" autoComplete="off" value={key} onChange={(e) => setKey(e.target.value)} placeholder={__('AIza…', 'ai-rank-suite')} />
							</Field>
							<div className="flex items-center gap-2 flex-wrap">
								<Button onClick={saveKey} busy={busy === 'key'} disabled={!key.trim()}>{__('Save key', 'ai-rank-suite')}</Button>
								<a className="ars-linkbtn" href="https://console.cloud.google.com/apis/library/places-backend.googleapis.com" target="_blank" rel="noreferrer">{__('Enable Places API (New) ↗', 'ai-rank-suite')}</a>
							</div>
							<Explain title={__('Why a Places key and not “Sign in with Google”', 'ai-rank-suite')}>
								<p>
									{__('Google’s Business Profile management API needs a project reviewed and approved by Google — weeks, and quota zero until then. The Places API answers with a plain key the same afternoon and returns the part of the profile that matters for consistency: name, address, phone, website, hours, rating and review count. Editing the profile stays on Google’s side; this checks and imports.', 'ai-rank-suite')}
								</p>
							</Explain>
						</div>
					) : !g ? (
						<div className="grid gap-3">
							<span className="t-caption">{sprintf(__('Key saved (%s).', 'ai-rank-suite'), data.key_hint)}</span>
							<form
								className="flex gap-2"
								onSubmit={(e) => {
									e.preventDefault();
									search();
								}}
							>
								<input
									type="text"
									value={query}
									onChange={(e) => setQuery(e.target.value)}
									placeholder={`${record.name || __('Business name', 'ai-rank-suite')}, ${record.city || __('city', 'ai-rank-suite')}`}
									style={{ flex: 1 }}
								/>
								<Button onClick={search} busy={busy === 'search'} disabled={!query.trim()}>{__('Find my listing', 'ai-rank-suite')}</Button>
							</form>
							{found && found.length === 0 && <span className="t-caption">{__('Nothing found — try the name as it appears on Google Maps.', 'ai-rank-suite')}</span>}
							{found && found.length > 0 && (
								<div className="grid gap-1.5">
									{found.map((p) => (
										<button key={p.id} type="button" className="ars-place" onClick={() => fetch(p.id)}>
											<span className="grid gap-0.5 min-w-0">
												<span className="font-semibold text-[13px] truncate">{p.name}</span>
												<span className="t-caption truncate">{p.address}</span>
											</span>
											<span className="t-caption shrink-0">
												{p.rating ? `${p.rating} ★ · ${p.reviews}` : p.type || ''}
											</span>
										</button>
									))}
								</div>
							)}
							<button type="button" className="ars-linkbtn justify-self-start" onClick={() => run('key', async () => setData(await api.post('/local-seo/listings', { key: '' })))}>{__('Remove key', 'ai-rank-suite')}</button>
						</div>
					) : (
						<div className="grid gap-3">
							<div className="ars-listing-head">
								<div className="grid gap-0.5 min-w-0">
									<span className="font-semibold text-[15px] truncate">{g.name}</span>
									<span className="t-caption truncate">{g.address}</span>
									<span className="t-caption">
										{g.type}
										{g.status && g.status !== 'OPERATIONAL' ? ` · ${g.status.toLowerCase().replace(/_/g, ' ')}` : ''}
									</span>
								</div>
								<div className="ars-listing-rating">
									<span className="ars-listing-stars t-num">{g.rating ?? '–'}</span>
									<span className="t-caption">★ · {sprintf(_n('%s review', '%s reviews', g.reviews || 0, 'ai-rank-suite'), (g.reviews || 0).toLocaleString())}</span>
								</div>
							</div>
							{g.hours && g.hours.length > 0 && (
								<details>
									<summary className="t-caption cursor-pointer">{__('Hours as Google shows them', 'ai-rank-suite')}</summary>
									<ul className="m-0 mt-1 pl-4 text-[12px]" style={{ color: 'var(--ars-ink-2)' }}>
										{g.hours.map((h) => (
											<li key={h}>{h}</li>
										))}
									</ul>
								</details>
							)}
							<div className="flex items-center gap-2 flex-wrap">
								{g.maps_url && (
									<a className="ars-linkbtn" href={g.maps_url} target="_blank" rel="noreferrer">{__('Open on Google Maps ↗', 'ai-rank-suite')}</a>
								)}
								<a className="ars-linkbtn" href="https://business.google.com/" target="_blank" rel="noreferrer">{__('Edit in Business Profile ↗', 'ai-rank-suite')}</a>
								<span className="t-caption">{sprintf(__('Fetched %s · refreshed weekly', 'ai-rank-suite'), new Date(g.fetched * 1000).toLocaleString())}</span>
							</div>
						</div>
					)}
				</Card>

				{/* ---- Consistency ---------------------------------------- */}
				<Card
					title={__('NAP consistency', 'ai-rank-suite')}
					subtitle={__('Your record beside Google’s listing — the fields a matching engine compares', 'ai-rank-suite')}
					flush
					action={
						g && (
							<span className="flex items-center gap-2">
								<Button variant="tonal" busy={busy === 'import'} onClick={() => doImport(false)}>{__('Fill empty fields', 'ai-rank-suite')}</Button>
								<Button variant="ghost" busy={busy === 'overwrite'} onClick={() => doImport(true)}>{__('Overwrite with Google', 'ai-rank-suite')}</Button>
							</span>
						)
					}
				>
					{!g ? (
						<div className="px-4 py-4 text-[12.5px]" style={{ color: 'var(--ars-ink-2)' }}>{__('Connect the Google listing and this becomes a field-by-field comparison with one-click import.', 'ai-rank-suite')}</div>
					) : (
						<div className="ars-table-wrap">
							<table className="ars-table">
								<thead>
									<tr>
										<th>{__('Field', 'ai-rank-suite')}</th>
										<th>{__('Your record', 'ai-rank-suite')}</th>
										<th>{__('Google', 'ai-rank-suite')}</th>
										<th style={{ width: 80 }} />
									</tr>
								</thead>
								<tbody>
									{data.compare.map((c) => (
										<tr key={c.key}>
											<td className="font-medium">{c.label}</td>
											<td className={c.ours ? '' : 'is-muted'} style={{ maxWidth: 220 }}>
												<span className="truncate block">{c.ours || '—'}</span>
											</td>
											<td className={c.theirs ? '' : 'is-muted'} style={{ maxWidth: 220 }}>
												<span className="truncate block">{c.theirs || '—'}</span>
											</td>
											<td className="is-num">
												{c.match === true ? <Badge tone="good">{__('match', 'ai-rank-suite')}</Badge> : c.match === false ? <Badge tone="warning">{__('differs', 'ai-rank-suite')}</Badge> : <Badge tone="neutral">{__('n/a', 'ai-rank-suite')}</Badge>}
											</td>
										</tr>
									))}
								</tbody>
							</table>
							{imported && (
								<p className="m-0 px-4 py-2 t-caption">
									{imported.length ? sprintf(__('Imported: %s. Save the profile to publish.', 'ai-rank-suite'), imported.join(', ')) : __('Nothing to import — every field was already filled.', 'ai-rank-suite')}
								</p>
							)}
						</div>
					)}
				</Card>
			</div>

			{/* ---- Reviews trend -------------------------------------------- */}
			{history.length > 0 && (
				<Card
					title={__('Reviews over time', 'ai-rank-suite')}
					subtitle={__('One point per weekly read — a listing that gains reviews is one an assistant trusts more', 'ai-rank-suite')}
					action={history.length > 1 && lastR && firstR ? <Delta value={lastR.reviews - firstR.reviews} suffix={` ${__('reviews since first read', 'ai-rank-suite')}`} /> : null}
				>
					<LineChart data={history} label={__('Reviews', 'ai-rank-suite')} color="var(--ars-good)" height={140} formatValue={(v) => `${v}`} />
					{lastR && lastR.rating !== null && (
						<p className="m-0 mt-2 t-caption">
							{sprintf(__('Rating now %s ★', 'ai-rank-suite'), lastR.rating)}{firstR && firstR.rating !== null && firstR !== lastR ? ` ${sprintf(__('(was %1$s ★ on %2$s)', 'ai-rank-suite'), firstR.rating, firstR.day)}` : ''}.
						</p>
					)}
				</Card>
			)}

			{/* ---- Bing + Apple ------------------------------------------- */}
			<div className="grid gap-4 lg:grid-cols-2 items-stretch">
				<Card title={__('Bing Places for Business', 'ai-rank-suite')} subtitle={__('What Copilot and Bing Maps show — no public API, so it is attached by URL', 'ai-rank-suite')}>
					<div className="grid gap-3">
						<Field label={__('Your Bing Places listing URL', 'ai-rank-suite')} hint={__('Published as sameAs alongside the Google listing.', 'ai-rank-suite')}>
							<input type="url" style={{ width: "100%" }} value={record.bing_url || ''} onChange={(e) => onImported && onImported({ bing_url: e.target.value })} placeholder="https://www.bing.com/maps?…" />
						</Field>
						<div className="flex items-center gap-2 flex-wrap">
							<a className="ars-linkbtn" href="https://www.bingplaces.com/" target="_blank" rel="noreferrer">{__('Open Bing Places ↗', 'ai-rank-suite')}</a>
							{record.bing_url ? <Badge tone="good">{__('attached', 'ai-rank-suite')}</Badge> : <Badge tone="neutral">{__('not attached', 'ai-rank-suite')}</Badge>}
						</div>
						<Explain title={__('Keep Bing identical to Google in one click', 'ai-rank-suite')}>
							<p>
								{__('Bing Places has an “Import from Google My Business” option in its dashboard that syncs name, address, phone, hours and photos from your Google profile — and can keep syncing. Use it, and the consistency check above covers Bing too.', 'ai-rank-suite')}
							</p>
						</Explain>
					</div>
				</Card>
				<Card title={__('Apple Business Connect', 'ai-rank-suite')} subtitle={__('What Siri and Apple Maps show — attached by URL', 'ai-rank-suite')}>
					<div className="grid gap-3">
						<Field label={__('Your Apple Maps place URL', 'ai-rank-suite')} hint={__('From Apple Business Connect → your location → Share. Published as sameAs.', 'ai-rank-suite')}>
							<input type="url" style={{ width: "100%" }} value={record.apple_url || ''} onChange={(e) => onImported && onImported({ apple_url: e.target.value })} placeholder="https://maps.apple.com/place?…" />
						</Field>
						<div className="flex items-center gap-2 flex-wrap">
							<a className="ars-linkbtn" href="https://businessconnect.apple.com/" target="_blank" rel="noreferrer">{__('Open Business Connect ↗', 'ai-rank-suite')}</a>
							{record.apple_url ? <Badge tone="good">{__('attached', 'ai-rank-suite')}</Badge> : <Badge tone="neutral">{__('not attached', 'ai-rank-suite')}</Badge>}
						</div>
					</div>
				</Card>
			</div>
		</div>
	);
}
