import { useState } from 'react';
import {
	AlertTriangle,
	ArrowLeft,
	ArrowRight,
	Check,
	ExternalLink,
	Loader2,
	MapPin,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import FlavioIcon from '@/components/ui/flavio-icon';
import { getWordPressConfig, isAppPaused, post } from '@/api/client';
import { useInterventionResponse } from '@/features/interventions/useInterventionResponse';
import UpgradeLock from '@/features/interventions/detail/UpgradeLock';
import { logError } from '@/errors/logger';

const GOOGLE_BUSINESS_URL = 'https://business.google.com/';

const STEPS = [
	'Open your Business Profile in Google.',
	'Go to Edit profile, then Business information, then Location.',
	'Change the address so it matches your profile, and save.',
	'Google can take a while to publish the change, and may ask you to verify the new address.',
];

/**
 * Detail for the `gbpaddress` / `fix_address` intervention (type `selection`,
 * class `required`).
 *
 * The address in the Flavio profile and the one published on the Google
 * Business Profile listing disagree. Flavio can rewrite the listing's
 * description but never its address — only the owner can, in Google — so it
 * stops updating the listing and asks which address is the right one.
 *
 * Two outcomes, both acknowledgements (a dismissal would hide the whole task):
 *  - `address_updated`  — the profile is right and the user fixed Google. The
 *    executor re-reads the listing to confirm before carrying on.
 *  - `use_gbp_address`  — Google is right, so we PATCH the profile with the
 *    listing address FIRST and only acknowledge if that write succeeded. Doing
 *    it the other way round would have the executor re-read the old profile
 *    address and re-open this card.
 *
 * Contract metadata: `profile_address`, `gbp_address`, `profile_locality?`,
 * `gbp_locality?`, `location_name`, `reason`, `options[]`. Rendered
 * defensively: any missing field degrades to generic copy.
 */
const FixGbpAddress = ({
	intervention = {},
	interventionId,
	onBack,
	onResolved,
}) => {
	const m = intervention.metadata || {};
	const profileAddress = m.profile_address || '';
	const gbpAddress = m.gbp_address || '';

	const config = getWordPressConfig();
	// Trial ended: the intervention can't be acted on, so its action buttons are
	// swapped for the single "unlock" upgrade CTA.
	const isPaused = isAppPaused();

	const [savingProfile, setSavingProfile] = useState(false);
	const [profileError, setProfileError] = useState(null);

	const { pending, resolved, error, run } = useInterventionResponse(
		interventionId,
		{ onResolved }
	);

	// "Google is right": persist the listing address as the profile address,
	// then acknowledge. `locationComplete` is cleared on purpose: leaving the
	// old Google Place attached would keep its stale coordinates around.
	const adoptGoogleAddress = async () => {
		if (!gbpAddress) return;
		setProfileError(null);
		setSavingProfile(true);
		try {
			await post(config.endpoints.businessInfo, {
				location: gbpAddress,
				locationComplete: null,
			});
		} catch (err) {
			setProfileError(
				"I couldn't update your profile just now. Please try again."
			);
			logError(err, {
				action: 'adopt_gbp_address',
				component: 'FixGbpAddress',
			});
			return;
		} finally {
			setSavingProfile(false);
		}

		run('secondary', {
			status: 'acknowledge',
			userResponse: { choice: 'use_gbp_address', address: gbpAddress },
		});
	};

	if (resolved) {
		const adopted = resolved === 'secondary';
		return (
			<div className="max-w-2xl mx-auto text-center">
				<FlavioIcon className="w-12 h-12 mx-auto mb-4" />
				<h1 className="heading-h2 mt-0! leading-tight mb-3">
					{adopted ? 'Profile updated' : 'Got it'}
				</h1>
				<div className="max-w-md mx-auto">
					<p className="paragraph-regular text-muted-foreground mb-0!">
						{adopted
							? "I've saved the address from your Google listing, and I'll work from it across your site from now on."
							: "Thanks. I'll check your Google listing, and pick things up as soon as it shows the new address."}
					</p>
				</div>
				{onBack && (
					<Button
						onClick={onBack}
						size="lg"
						className="mt-6 bg-foreground text-background! hover:bg-foreground/90"
					>
						<ArrowLeft />
						Back to your list
					</Button>
				)}
			</div>
		);
	}

	const busy = !!pending || savingProfile || !!resolved;

	return (
		<div className="max-w-2xl mx-auto text-center">
			<span className="inline-flex items-center justify-center w-12 h-12 rounded-full bg-amber-50 text-amber-500 mb-4">
				<MapPin className="w-6 h-6" />
			</span>
			<h1 className="heading-h1 mt-0! leading-tight mb-3">
				Your Google listing shows a different address
			</h1>
			<div className="max-w-xl mx-auto mb-8">
				<p className="paragraph-regular text-muted-foreground mb-0!">
					I can rewrite what your Google listing says about your
					business, but I can&apos;t change the address on it. Only
					you can do that, from Google. So before I touch your
					listing, let&apos;s agree on where you are.
				</p>
			</div>

			<div className="rounded-2xl border border-border p-8">
				<div className="grid sm:grid-cols-2 gap-4">
					<div>
						<p className="small-semibold text-foreground my-0! mb-2!">
							In your profile
						</p>
						<div className="rounded-lg bg-muted/50 px-3 py-2 break-words text-left paragraph-regular">
							{profileAddress || 'No address yet'}
						</div>
					</div>
					<div>
						<p className="small-semibold text-foreground my-0! mb-2!">
							On your Google listing
						</p>
						<div className="rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 break-words text-left paragraph-regular">
							{gbpAddress || 'No address published'}
						</div>
					</div>
				</div>
			</div>

			{!isPaused && (
				<>
					<div className="rounded-2xl border border-border p-8 mt-6">
						<h2 className="heading-h4 mt-0! mb-6">
							If your profile is the right one
						</h2>
						<div className="space-y-5 text-left mt-4">
							{STEPS.map((text, index) => (
								<div
									key={text}
									className="flex items-start gap-4"
								>
									<span className="flex items-center justify-center w-8 h-8 rounded-full border border-border text-muted-foreground small-semibold shrink-0">
										{index + 1}
									</span>
									<p className="paragraph-regular text-foreground my-0! pt-0.5">
										{text}
									</p>
								</div>
							))}
						</div>

						<div className="mt-6 flex flex-col sm:flex-row gap-3">
							<Button
								asChild
								variant="secondary"
								size="lg"
								className="flex-1 border border-neutral-300"
							>
								<a
									href={GOOGLE_BUSINESS_URL}
									target="_blank"
									rel="noopener noreferrer"
								>
									Open Google Business Profile
									<ExternalLink />
								</a>
							</Button>
							<Button
								onClick={() =>
									run('primary', {
										status: 'acknowledge',
										userResponse: {
											choice: 'address_updated',
										},
									})
								}
								disabled={busy}
								size="lg"
								className="flex-1 bg-foreground text-background! hover:bg-foreground/90"
							>
								{pending === 'primary' ? (
									<Loader2 className="animate-spin" />
								) : (
									<Check />
								)}
								I&apos;ve updated it in Google
							</Button>
						</div>
					</div>

					{gbpAddress && (
						<div className="rounded-2xl border border-border p-8 mt-6 text-left">
							<h2 className="heading-h4 mt-0! mb-3">
								Or is Google the right one?
							</h2>
							<p className="paragraph-regular text-muted-foreground mb-6!">
								If you&apos;ve moved and your listing is already
								up to date, I&apos;ll save that address as yours
								and work from it everywhere else: your contact
								page, your business details for search engines,
								and the pages about your area.
							</p>
							<Button
								onClick={adoptGoogleAddress}
								disabled={busy}
								variant="outline"
								size="lg"
							>
								{pending === 'secondary' || savingProfile ? (
									<Loader2 className="animate-spin" />
								) : (
									<ArrowRight />
								)}
								Use the address from Google
							</Button>
							{profileError && (
								<p className="small-regular text-destructive mt-3 mb-0!">
									{profileError}
								</p>
							)}
						</div>
					)}

					{error && (
						<p className="small-regular text-destructive mt-3 mb-0!">
							{error}
						</p>
					)}

					<div className="max-w-xl mx-auto mt-6 flex items-start justify-center gap-2 small-regular text-muted-foreground">
						<AlertTriangle className="w-4 h-4 shrink-0 mt-0.5" />
						<span className="text-left">
							Everything else on your site already uses the
							address in your profile. It&apos;s only your Google
							listing that&apos;s waiting on this.
						</span>
					</div>
				</>
			)}

			{isPaused && (
				<div className="mt-8">
					<UpgradeLock />
				</div>
			)}
		</div>
	);
};

export default FixGbpAddress;
