import {
	ExternalLink,
	AlertTriangle,
	ArrowLeft,
	Check,
	Loader2,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
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 `no500` / `server_errors` intervention (type `help`).
 *
 * A 500 means the server crashed while rendering the page, so the page won't
 * load at all. The cause lives in the site's code or hosting (a plugin/theme
 * conflict, a recent change, a server limit), which Flavio can't change on its
 * own. The steps are instructional. The scan re-checks the URLs on its next
 * cycle and the heartbeat auto-resolves once they respond again, but that can
 * lag, so we also give the user an explicit "I've already done this" action that
 * acknowledges the intervention (`status: 'acknowledge'`) and clears it now.
 *
 * Defensive on metadata: the base contract only guarantees `variant`, so we
 * normalise `pending_items` and fall back to `pending_count` for the headline.
 */

/** What the user can do to clear the 500s (the fix lives on their side). */
const STEPS = [
	{
		text: 'These errors usually follow a recent change.',
		hint: 'A plugin update, a new plugin, or an edit. Undoing the latest one often clears it.',
	},
	{
		text: 'Still down? Contact your hosting provider.',
		hint: "They can read the server log and tell you exactly what failed.",
	},
	{ text: "Once the pages load again, I'll pick up where I left off." },
];

/** Normalise a scanner item (string or object) to a single URL string. */
const itemUrl = (item) =>
	typeof item === 'string'
		? item
		: item?.url || item?.path || item?.loc || '';

const ServerErrors = ({
	intervention = {},
	interventionId,
	onBack,
	onResolved,
}) => {
	const metadata = intervention.metadata || {};
	const items = (
		Array.isArray(metadata.pending_items) ? metadata.pending_items : []
	)
		.map(itemUrl)
		.filter(Boolean);

	const count = Number(metadata.pending_count) || items.length;
	const plural = count === 1 ? '' : 's';

	// 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 { pending, resolved, error, run } = useInterventionResponse(
		interventionId,
		{ onResolved }
	);

	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 re-check those pages and pick things up from
						there.
					</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 MAX_SHOWN = 6;
	const shown = items.slice(0, MAX_SHOWN);
	const remaining = Math.max(items.length - shown.length, 0);

	return (
		<div className="max-w-2xl mx-auto text-center">
			<h1 className="heading-h1 mt-0! leading-tight mb-3">
				{count === 1
					? 'A page is returning an error'
					: 'Some pages are returning errors'}
			</h1>
			<div className="max-w-xl mx-auto mb-8">
				<p className="paragraph-regular text-muted-foreground mb-0!">
					These pages hit a server error and won't load. The cause is in
					your site's setup or hosting, which I can't change on my own,
					but it's usually quick to fix.
				</p>
			</div>

			{shown.length > 0 && (
				<div className="rounded-2xl border border-border p-6 text-left">
					<h2 className="heading-h4 mt-0! mb-4">
						Affected page{plural}
					</h2>
					<ul className="space-y-3">
						{shown.map((url) => (
							<li key={url} className="flex items-center gap-3">
								<span className="shrink-0 rounded-md border border-red-200 bg-red-50 px-2 py-0.5 small-medium text-red-700">
									500
								</span>
								<a
									href={url}
									target="_blank"
									rel="noopener noreferrer"
									className="inline-flex items-center gap-1.5 min-w-0 small-regular text-foreground! hover:underline"
								>
									<span className="truncate">{url}</span>
									<ExternalLink className="w-3.5 h-3.5 shrink-0 text-muted-foreground" />
								</a>
							</li>
						))}
					</ul>
					{remaining > 0 && (
						<p className="small-regular text-muted-foreground mt-3 mb-0!">
							and {remaining} more
						</p>
					)}
				</div>
			)}

			<div className="rounded-2xl border border-border p-8 mt-4">
				<h2 className="heading-h4 mt-0! mb-6">How we fix this</h2>
				<div className="space-y-5 text-left mt-4">
					{STEPS.map((step, index) => (
						<div key={step.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>
							<div>
								<p className="paragraph-regular text-foreground my-0! pt-0.5">
									{step.text}
								</p>
								{step.hint && (
									<p className="small-regular text-muted-foreground mt-1! mb-0!">
										{step.hint}
									</p>
								)}
							</div>
						</div>
					))}
				</div>
			</div>

			<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">
					Search engines can't index a page that won't load, and repeated
					errors make them crawl your site less often.
				</span>
			</div>

			{isPaused ? (
				<div className="mt-8">
					<UpgradeLock />
				</div>
			) : (
				/* Already-done escape hatch: acknowledge so it clears now, without
				    waiting for the scan to re-check the pages. */
				<div className="mt-8">
					<p className="small-regular text-muted-foreground my-0!">
						Already sorted this out? Let me know and I'll take it from
						here.
					</p>
					<Button
						onClick={() =>
							run('primary', {
								status: 'acknowledge',
								userResponse: { choice: 'already_done' },
							})
						}
						disabled={!!pending || !!resolved}
						variant="outline"
						size="lg"
						className="mt-4"
					>
						{pending === 'primary' ? (
							<Loader2 className="animate-spin" />
						) : (
							<Check />
						)}
						I've already done this
					</Button>

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

export default ServerErrors;
