import {
	ArrowLeft,
	Loader2,
	Check,
	RotateCcw,
	FileText,
	ExternalLink,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import FlavioIcon from '@/components/ui/flavio-icon';
import { isAppPaused } from '@/api/client';
import UpgradeLock from '@/features/interventions/detail/UpgradeLock';
import { useInterventionResponse } from '@/features/interventions/useInterventionResponse';

/**
 * Reusable detail UI for the `drift` variant shared by the text-field handlers
 * (optimizetitlesingle, optimizedescsingle, and later tagline).
 *
 * Drift fires when the user changed a value Flavio had set and the scanner
 * noticed. Rather than stomping the user, Flavio asks which version to keep:
 *  - keep_current       → adopt the user's value as the new contract.
 *  - revert_to_expected → restore the value Flavio had set.
 * Both resolve the intervention (status "acknowledge"); neither is a dismiss, so
 * there is no confirmation dialog. This is a read-only comparison: nothing here
 * is editable, the user only picks a side.
 *
 * Per-handler wrappers map `metadata.drift` into `changes` and the copy.
 *
 * @param {object}   props
 * @param {string}   props.interventionId
 * @param {()=>void} [props.onBack]      Navigate back; also the success-state CTA.
 * @param {()=>void} [props.onResolved]  Fired once the intervention is resolved.
 * @param {string}   props.heading
 * @param {string}   props.subtitle
 * @param {string}  [props.pageLabel]    Which page this affects (chip under the subtitle).
 * @param {string}  [props.pageUrl]      When set, the page chip links to it (new tab).
 * @param {string}  [props.changesLabel] Small header above the list (e.g. "3 images").
 * @param {Array<{label:string,sublabel?:string,thumbnail?:string,current:string,expected:string,renderValue?:(v:string)=>React.ReactNode}>} props.changes
 * @param {string}  [props.keepLabel]
 * @param {string}  [props.revertLabel]
 * @param {string}  [props.keepDoneText]
 * @param {string}  [props.revertDoneText]
 * @param {string}  [props.emptyText]
 * @param {string}  [props.footerNote]
 */
const DriftDecision = ({
	interventionId,
	onBack,
	onResolved,
	heading,
	subtitle,
	pageLabel,
	pageUrl,
	changesLabel,
	changes = [],
	keepLabel = 'Keep the current version',
	revertLabel = "Switch to Flavio's",
	keepDoneText = "Got it. I'll keep your version from now on.",
	revertDoneText = "Done. I'll restore my version shortly.",
	emptyText = 'Empty, nothing set',
	footerNote = 'Nothing changes until you choose.',
}) => {
	const { pending, resolved, error, run } = useInterventionResponse(
		interventionId,
		{ onResolved }
	);
	// Trial ended: the intervention can't be acted on, so the action buttons are
	// swapped for the single "unlock" upgrade CTA.
	const isPaused = isAppPaused();

	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">
					{resolved === 'primary' ? 'Got it' : 'All set'}
				</h1>
				<div className="max-w-md mx-auto">
					<p className="paragraph-regular text-muted-foreground mb-0!">
						{resolved === 'primary' ? keepDoneText : revertDoneText}
					</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 renderVal = (change, value) => {
		if (!value) {
			return (
				<span className="small-regular italic text-muted-foreground/70">
					{emptyText}
				</span>
			);
		}
		return change.renderValue ? (
			change.renderValue(value)
		) : (
			<span className="paragraph-regular text-foreground break-words">
				{value}
			</span>
		);
	};

	return (
		<div className="max-w-2xl mx-auto text-center">
			<h1 className="heading-h1 mt-0! leading-tight mb-3">{heading}</h1>
			<div className="max-w-xl mx-auto mb-8">
				<p className="paragraph-regular text-muted-foreground mb-0!">
					{subtitle}
				</p>
				{pageLabel &&
					(pageUrl ? (
						<a
							href={pageUrl}
							target="_blank"
							rel="noopener noreferrer"
							className="mt-3 inline-flex items-center gap-1.5 rounded-full border border-border px-3 py-1 small-medium text-muted-foreground! hover:bg-muted/60 hover:text-foreground! transition-colors"
						>
							<FileText className="w-3.5 h-3.5" />
							{pageLabel}
							<ExternalLink className="w-3 h-3" />
						</a>
					) : (
						<div className="mt-3 inline-flex items-center gap-1.5 rounded-full border border-border px-3 py-1 small-medium text-muted-foreground">
							<FileText className="w-3.5 h-3.5" />
							{pageLabel}
						</div>
					))}
			</div>

			{changesLabel && (
				<p className="small-semibold uppercase tracking-wide text-muted-foreground text-left my-0! mb-3!">
					{changesLabel}
				</p>
			)}

			<div className="space-y-4">
				{changes.map((change, i) => (
					<div
						key={i}
						className="rounded-2xl border border-border p-6 text-left"
					>
						<div className="flex items-center gap-3 mb-4">
							{change.thumbnail && (
								<img
									src={change.thumbnail}
									alt=""
									className="w-10 h-10 rounded-md object-cover border border-border bg-muted shrink-0"
								/>
							)}
							<div className="min-w-0">
								<p
									className={`my-0! ${
										change.thumbnail
											? 'small-semibold font-mono text-foreground truncate'
											: 'small-semibold uppercase tracking-wide text-muted-foreground'
									}`}
								>
									{change.label}
								</p>
								{change.sublabel && (
									<p className="small-regular text-muted-foreground/70 my-0! mt-0.5!">
										{change.sublabel}
									</p>
								)}
							</div>
						</div>
						<div className="grid sm:grid-cols-2 gap-4">
							<div>
								<p className="small-semibold text-foreground my-0! mb-2!">
									On your site now
								</p>
								<div className="rounded-lg bg-muted/50 px-3 py-2 break-words">
									{renderVal(change, change.current)}
								</div>
							</div>
							<div>
								<p className="small-semibold text-magenta-600 my-0! mb-2!">
									Flavio&apos;s version
								</p>
								<div className="rounded-lg border border-magenta-200 bg-magenta-50 px-3 py-2 break-words">
									{renderVal(change, change.expected)}
								</div>
							</div>
						</div>
					</div>
				))}
			</div>

			<div className="flex items-center justify-center gap-3 mt-8">
				{isPaused ? (
					<UpgradeLock />
				) : (
					<>
						<Button
							onClick={() =>
								run('primary', {
									status: 'acknowledge',
									userResponse: { choice: 'keep_current' },
								})
							}
							disabled={!!pending || !!resolved}
							size="lg"
							className="bg-foreground text-background! hover:bg-foreground/90"
						>
							{pending === 'primary' ? (
								<Loader2 className="animate-spin" />
							) : (
								<Check />
							)}
							{keepLabel}
						</Button>
						<Button
							onClick={() =>
								run('secondary', {
									status: 'acknowledge',
									userResponse: {
										choice: 'revert_to_expected',
									},
								})
							}
							disabled={!!pending || !!resolved}
							size="lg"
							variant="outline"
						>
							{pending === 'secondary' ? (
								<Loader2 className="animate-spin" />
							) : (
								<RotateCcw />
							)}
							{revertLabel}
						</Button>
					</>
				)}
			</div>

			{error && (
				<p className="small-regular text-destructive mt-3 mb-0!">
					{error}
				</p>
			)}
			{footerNote && (
				<p className="small-regular text-muted-foreground mt-4 mb-0!">
					{footerNote}
				</p>
			)}
		</div>
	);
};

export default DriftDecision;
