import { ArrowRight, Sparkles, X } from 'lucide-react';

import { useEffect, useState } from 'react';

import { Link, usePage } from '@inertiajs/react';

import { DraftOutputTeaser } from '@/Components/Ai/DraftOutputTeaser';
import { BillingLink } from '@/Components/billing/BillingLink';
import { Button } from '@/Components/ui/button';
import { trackEvent } from '@/lib/analytics';
import {
  BYOK_LINK_CLICKED,
  BYOK_NUDGE_DEFERRED,
  UPGRADE_PROMPT_CLICKED,
  WIZARD_AI_STEP_SHOWN,
} from '@/lib/event-catalog';
import type { PageProps } from '@/types';

const BYOK_DEFERRED_KEY = 'byok_nudge_deferred';

/**
 * Sources for `BYOK_LINK_CLICKED` — match the existing source taxonomy
 * used by `UPGRADE_PROMPT_CLICKED` so the two funnels can be joined
 * downstream.
 */
type ByokLinkSource = 'byok_nudge_trial' | 'byok_nudge_free' | 'byok_only_fallback';
type PlanTier = 'free' | 'trial' | 'pro';

interface AiDraftNudgeCardProps {
  siteId: string;
  /**
   * Number of bundled AI drafts the user has remaining this month.
   * `null` means we don't know (e.g. ai_status not in shared props),
   * which the card treats as "BYOK-only mode" — see logic below.
   */
  bundledRemaining: number | null;
}

/**
 * AI draft nudge inside the post-analysis disclosure.
 *
 * Branches based on plan + remaining credits:
 *   - Has credits → "use what you have" CTA into the recommendations page.
 *   - Trial user, exhausted → upgrade-to-Pro CTA. (BYOK is hidden — see
 *     "BYOK is a Pro-only feature" below.)
 *   - Free user, exhausted → upgrade-to-Pro CTA + DraftOutputTeaser.
 *   - Pro user, exhausted, billing enabled → falls into the BYOK-only
 *     fallback branch since neither the trial nor free conditional matches.
 *     This is the right surface for a paid user out of credits: BYOK is
 *     the next step.
 *   - Billing feature flag disabled → BYOK-only fallback for everyone (no
 *     Pro path exists in this deployment).
 *
 * BYOK is a Pro-only feature. Free and trial users do not see the
 * "connect your own OpenAI key" link — BYOK is positioned as a paid-tier
 * perk rather than a free-tier escape valve. See
 * `docs/byok-pro-only.md` for the full rationale and reversal plan.
 *
 * Click instrumentation: every BYOK link / CTA fires `BYOK_LINK_CLICKED`
 * with plan tier and source. This is the first hop of the BYOK funnel;
 * downstream events (`BYOK_KEY_SAVED`, `BYOK_KEY_VALIDATED`,
 * `BYOK_FIRST_DRAFT_GENERATED`) are dispatched server-side from
 * `AnalyticsEventService` (see `EventCatalog::BYOK_FIRST_DRAFT_GENERATED`).
 *
 * The "Remind me later" defer state is stored in `localStorage`. This is
 * known polish debt (see audit polish #9). A server-side preference would
 * survive device changes; until then we accept that the nudge resurfaces
 * on a fresh device.
 *
 * Renders nothing once deferred. The mount-time `WIZARD_AI_STEP_SHOWN`
 * event still fires on every fresh render (since `<details>` always
 * renders its children) — preserving the previous "shown to user"
 * denominator.
 */
export function AiDraftNudgeCard({ siteId, bundledRemaining }: AiDraftNudgeCardProps) {
  const { trial, plan, features } = usePage<PageProps>().props;

  const [deferred, setDeferred] = useState(() => {
    try {
      return localStorage.getItem(BYOK_DEFERRED_KEY) === '1';
    } catch {
      return false;
    }
  });

  useEffect(() => {
    trackEvent(WIZARD_AI_STEP_SHOWN, { site_id: String(siteId) });
    // Intentional fire-once-on-mount: dependencies omitted by design.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const hasCredits = bundledRemaining !== null && bundledRemaining > 0;
  const isTrialUser = trial?.active === true;
  const isFreePlan = !plan && !isTrialUser;
  const isPro = !!plan && !isTrialUser;

  // Plan tier label used in analytics payloads. The three values match the
  // BYOK_LINK_CLICKED payload schema documented in event-catalog.ts.
  const planTier: PlanTier = isPro ? 'pro' : isTrialUser ? 'trial' : 'free';

  /**
   * Fire `BYOK_LINK_CLICKED` for every BYOK link / CTA click — first hop
   * of the BYOK funnel. The Link component still navigates as normal;
   * this is a tracking side effect.
   */
  const trackByokClick = (source: ByokLinkSource) => {
    trackEvent(BYOK_LINK_CLICKED, {
      site_id: String(siteId),
      plan_tier: planTier,
      source,
    });
  };

  if (deferred) return null;

  const handleDefer = () => {
    trackEvent(BYOK_NUDGE_DEFERRED, {
      site_id: String(siteId),
      plan: isTrialUser ? 'trial' : 'free',
    });
    try {
      localStorage.setItem(BYOK_DEFERRED_KEY, '1');
    } catch {
      // localStorage unavailable — ignore.
    }
    setDeferred(true);
  };

  return (
    <div className="rounded-lg border border-primary/20 bg-primary/5 p-4">
      <div className="flex items-start gap-3">
        <Sparkles className="size-5 text-primary shrink-0 mt-0.5" aria-hidden="true" />
        <div className="flex-1 min-w-0">
          <p className="text-sm font-semibold text-foreground">
            Turn a recommendation into a publish-ready draft
          </p>
          {hasCredits ? (
            <>
              <p className="text-xs text-muted-foreground mt-1">
                You have{' '}
                <span className="font-medium text-foreground">
                  {bundledRemaining} bundled AI draft{bundledRemaining !== 1 ? 's' : ''}
                </span>{' '}
                left this month — enough for {bundledRemaining} recommendation rewrite
                {bundledRemaining !== 1 ? 's' : ''}. No API key needed.
              </p>
              {/* UI-010: Button asChild for accessible semantics + consistent focus ring */}
              <Button asChild size="sm" className="mt-3">
                <Link href={route('recommendations.index', { site: siteId })}>
                  Generate Your First AI Draft
                </Link>
              </Button>
            </>
          ) : (
            <>
              {/* ACT-006: dual-path UI when bundled credits are exhausted. */}
              {isTrialUser ? (
                // Trial users: show credit context + billing CTA. BYOK is
                // hidden — the trial is the conversion moment, not an
                // opportunity to fall back to BYOK.
                <>
                  <p className="text-xs text-muted-foreground mt-1 mb-3">
                    You've used your bundled drafts for this month. Your Pro trial includes 30
                    drafts/month — upgrade to continue generating.
                  </p>
                  <Button asChild size="sm">
                    <BillingLink
                      params={{ plan: 'pro', source: 'onboarding_byok_nudge_trial' }}
                      onClick={() =>
                        trackEvent(UPGRADE_PROMPT_CLICKED, {
                          surface: 'onboarding_wizard',
                          source: 'byok_nudge_trial',
                          site_id: String(siteId),
                        })
                      }
                    >
                      Upgrade to Pro
                      <ArrowRight className="size-3.5" aria-hidden="true" />
                    </BillingLink>
                  </Button>
                </>
              ) : isFreePlan && features?.billing ? (
                // Free users: single upgrade CTA. BYOK is hidden — it's a
                // Pro-only feature.
                <>
                  <p className="text-xs text-muted-foreground mt-1 mb-3">
                    You've used all bundled drafts this month. Upgrade to Pro for 30 drafts/month.
                  </p>
                  {/* ACT-002: taste-before-commitment teaser. */}
                  <DraftOutputTeaser siteId={siteId} />
                  <Button asChild size="sm">
                    <BillingLink
                      params={{ plan: 'pro', source: 'onboarding_byok_nudge_free' }}
                      onClick={() =>
                        trackEvent(UPGRADE_PROMPT_CLICKED, {
                          surface: 'onboarding_wizard',
                          source: 'byok_nudge_free',
                          site_id: String(siteId),
                        })
                      }
                    >
                      Upgrade to Pro — 14-Day Free Trial
                      <ArrowRight className="size-3.5" aria-hidden="true" />
                    </BillingLink>
                  </Button>
                </>
              ) : (
                // BYOK-only fallback. Two cases hit this branch:
                //   1. Pro users out of bundled credits — they've already
                //      paid, so BYOK is the natural next step.
                //   2. Deployments with the billing feature flag off — there
                //      is no Pro tier, so BYOK is the only path.
                <>
                  <p className="text-xs text-muted-foreground mt-1 mb-3">
                    {bundledRemaining === 0
                      ? "You've used all bundled drafts this month. Set up your OpenAI key to keep generating."
                      : 'Connect your own OpenAI key to generate unlimited AI drafts at cost price.'}
                  </p>
                  {/* ACT-002: taste-before-commitment teaser. */}
                  <DraftOutputTeaser siteId={siteId} />
                  <Button asChild size="sm">
                    <Link
                      href={route('settings.ai')}
                      onClick={() => trackByokClick('byok_only_fallback')}
                    >
                      Unlock Full AI Drafts →
                    </Link>
                  </Button>
                </>
              )}
              <div className="mt-3 flex items-center">
                <button
                  type="button"
                  onClick={handleDefer}
                  className="inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground"
                >
                  <X className="size-3" aria-hidden="true" />
                  Remind me later
                </button>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}
