"use client";

/**
 * Upgrade Modal
 * ─────────────
 * Single shared modal, controlled by the PlanProvider. Opens via
 * PlanContext.openUpgrade({ kind, feature | creditKind | recommendedPlan }).
 *
 * Rendered once at the root (AppShell) so any deep component can
 * trigger it without plumbing callbacks. All three trigger shapes
 * render against the same frame:
 *
 *   kind: "feature"      — feature gate locked, recommend cheapest plan
 *                          containing the feature
 *   kind: "credit_limit" — user hit an AI credit / brief / keyword cap
 *   kind: "manual"       — sidebar "upgrade" button / marketing link
 */

import Link from "next/link";
import { X, Check, Sparkles, Zap, CreditCard, ArrowRight } from "lucide-react";
import { usePlanContext, PLANS, featureLabel, resolveEffectivePlan } from "@/context/plan-context";
import { recommendPlanFor, type PlanId, type FeatureKey } from "@/lib/plan-config";

const PLAN_ORDER: PlanId[] = ["growth", "professional", "agency", "agency_pro", "enterprise"];

export default function UpgradeModal() {
  const { state, upgrade, closeUpgrade } = usePlanContext();
  if (!upgrade) return null;

  const currentPlanId = state
    ? resolveEffectivePlan({ plan: state.plan, planExpiresAt: state.planExpiresAt ? new Date(state.planExpiresAt) : null })
    : null;
  const current = currentPlanId ? PLANS[currentPlanId] : null;

  // Recommended plan depends on what triggered the modal.
  let recommendedId: PlanId;
  let header: string;
  let subhead: string;
  if (upgrade.kind === "feature") {
    recommendedId = recommendPlanFor(upgrade.feature) ?? nextPaidAfter(currentPlanId);
    header = `Upgrade to unlock ${featureLabel(upgrade.feature)}`;
    subhead = `${featureLabel(upgrade.feature)} is included on the ${PLANS[recommendedId].name} plan and above.`;
  } else if (upgrade.kind === "credit_limit") {
    recommendedId = nextPaidAfter(currentPlanId);
    header = creditLimitHeader(upgrade.creditKind);
    subhead = creditLimitSubhead(upgrade.creditKind);
  } else {
    recommendedId = upgrade.recommendedPlan ?? nextPaidAfter(currentPlanId);
    header = "Upgrade your plan";
    subhead = "Pick the plan that matches how you work.";
  }

  const recommended = PLANS[recommendedId];

  // Cycle dropdown — if the user's on annual we keep them on annual,
  // otherwise we surface annual as the better deal and let them
  // flip to monthly if they really want.
  const cycle = state?.billingCycle ?? "annual";
  const currentPrice = priceOf(currentPlanId, cycle);
  const recommendedPrice = priceOf(recommendedId, cycle);
  const priceDelta = currentPrice != null && recommendedPrice != null
    ? recommendedPrice - currentPrice
    : null;

  // Usage breakdown for the "current plan" section. Only renders the
  // fields the user's plan actually caps — unlimited tiers skip them.
  const limits = state?.limits;

  return (
    <div
      className="fixed inset-0 z-[100] flex items-center justify-center bg-slate-900/70 p-4"
      onClick={closeUpgrade}
    >
      <div
        className="bg-white rounded-2xl shadow-2xl w-full max-w-2xl max-h-[90vh] flex flex-col overflow-hidden"
        onClick={(e) => e.stopPropagation()}
      >
        {/* Header */}
        <header className="flex items-start justify-between px-6 py-5 border-b border-slate-200">
          <div>
            <h2 className="text-xl font-bold text-slate-900">{header}</h2>
            <p className="text-sm text-slate-500 mt-0.5">{subhead}</p>
          </div>
          <button onClick={closeUpgrade} className="p-1.5 rounded-lg hover:bg-slate-100 text-slate-500">
            <X className="w-4 h-4" />
          </button>
        </header>

        <div className="flex-1 overflow-auto p-6 space-y-5">
          {/* Current vs recommended cards side-by-side */}
          <div className="grid grid-cols-2 gap-3">
            {/* Current */}
            <div className="rounded-xl border border-slate-200 p-4">
              <p className="text-[10px] font-bold uppercase tracking-widest text-slate-400 mb-1">Current plan</p>
              <p className="text-lg font-extrabold text-slate-900 mb-0.5">{current?.name ?? "—"}</p>
              {currentPrice != null && (
                <p className="text-xs text-slate-500">
                  ${currentPrice.toLocaleString()}/mo
                  <span className="ml-1 text-[10px] text-slate-400">({cycle})</span>
                </p>
              )}
              {state && limits && (
                <ul className="mt-3 space-y-1 text-[11px] text-slate-600">
                  {limits.maxBrands !== "unlimited" && (
                    <li>Brands: <span className="font-semibold text-slate-800">{state.usage.brandsUsed} of {limits.maxBrands}</span></li>
                  )}
                  {limits.aiCredits !== "unlimited" && (
                    <li>AI credits: <span className="font-semibold text-slate-800">{state.usage.aiCreditsUsed.toLocaleString()} of {limits.aiCredits.toLocaleString()}</span></li>
                  )}
                </ul>
              )}
            </div>

            {/* Recommended */}
            <div className="rounded-xl border-2 border-brand-300 bg-brand-50/30 p-4 relative">
              <span className="absolute top-2 right-2 text-[9px] font-bold uppercase tracking-widest bg-brand-600 text-white rounded-full px-2 py-0.5">
                Recommended
              </span>
              <p className="text-[10px] font-bold uppercase tracking-widest text-brand-600 mb-1">Upgrade to</p>
              <p className="text-lg font-extrabold text-slate-900 mb-0.5">{recommended.name}</p>
              {recommendedPrice != null ? (
                <p className="text-xs text-slate-600">
                  ${recommendedPrice.toLocaleString()}/mo
                  <span className="ml-1 text-[10px] text-slate-400">({cycle})</span>
                </p>
              ) : (
                <p className="text-xs text-slate-600">Custom pricing</p>
              )}
              {priceDelta != null && priceDelta > 0 && (
                <p className="text-[11px] text-emerald-600 font-semibold mt-1">
                  Just ${priceDelta.toLocaleString()}/mo more
                </p>
              )}
              <ul className="mt-3 space-y-1 text-[11px] text-slate-700">
                {(() => {
                  // Diff: show up to 4 features the recommended plan adds.
                  const currentFeatures = current ? new Set<string>(current.features as string[]) : new Set<string>();
                  const added = (recommended.features[0] === "*" ? ["All features"] : (recommended.features as FeatureKey[]))
                    .filter((f) => f === "*" || !currentFeatures.has(f))
                    .slice(0, 5);
                  return added.map((f) => (
                    <li key={f} className="flex items-start gap-1.5">
                      <Check className="w-3 h-3 text-emerald-500 mt-0.5 shrink-0" />
                      <span>{f === "*" ? "Everything" : featureLabel(f as FeatureKey)}</span>
                    </li>
                  ));
                })()}
              </ul>
            </div>
          </div>

          {/* Add-on alternative when the trigger is a credit/brand
              limit. For feature unlocks we don't offer an add-on;
              the feature itself isn't purchasable a-la-carte. */}
          {upgrade.kind === "credit_limit" && upgrade.creditKind === "ai" && (
            <div className="rounded-xl border border-slate-200 bg-slate-50 p-4 flex items-center gap-3">
              <div className="w-9 h-9 rounded-lg bg-amber-100 text-amber-700 flex items-center justify-center shrink-0">
                <Zap className="w-4 h-4" />
              </div>
              <div className="flex-1">
                <p className="text-sm font-bold text-slate-900">Or add 500 credits for $49</p>
                <p className="text-xs text-slate-500">One-time top-up for this billing cycle. No plan change.</p>
              </div>
              <button className="px-4 py-2 text-xs font-semibold border border-slate-200 rounded-lg bg-white hover:bg-slate-50">
                Add credits
              </button>
            </div>
          )}
          {upgrade.kind === "credit_limit" && upgrade.creditKind === "brands" && (
            <div className="rounded-xl border border-slate-200 bg-slate-50 p-4 flex items-center gap-3">
              <div className="w-9 h-9 rounded-lg bg-sky-100 text-sky-700 flex items-center justify-center shrink-0">
                <CreditCard className="w-4 h-4" />
              </div>
              <div className="flex-1">
                <p className="text-sm font-bold text-slate-900">Or add one more brand</p>
                <p className="text-xs text-slate-500">$49–$79/mo depending on your plan. No upgrade required.</p>
              </div>
              <button className="px-4 py-2 text-xs font-semibold border border-slate-200 rounded-lg bg-white hover:bg-slate-50">
                Add brand
              </button>
            </div>
          )}

          {/* Billing note */}
          {cycle === "annual" ? (
            <p className="text-[11px] text-slate-500 bg-slate-50 rounded-lg px-3 py-2">
              Annual plans bill upfront. Upgrading mid-cycle prorates the difference for the remaining days.
            </p>
          ) : (
            <p className="text-[11px] text-slate-500 bg-slate-50 rounded-lg px-3 py-2">
              Switching to annual saves up to 20% — we&apos;ll surface the annual option during checkout.
            </p>
          )}
        </div>

        {/* Footer CTAs */}
        <footer className="flex items-center justify-end gap-2 px-6 py-4 border-t border-slate-200 bg-slate-50">
          <button onClick={closeUpgrade} className="px-4 py-2 text-xs font-semibold text-slate-600">
            Cancel
          </button>
          <Link
            href="/pricing"
            onClick={closeUpgrade}
            className="inline-flex items-center gap-1 px-4 py-2 text-xs font-semibold text-slate-600 hover:text-slate-900"
          >
            Compare all plans <ArrowRight className="w-3 h-3" />
          </Link>
          {recommended.monthlyPrice != null ? (
            <Link
              href={`/pricing?plan=${recommendedId}`}
              onClick={closeUpgrade}
              className="inline-flex items-center gap-1.5 px-5 py-2 bg-brand-600 text-white text-xs font-semibold rounded-lg hover:bg-brand-700"
            >
              <Sparkles className="w-3 h-3" /> Upgrade to {recommended.name}
            </Link>
          ) : (
            <Link
              href="/pricing#enterprise"
              onClick={closeUpgrade}
              className="inline-flex items-center gap-1.5 px-5 py-2 bg-slate-900 text-white text-xs font-semibold rounded-lg hover:bg-slate-800"
            >
              Book a demo
            </Link>
          )}
        </footer>
      </div>
    </div>
  );
}

// ─── helpers ──────────────────────────────────────────────────────

function priceOf(planId: PlanId | null, cycle: "monthly" | "annual"): number | null {
  if (!planId) return null;
  const p = PLANS[planId];
  return cycle === "annual" ? p.annualMonthlyPrice : p.monthlyPrice;
}

function nextPaidAfter(planId: PlanId | null): PlanId {
  if (!planId) return "professional";
  const i = PLAN_ORDER.indexOf(planId);
  if (i < 0) return "professional";
  // Climb one step, skipping Enterprise unless nothing else is left.
  for (let j = i + 1; j < PLAN_ORDER.length; j++) {
    if (PLAN_ORDER[j] !== "enterprise") return PLAN_ORDER[j];
  }
  return "enterprise";
}

function creditLimitHeader(kind: "ai" | "briefs" | "keywords" | "brands"): string {
  switch (kind) {
    case "ai":       return "You've hit your AI credit limit";
    case "briefs":   return "You've hit your content brief limit";
    case "keywords": return "You've hit your rank tracking keyword limit";
    case "brands":   return "You've hit your brand limit";
  }
}

function creditLimitSubhead(kind: "ai" | "briefs" | "keywords" | "brands"): string {
  switch (kind) {
    case "ai":       return "AI features pause until your next billing cycle — or upgrade now for more.";
    case "briefs":   return "Brief generation resumes next cycle — or upgrade for a larger pool.";
    case "keywords": return "Add more keywords by upgrading, or remove existing ones.";
    case "brands":   return "Add more brands with an upgrade, or buy an Additional Brand add-on.";
  }
}
