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

import { useEffect, useRef, useState } from 'react';

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

import { Alert, AlertDescription } from '@/Components/ui/alert';
import { Button } from '@/Components/ui/button';
import { trackEvent } from '@/lib/analytics';
import { PQL_SIGNAL, PQL_THRESHOLD_REACHED, UPGRADE_PROMPT_CLICKED } from '@/lib/event-catalog';
import type { PageProps } from '@/types';

interface UpgradePromptProps {
  /**
   * Type of limit being approached/reached
   */
  limitType: 'sites' | 'drafts' | 'pages' | 'analysis' | 'briefs';

  /**
   * Current usage count
   */
  currentUsage: number;

  /**
   * Maximum allowed under current plan
   */
  maxUsage: number;

  /**
   * Maximum allowed under Pro plan
   */
  proLimit: number | string;

  /**
   * Whether the alert can be dismissed
   */
  dismissible?: boolean;

  /**
   * Custom message override
   */
  customMessage?: string;

  /**
   * Custom CTA button label override
   */
  ctaLabel?: string;

  /**
   * The next upgrade tier name (e.g. 'Pro', 'Team'). Defaults to 'Pro'.
   * Pass 'Team' for Pro users approaching Team-tier limits.
   */
  nextTier?: string;

  /**
   * Label for the current plan tier shown in limit messages.
   * Defaults to 'free tier'. Pass 'Pro' for paid subscribers.
   */
  currentTierLabel?: string;

  /**
   * The current user's lead score tier ('cold'|'warm'|'hot'|'pql').
   * When 'pql', a personalized high-intent banner is shown instead of the
   * generic upgrade prompt. Pass from page props when available.
   */
  leadScoreTier?: 'cold' | 'warm' | 'hot' | 'pql';
}

export function UpgradePrompt({
  limitType,
  currentUsage,
  maxUsage,
  proLimit,
  dismissible = true,
  customMessage,
  ctaLabel,
  nextTier = 'Pro',
  currentTierLabel = 'free tier',
  leadScoreTier,
}: UpgradePromptProps) {
  const { features } = usePage<PageProps>().props;

  const isAtLimit = maxUsage > 0 && currentUsage >= maxUsage;
  const isNearLimit = maxUsage > 0 && currentUsage >= maxUsage * 0.8;
  // Scope the dismissal key to threshold level so the "at limit" state
  // always shows fresh even if the user dismissed the "near limit" warning.
  const thresholdLevel = isAtLimit ? 'at-limit' : 'near-limit';
  const storageKey = `upgrade-prompt-dismissed-${limitType}-${thresholdLevel}`;

  // CRO-005: When at limit, reduce reshow to 1 day to keep upgrade path visible
  const DISMISS_RESHOW_DAYS = isAtLimit ? 1 : 7;

  const [dismissed, setDismissed] = useState(() => {
    // CRO-005: Never dismiss when hard-blocked at limit
    if (isAtLimit) return false;
    if (typeof window === 'undefined') return false;
    const dismissedAt = localStorage.getItem(storageKey);
    if (!dismissedAt) return false;
    // Re-show after DISMISS_RESHOW_DAYS days
    const dismissedTime = parseInt(dismissedAt, 10);
    if (isNaN(dismissedTime)) return false;
    const daysSinceDismissed = (Date.now() - dismissedTime) / (1000 * 60 * 60 * 24);
    return daysSinceDismissed < DISMISS_RESHOW_DAYS;
  });

  const handleDismiss = () => {
    setDismissed(true);
    if (typeof window !== 'undefined') {
      localStorage.setItem(storageKey, String(Date.now()));
    }
  };

  // Fire PQL_THRESHOLD_REACHED at most once per component lifetime (on mount).
  // The server-side PqlThresholdReachedJob is the authoritative source for this event;
  // this client-side fire tracks which in-app surface triggered the PQL prompt so PostHog
  // cohort analysis can attribute the touchpoint. Using a mount-only effect (empty dep array)
  // prevents the event from re-firing on every dep change for persistently-PQL users.
  const pqlEventFired = useRef(false);
  useEffect(() => {
    if (pqlEventFired.current || leadScoreTier !== 'pql' || maxUsage <= 0) return;
    pqlEventFired.current = true;
    trackEvent(PQL_THRESHOLD_REACHED, {
      surface: typeof window !== 'undefined' ? window.location.pathname : '',
      limit_type: limitType,
      utilization_pct: maxUsage > 0 ? Math.round((currentUsage / maxUsage) * 100) : 0,
    });
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []); // mount-only — values captured at initial render are intentional

  // Fire PQL signal whenever near/at limit state or usage changes.
  // Also records server-side via POST /api/lead-score/pql-signal so lead_score is updated
  // regardless of client-side consent state (GDPR legitimate interest — see Privacy Policy §Analytics).
  useEffect(() => {
    if (maxUsage <= 0 || (!isAtLimit && !isNearLimit) || dismissed) return;
    const utilizationPct = maxUsage > 0 ? Math.round((currentUsage / maxUsage) * 100) : 0;
    const payload = {
      limit_type: limitType,
      utilization_pct: utilizationPct,
      is_at_limit: isAtLimit,
    };

    // Client-side: consent-gated PostHog event
    trackEvent(PQL_SIGNAL, payload);

    // Server-side: consent-independent lead score update
    fetch('/api/lead-score/pql-signal', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
      },
      body: JSON.stringify(payload),
    }).catch(() => {
      // Best-effort — do not surface fetch errors to the user
    });

    // Also set as a PostHog person property so cohorts can be built without relying on event history.
    // Use $set via capture (no distinct_id needed — PostHog uses the current session's identity).
    if (typeof window !== 'undefined' && window.posthog?.capture) {
      window.posthog.capture('$set', {
        $set: {
          [`${limitType}_utilization_pct`]: utilizationPct,
          [`${limitType}_at_limit`]: isAtLimit,
        },
      });
    }
  }, [limitType, isAtLimit, isNearLimit, dismissed, maxUsage, currentUsage, leadScoreTier]);

  // Disabled/unlimited feature, not near/at limit, or already dismissed
  if (maxUsage <= 0 || (!isAtLimit && !isNearLimit) || dismissed) return null;

  const getLimitLabel = (type: string): string => {
    switch (type) {
      case 'sites':
        return 'site';
      case 'drafts':
        return 'AI draft';
      case 'pages':
        return 'page';
      case 'analysis':
        return 'analysis';
      case 'briefs':
        return 'content brief';
      default:
        return 'resource';
    }
  };

  const getDefaultMessage = (): string => {
    const label = getLimitLabel(limitType);

    if (isAtLimit) {
      return `You've reached your ${currentTierLabel} limit of ${maxUsage} ${maxUsage === 1 ? label : `${label}s`}.`;
    }

    return `You're using ${currentUsage} of ${maxUsage} ${maxUsage === 1 ? label : `${label}s`} in your ${currentTierLabel}.`;
  };

  const getProLimitText = (): string => {
    if (typeof proLimit === 'string') return proLimit;
    const label = getLimitLabel(limitType);
    return `${proLimit} ${proLimit === 1 ? label : `${label}s`}`;
  };

  const getSpecificBenefitMessage = (): string => {
    switch (limitType) {
      case 'drafts':
        return `${proLimit} drafts/month, batch generation, and direct WordPress publishing.`;
      case 'sites':
        return `Manage up to ${proLimit} WordPress sites with shared analysis and ROI tracking.`;
      case 'briefs':
        return 'Unlimited content briefs with AI-generated outlines and export.';
      case 'pages':
        return 'Analyze your full site — unlimited pages per analysis run.';
      default:
        return `Upgrade to ${nextTier} for ${getProLimitText()} and unlock all features.`;
    }
  };

  const getDefaultCtaLabel = (): string => {
    switch (limitType) {
      case 'drafts':
        return `Generate More with ${nextTier} — ${proLimit} drafts/mo`;
      case 'sites':
        return `Manage More Sites with ${nextTier}`;
      case 'briefs':
        return `Scale Your Content with ${nextTier}`;
      case 'pages':
        return `Analyze Your Full Site with ${nextTier}`;
      default:
        return `Upgrade to ${nextTier}`;
    }
  };

  const message = customMessage || getDefaultMessage();
  const billingEnabled = features.billing;
  const isPql = leadScoreTier === 'pql';

  // PQL variant: personalized high-intent banner for users who crossed the PQL threshold
  if (isPql && billingEnabled) {
    return (
      <Alert className="border-amber-500/40 bg-amber-50/60 dark:bg-amber-950/20 relative">
        <TrendingUp className="h-4 w-4 text-amber-600 dark:text-amber-400" />
        {dismissible && !isAtLimit && (
          <button
            onClick={handleDismiss}
            className="absolute top-3 right-3 p-1 rounded-sm opacity-70 hover:opacity-100 transition-opacity"
            aria-label="Dismiss"
          >
            <X className="h-4 w-4" />
          </button>
        )}
        <AlertDescription className="pr-8">
          <div className="space-y-2">
            <div>
              <p className="font-semibold text-amber-700 dark:text-amber-300">
                You're hitting limits — that means it's working.
              </p>
              <p className="text-sm text-muted-foreground mt-1">
                {message} Upgrade to {nextTier} and keep the momentum going.
              </p>
            </div>
            <div className="flex flex-wrap gap-2 mt-2">
              <Link
                href={route('billing.plans', { utm_source: 'pql_banner', utm_campaign: 'pql_conversion' })}
                onClick={() =>
                  trackEvent(UPGRADE_PROMPT_CLICKED, {
                    limit_type: limitType,
                    surface: typeof window !== 'undefined' ? window.location.pathname : '',
                    variant: 'pql',
                  })
                }
              >
                <Button size="sm" className="bg-amber-600 hover:bg-amber-700 text-white border-0">
                  {ctaLabel ?? `Upgrade to ${nextTier}`}
                  <ArrowRight className="h-4 w-4 ml-2" />
                </Button>
              </Link>
              <Link
                href={route('billing.plans', { utm_source: 'pql_banner_demo', utm_campaign: 'pql_conversion' })}
                onClick={() =>
                  trackEvent(UPGRADE_PROMPT_CLICKED, {
                    limit_type: limitType,
                    surface: typeof window !== 'undefined' ? window.location.pathname : '',
                    variant: 'pql_demo',
                  })
                }
              >
                <Button size="sm" variant="outline" className="border-amber-500/50 text-amber-700 dark:text-amber-300 hover:bg-amber-50 dark:hover:bg-amber-950/40">
                  <Calendar className="h-4 w-4 mr-2" />
                  See personalised plan
                </Button>
              </Link>
            </div>
          </div>
        </AlertDescription>
      </Alert>
    );
  }

  return (
    <Alert className="border-primary/30 bg-primary/10 relative">
      <Sparkles className="h-4 w-4 text-primary" />
      {dismissible && !isAtLimit && (
        <button
          onClick={handleDismiss}
          className="absolute top-3 right-3 p-1 rounded-sm opacity-70 hover:opacity-100 transition-opacity"
          aria-label="Dismiss"
        >
          <X className="h-4 w-4" />
        </button>
      )}
      <AlertDescription className="pr-8">
        <div className="space-y-2">
          <div className="flex items-start justify-between gap-4">
            <div>
              <p className="font-medium text-primary">{message}</p>
              <p className="text-sm text-muted-foreground mt-1">
                {getSpecificBenefitMessage()}
              </p>
            </div>
          </div>
          {billingEnabled ? (
            <Link
              href={route('billing.plans')}
              onClick={() =>
                trackEvent(UPGRADE_PROMPT_CLICKED, {
                  limit_type: limitType,
                  surface: typeof window !== 'undefined' ? window.location.pathname : '',
                })
              }
            >
              <Button size="sm" className="mt-2">
                {ctaLabel ?? getDefaultCtaLabel()}
                <ArrowRight className="h-4 w-4 ml-2" />
              </Button>
            </Link>
          ) : (
            <p className="text-xs text-muted-foreground mt-2">
              Contact support to upgrade your account.
            </p>
          )}
        </div>
      </AlertDescription>
    </Alert>
  );
}
