import { useState } from 'react';
import {
	ArrowLeft,
	Check,
	Loader2,
	MapPin,
	Phone,
	Mail,
	Sparkles,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { TextInput } from '@/components/ui/text-input';
import FlavioIcon from '@/components/ui/flavio-icon';
import { isAppPaused } from '@/api/client';
import { useInterventionResponse } from '@/features/interventions/useInterventionResponse';
import UpgradeLock from '@/features/interventions/detail/UpgradeLock';

/**
 * Detail for the `request_contact_data` variant (type `request_data`).
 *
 * Three handlers (`checknap`, `existcontact`, `structureddatasingle`) open this
 * same intervention deduped under `tag=contact`: phase 1 collects the business
 * contact info every one of them needs before it can act. We render a single
 * shared card with three fields and submit a partial `contact_data` carrying
 * whichever values the user filled.
 *
 * Contract metadata: `contact_data:SerializedContactData` (prefill) and
 * `needed_fields:string[]` (which fields the originating handler can't proceed
 * without). userResponse: `{ contact_data: { address?, phone?, email?, … } }` —
 * only non-empty fields travel, the executor falls back to the prefill /
 * business_info otherwise.
 *
 * Per product, the form only asks for address + phone + email (no opening
 * hours, no business name). Email is always optional. `address` and `location`
 * in needed_fields both map to the address field, following the historical
 * `business_info.location ← contact_data.address` rename convention documented
 * in the contract.
 *
 * No options on this variant: the user fills the form or ignores the card.
 * Submit goes as `acknowledge`; no dismiss path here.
 */

/** A labeled input with a leading icon, optional "· optional" hint and inline error. */
const Field = ({
	label,
	optional = false,
	icon: Icon,
	value,
	onChange,
	placeholder,
	type = 'text',
	error = false,
	hint = '',
	autoComplete,
	inputMode,
}) => (
	<label className="block">
		<span className="block mb-2">
			<span className="small-semibold text-foreground">{label}</span>
			{optional && (
				<span className="small-regular text-muted-foreground/70 ml-1">
					· optional
				</span>
			)}
		</span>
		<div className="relative">
			{Icon && (
				<Icon className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground/60 pointer-events-none" />
			)}
			<TextInput
				type={type}
				value={value}
				onChange={(e) => onChange(e.target.value)}
				placeholder={placeholder}
				error={error}
				autoComplete={autoComplete}
				inputMode={inputMode}
				className={Icon ? 'pl-9!' : ''}
			/>
		</div>
		{hint && (
			<p className="small-regular text-destructive mt-1 mb-0!">{hint}</p>
		)}
	</label>
);

const ContactDetails = ({
	intervention = {},
	interventionId,
	onBack,
	onResolved,
}) => {
	const m = intervention.metadata || {};
	const prefill = m.contact_data || {};
	const needed = Array.isArray(m.needed_fields) ? m.needed_fields : [];

	// `address` and `location` are aliased into the same form field; see the
	// rename convention in the contract doc.
	const addressRequired =
		needed.includes('address') || needed.includes('location');
	const phoneRequired = needed.includes('phone');

	// 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 [address, setAddress] = useState(prefill.address || '');
	const [phone, setPhone] = useState(prefill.phone || '');
	const [email, setEmail] = useState(prefill.email || '');

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

	const trimmedEmail = email.trim();
	// Only validate format when the user actually entered something; empty +
	// optional is fine. Keep it loose: a stricter regex shouldn't reject real
	// addresses our backend accepts.
	const emailFormatOk =
		!trimmedEmail || /^\S+@\S+\.\S+$/.test(trimmedEmail);

	const addressOk = !addressRequired || address.trim().length > 0;
	const phoneOk = !phoneRequired || phone.trim().length > 0;
	const canSave =
		addressOk && phoneOk && emailFormatOk && !pending && !resolved;

	const save = () => {
		const contactData = {};
		const a = address.trim();
		const p = phone.trim();
		const e = trimmedEmail;
		if (a) contactData.address = a;
		if (p) contactData.phone = p;
		if (e) contactData.email = e;
		run('primary', {
			status: 'acknowledge',
			userResponse: { contact_data: contactData },
		});
	};

	if (resolved) {
		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">Got it</h1>
				<div className="max-w-md mx-auto">
					<p className="paragraph-regular text-muted-foreground mb-0!">
						Thanks. I'll add these to your site shortly.
					</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>
		);
	}

	return (
		<div className="max-w-2xl mx-auto">
			<div className="text-center">
				<h1 className="heading-h1 mt-0! leading-tight mb-3">
					Add your business contact details
				</h1>
				<div className="max-w-xl mx-auto mb-8">
					<p className="paragraph-regular text-muted-foreground mb-0!">
						Once I have these, I'll add them everywhere they should
						appear: contact page, schema markup, the works.
					</p>
				</div>
			</div>

			<div className="rounded-2xl border border-border p-6">
				<div className="space-y-5">
					<Field
						label="Business address"
						icon={MapPin}
						value={address}
						onChange={setAddress}
						placeholder="e.g. 1600 Amphitheatre Parkway, Mountain View, CA 94043"
						error={!addressOk && address.length === 0}
						autoComplete="street-address"
					/>
					<Field
						label="Public phone"
						icon={Phone}
						type="tel"
						inputMode="tel"
						value={phone}
						onChange={setPhone}
						placeholder="+1 (555) 123 4567"
						error={!phoneOk && phone.length === 0}
						autoComplete="tel"
					/>
					<Field
						label="Public email"
						optional
						icon={Mail}
						type="email"
						inputMode="email"
						value={email}
						onChange={setEmail}
						placeholder="hello@acme.com"
						error={!emailFormatOk}
						hint={
							!emailFormatOk
								? "That doesn't look like a valid email."
								: ''
						}
						autoComplete="email"
					/>
				</div>

				<div className="mt-5 flex items-start gap-2 rounded-xl border border-magenta-200 bg-magenta-50 p-3 small-regular text-magenta-700">
					<Sparkles className="w-4 h-4 shrink-0 mt-0.5 text-magenta-500" />
					<span>
						I'll only show these where they help, never in places
						visitors won't expect.
					</span>
				</div>
			</div>

			<div className="flex items-center justify-center gap-3 mt-8">
				{isPaused ? (
					<UpgradeLock />
				) : (
					<Button
						onClick={save}
						disabled={!canSave}
						size="lg"
						className="bg-foreground text-background! hover:bg-foreground/90"
					>
						{pending === 'primary' ? (
							<Loader2 className="animate-spin" />
						) : (
							<Check />
						)}
						Approve and publish
					</Button>
				)}
			</div>

			{!isPaused && (error || !canSave) && (
				<p
					className={`small-regular text-center mt-3 mb-0! ${
						error ? 'text-destructive' : 'text-muted-foreground'
					}`}
				>
					{error ||
						(!emailFormatOk
							? 'Fix the email format before saving.'
							: !addressOk && !phoneOk
								? 'Add an address and a phone to save.'
								: !addressOk
									? 'Add an address to save.'
									: !phoneOk
										? 'Add a phone to save.'
										: '')}
				</p>
			)}
			<p className="small-regular text-muted-foreground text-center mt-4 mb-0!">
				I'll use these to update your site.
			</p>
		</div>
	);
};

export default ContactDetails;
