import React from 'react';
import { clsx } from 'clsx';
import { Lock, Check, X, Zap, Crown, Building2 } from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/Card';
import {
  Button,
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from '@/components/ui';
import { useSubscription } from '@/contexts/SubscriptionContext';
import { SubscriptionFeatureFlag, SUBSCRIPTION_PLANS, formatPrice } from '@/types/subscription';
import { useNavigate } from 'react-router-dom';

export interface PaywallProps {
  feature: SubscriptionFeatureFlag | SubscriptionFeatureFlag[];
  title?: string;
  description?: string;
  children?: React.ReactNode;
  showUpgradeButton?: boolean;
  requiredPlan?: 'basic' | 'professional' | 'enterprise';
  className?: string;
}

const featureIcons: Record<string, React.ReactNode> = {
  unlimited_organizations: <Building2 className="h-5 w-5" />,
  advanced_analytics: <Zap className="h-5 w-5" />,
  api_access: <Zap className="h-5 w-5" />,
  custom_domain: <Crown className="h-5 w-5" />,
  sso: <Crown className="h-5 w-5" />,
  priority_support: <Crown className="h-5 w-5" />,
  dedicated_support: <Crown className="h-5 w-5" />,
  team_collaboration: <Building2 className="h-5 w-5" />,
  white_label: <Crown className="h-5 w-5" />,
};

/**
 * Paywall component that blocks access to premium features
 */
export const Paywall = ({
  feature,
  title,
  description,
  children,
  showUpgradeButton = true,
  requiredPlan,
  className,
}: PaywallProps) => {
  const { canAccessFeature, subscription } = useSubscription();
  const navigate = useNavigate();
  const [showUpgradeDialog, setShowUpgradeDialog] = React.useState(false);

  const features = Array.isArray(feature) ? feature : [feature];
  const hasAccess = features.every((f) => canAccessFeature(f));

  if (hasAccess) {
    return <>{children}</>;
  }

  const featureName = features.length === 1 ? features[0].replace(/_/g, ' ') : 'premium features';
  const displayTitle = title || `Upgrade to Access ${featureName}`;
  const displayDescription =
    description ||
    `This feature is available in our premium plans. Upgrade your subscription to unlock ${featureName}.`;

  // Determine minimum required plan
  const currentPlan = subscription?.plan || 'free';
  const plans = ['free', 'basic', 'professional', 'enterprise'] as const;
  const currentPlanIndex = plans.indexOf(currentPlan);
  const nextPlan =
    requiredPlan ||
    (currentPlanIndex < plans.length - 1 ? plans[currentPlanIndex + 1] : 'professional');

  const handleUpgrade = () => {
    setShowUpgradeDialog(true);
  };

  return (
    <>
      <div
        className={clsx(
          'relative rounded-lg border-2 border-dashed border-muted-foreground/30 bg-muted/20 p-8',
          'flex flex-col items-center justify-center text-center',
          className
        )}
      >
        <div className="mb-4 rounded-full bg-muted p-3">
          <Lock className="h-8 w-8 text-muted-foreground" />
        </div>
        <h3 className="text-lg font-semibold mb-2">{displayTitle}</h3>
        <p className="text-sm text-muted-foreground mb-6 max-w-md">{displayDescription}</p>
        {showUpgradeButton && (
          <Button onClick={handleUpgrade} variant="primary" size="lg">
            Upgrade to {SUBSCRIPTION_PLANS[nextPlan].name}
          </Button>
        )}
      </div>

      <Dialog open={showUpgradeDialog} onOpenChange={setShowUpgradeDialog}>
        <DialogContent size="lg">
          <DialogHeader>
            <DialogTitle>Upgrade Your Plan</DialogTitle>
            <DialogDescription>Choose the plan that's right for you</DialogDescription>
          </DialogHeader>
          <UpgradePlans
            currentPlan={currentPlan}
            onSelectPlan={(plan) => navigate(`/billing?plan=${plan}`)}
          />
        </DialogContent>
      </Dialog>
    </>
  );
};

interface UpgradePlansProps {
  currentPlan: string;
  onSelectPlan: (plan: string) => void;
}

const UpgradePlans = ({ currentPlan, onSelectPlan }: UpgradePlansProps) => {
  const plans = ['basic', 'professional', 'enterprise'] as const;

  return (
    <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
      {plans.map((plan) => {
        const planDetails = SUBSCRIPTION_PLANS[plan];
        const isCurrentPlan = currentPlan === plan;
        const isUpgrade =
          ['free', 'basic', 'professional'].indexOf(currentPlan) < plans.indexOf(plan);

        return (
          <Card
            key={plan}
            className={clsx('relative', {
              'border-primary border-2': planDetails.popular,
              'opacity-60': isCurrentPlan,
            })}
          >
            {planDetails.popular && (
              <div className="absolute -top-3 left-1/2 -translate-x-1/2">
                <span className="bg-primary text-primary-foreground px-3 py-1 rounded-full text-xs font-medium">
                  Most Popular
                </span>
              </div>
            )}
            <CardHeader>
              <CardTitle>{planDetails.name}</CardTitle>
              <CardDescription>{planDetails.description}</CardDescription>
              <div className="mt-4">
                <span className="text-3xl font-bold">{formatPrice(planDetails.price.monthly)}</span>
                <span className="text-muted-foreground">/month</span>
              </div>
            </CardHeader>
            <CardContent>
              <ul className="space-y-2 mb-6">
                {planDetails.features.map((feature) => (
                  <li key={feature.id} className="flex items-start gap-2 text-sm">
                    <Check className="h-4 w-4 text-success mt-0.5 flex-shrink-0" />
                    <span>{feature.name}</span>
                  </li>
                ))}
              </ul>
              <Button
                variant={planDetails.popular ? 'primary' : 'outline'}
                className="w-full"
                onClick={() => onSelectPlan(plan)}
                disabled={isCurrentPlan}
              >
                {isCurrentPlan ? 'Current Plan' : isUpgrade ? 'Upgrade' : 'Downgrade'}
              </Button>
            </CardContent>
          </Card>
        );
      })}
    </div>
  );
};
