"use client";

/**
 * <FeatureGate feature="rank_tracker">
 *   <RankTrackerPage />
 * </FeatureGate>
 *
 * Wraps a page / component. When the user's plan includes the feature,
 * children render normally. When it doesn't, a blurred preview of the
 * children renders behind a locked overlay with an Upgrade CTA that
 * opens the shared UpgradeModal.
 *
 * The "blurred preview" is a deliberate product choice: showing what
 * users can't access is a stronger upsell than hiding it. Children
 * still mount (so their data fetches run) — wrap with the `fallback`
 * prop when that's undesirable.
 */

import type { ReactNode } from "react";
import { Lock, Sparkles, ArrowRight } from "lucide-react";
import Link from "next/link";
import { useFeatureGate, featureLabel, PLANS } from "@/context/plan-context";
import type { FeatureKey } from "@/lib/plan-config";

interface Props {
  feature: FeatureKey;
  children: ReactNode;
  /** Render instead of the blurred preview when access is denied.
   *  Use this for pages where rendering the real component would
   *  hit an API the gate is meant to prevent. */
  fallback?: ReactNode;
}

export default function FeatureGate({ feature, children, fallback }: Props) {
  const { canAccess, loading, showUpgrade, recommendedPlan, currentPlan } = useFeatureGate(feature);

  // Loading state: render children normally. The server-side API
  // guard is the true enforcement line; a brief "locked-then-unlocked"
  // flash on cold load is worse UX than a brief "unlocked-then-locked"
  // flash on a user who will hit the API 403 anyway.
  if (loading || canAccess === null) return <>{children}</>;
  if (canAccess) return <>{children}</>;

  // Denied — show the overlay.
  const planName = recommendedPlan ? PLANS[recommendedPlan]?.name ?? "a higher plan" : "a higher plan";
  const label = featureLabel(feature);

  return (
    <div className="relative">
      {fallback ? (
        <div>{fallback}</div>
      ) : (
        // Blurred preview of the real content. pointer-events-none
        // stops the user from interacting with anything behind the
        // overlay; aria-hidden hides it from screen readers so the
        // upgrade CTA is the only focusable surface.
        <div className="pointer-events-none select-none blur-sm opacity-60" aria-hidden>
          {children}
        </div>
      )}
      <div className="absolute inset-0 flex items-start justify-center pt-24 px-4">
        <div className="w-full max-w-md bg-white rounded-2xl border border-slate-200 shadow-xl p-6 text-center">
          <div className="w-12 h-12 rounded-full bg-brand-50 text-brand-600 flex items-center justify-center mx-auto mb-3">
            <Lock className="w-5 h-5" />
          </div>
          <h2 className="text-lg font-bold text-slate-900 mb-1.5">
            Upgrade to unlock {label}
          </h2>
          <p className="text-sm text-slate-500 leading-relaxed mb-4">
            {label} is included on the <span className="font-semibold text-slate-700">{planName}</span> plan
            {currentPlan ? ` — you're currently on ${PLANS[currentPlan]?.name ?? currentPlan}.` : "."}
          </p>
          <div className="flex items-center gap-2 justify-center">
            <button
              onClick={showUpgrade}
              className="inline-flex items-center gap-1.5 px-5 py-2.5 bg-brand-600 text-white text-sm font-semibold rounded-xl hover:bg-brand-700 shadow-sm"
            >
              <Sparkles className="w-3.5 h-3.5" /> Upgrade Now
            </button>
            <Link
              href="/pricing"
              className="inline-flex items-center gap-1 px-4 py-2.5 text-sm font-semibold text-slate-600 hover:text-slate-900"
            >
              Compare plans <ArrowRight className="w-3 h-3" />
            </Link>
          </div>
        </div>
      </div>
    </div>
  );
}
