import { 
  Component, 
  Show, 
  createSignal, 
  createMemo,
  onMount,
  onCleanup,
  batch,
  JSX, For
} from 'solid-js';
import { useAiCredits, CREDIT_COSTS, PurchaseResponse } from '../../hooks/useAiCredits';

// Props interface
export interface AskAshModalProps {
  /** Whether the modal is open */
  isOpen: boolean;
  /** Callback when modal is closed */
  onClose: () => void;
  /** Minimum credits needed (optional) */
  requiredCredits?: number;
  /** Callback when purchase is successful */
  onPurchaseSuccess?: (response: PurchaseResponse) => void;
  /** Callback when purchase fails */
  onPurchaseError?: (error: Error) => void;
}

// Credit package options
interface CreditPackage {
  id: string;
  credits: number;
  price: number;
  label: string;
  popular?: boolean;
}

const CREDIT_PACKAGES: CreditPackage[] = [
  { id: 'small', credits: 10, price: 5, label: 'Starter' },
  { id: 'medium', credits: 50, price: 20, label: 'Pro', popular: true },
  { id: 'large', credits: 200, price: 60, label: 'Enterprise' },
];

// Payment method options
const PAYMENT_METHODS = [
  { id: 'card', label: 'Credit/Debit Card', icon: '💳' },
  { id: 'tracecoin', label: 'Tracecoin Balance', icon: '🪙' },
];

// Close icon
const CloseIcon: Component = () => (
  <svg 
    xmlns="http://www.w3.org/2000/svg" 
    class="h-6 w-6" 
    fill="none" 
    viewBox="0 0 24 24" 
    stroke="currentColor"
  >
    <path 
      stroke-linecap="round" 
      stroke-linejoin="round" 
      stroke-width="2" 
      d="M6 18L18 6M6 6l12 12" 
    />
  </svg>
);

// Check icon
const CheckIcon: Component = () => (
  <svg 
    xmlns="http://www.w3.org/2000/svg" 
    class="h-5 w-5" 
    viewBox="0 0 20 20" 
    fill="currentColor"
  >
    <path 
      fill-rule="evenodd" 
      d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" 
      clip-rule="evenodd" 
    />
  </svg>
);

// Sparkles icon
const SparklesIcon: Component = () => (
  <svg 
    xmlns="http://www.w3.org/2000/svg" 
    class="h-12 w-12" 
    fill="none" 
    viewBox="0 0 24 24" 
    stroke="currentColor"
  >
    <path 
      stroke-linecap="round" 
      stroke-linejoin="round" 
      stroke-width="1.5" 
      d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" 
    />
  </svg>
);

// Loading spinner
const LoadingSpinner: Component<{ size?: 'sm' | 'md' | 'lg' }> = (props) => {
  const sizeClass = {
    sm: 'h-4 w-4',
    md: 'h-5 w-5',
    lg: 'h-8 w-8',
  }[props.size || 'md'];
  
  return (
    <svg 
      class={`animate-spin ${sizeClass} text-current`} 
      xmlns="http://www.w3.org/2000/svg" 
      fill="none" 
      viewBox="0 0 24 24"
    >
      <circle 
        class="opacity-25" 
        cx="12" 
        cy="12" 
        r="10" 
        stroke="currentColor" 
        stroke-width="4"
      />
      <path 
        class="opacity-75" 
        fill="currentColor" 
        d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
      />
    </svg>
  );
};

export const AskAshModal: Component<AskAshModalProps> = (props) => {
  // Get credit hook
  const credits = useAiCredits();
  
  // Local state
  const [selectedPackage, setSelectedPackage] = createSignal<CreditPackage>(CREDIT_PACKAGES[1]);
  const [selectedPayment, setSelectedPayment] = createSignal<string>('card');
  const [step, setStep] = createSignal<'select' | 'confirm' | 'success'>('select');
  const [purchaseResult, setPurchaseResult] = createSignal<PurchaseResponse | null>(null);
  
  // Compute if user needs specific amount
  const requiredAmount = createMemo(() => props.requiredCredits ?? 1);
  
  // Compute current credit cost per operation
  const operationsEstimate = createMemo(() => Math.floor(selectedPackage().credits / requiredAmount()));
  
  // Handle escape key to close modal
  onMount(() => {
    const handleEscape = (e: KeyboardEvent) => {
      if (e.key === 'Escape' && props.isOpen && !credits.isPurchasing()) {
        handleClose();
      }
    };
    
    document.addEventListener('keydown', handleEscape);
    
    onCleanup(() => {
      document.removeEventListener('keydown', handleEscape);
    });
  });
  
  // Reset state when modal opens
  const resetState = () => {
    batch(() => {
      setSelectedPackage(CREDIT_PACKAGES[1]);
      setSelectedPayment('card');
      setStep('select');
      setPurchaseResult(null);
      credits.clearErrors();
    });
  };
  
  // Handle close
  const handleClose = () => {
    if (!credits.isPurchasing()) {
      props.onClose();
    }
  };
  
  // Handle backdrop click
  const handleBackdropClick = (e: MouseEvent) => {
    if (e.target === e.currentTarget) {
      handleClose();
    }
  };
  
  // Handle package selection
  const handleSelectPackage = (pkg: CreditPackage) => {
    setSelectedPackage(pkg);
  };
  
  // Handle continue to confirmation
  const handleContinue = () => {
    setStep('confirm');
  };
  
  // Handle purchase
  const handlePurchase = async () => {
    try {
      const response = await credits.purchase({
        amount: selectedPackage().credits,
        payment_method: selectedPayment(),
      });
      
      if (response) {
        setPurchaseResult(response);
        setStep('success');
        
        if (props.onPurchaseSuccess) {
          props.onPurchaseSuccess(response);
        }
      }
    } catch (err) {
      const error = err instanceof Error ? err : new Error('Purchase failed');
      
      if (props.onPurchaseError) {
        props.onPurchaseError(error);
      }
    }
  };
  
  // Handle done after success
  const handleDone = () => {
    resetState();
    props.onClose();
  };
  
  // Handle buy more after success
  const handleBuyMore = () => {
    setStep('select');
    setPurchaseResult(null);
  };

  // Component for package card
  const PackageCard: Component<{ pkg: CreditPackage }> = (pkgProps) => {
    const isSelected = createMemo(() => selectedPackage().id === pkgProps.pkg.id);
    
    return (
      <button
        type="button"
        onClick={() => handleSelectPackage(pkgProps.pkg)}
        class={`
          relative p-4 rounded-xl border-2 text-left transition-all duration-200
          ${isSelected() 
            ? 'border-indigo-600 bg-indigo-50' 
            : 'border-gray-200 hover:border-indigo-300 hover:bg-gray-50'
          }
        `}
      >
        {/* Popular badge */}
        <Show when={pkgProps.pkg.popular}>
          <span class="
            absolute -top-2 left-1/2 -translate-x-1/2
            px-2 py-0.5 bg-indigo-600 text-white text-xs font-medium rounded-full
          ">
            Popular
          </span>
        </Show>
        
        <div class="flex flex-col items-center text-center">
          <span class="text-lg font-bold text-gray-900">
            {pkgProps.pkg.credits} Credits
          </span>
          <span class="text-2xl font-bold text-indigo-600 mt-1">
            ${pkgProps.pkg.price}
          </span>
          <span class="text-xs text-gray-500 mt-1">
            ${(pkgProps.pkg.price / pkgProps.pkg.credits).toFixed(2)}/credit
          </span>
        </div>
        
        {/* Selection indicator */}
        <Show when={isSelected()}>
          <div class="absolute top-2 right-2 text-indigo-600">
            <CheckIcon />
          </div>
        </Show>
      </button>
    );
  };
  
  // Component for payment method
  const PaymentMethod: Component<{ method: typeof PAYMENT_METHODS[0] }> = (payProps) => {
    const isSelected = createMemo(() => selectedPayment() === payProps.method.id);
    
    return (
      <button
        type="button"
        onClick={() => setSelectedPayment(payProps.method.id)}
        class={`
          flex items-center gap-3 p-3 rounded-lg border transition-all duration-200
          ${isSelected() 
            ? 'border-indigo-600 bg-indigo-50' 
            : 'border-gray-200 hover:border-gray-300'
          }
        `}
      >
        <span class="text-2xl">{payProps.method.icon}</span>
        <div class="flex-1 text-left">
          <span class="font-medium text-gray-900">{payProps.method.label}</span>
        </div>
        <div class={`
          w-5 h-5 rounded-full border-2 flex items-center justify-center
          ${isSelected() ? 'border-indigo-600' : 'border-gray-300'}
        `}>
          <Show when={isSelected()}>
            <div class="w-2.5 h-2.5 rounded-full bg-indigo-600" />
          </Show>
        </div>
      </button>
    );
  };

  return (
    <Show when={props.isOpen}>
      {/* Modal backdrop */}
      <div 
        class="
          fixed inset-0 z-50 
          bg-black/50 backdrop-blur-sm
          flex items-center justify-center p-4
          animate-[fadeIn_0.2s_ease-out]
        "
        onClick={handleBackdropClick}
      >
        {/* Modal content */}
        <div 
          class={`
            relative w-full max-w-lg max-h-[90vh]
            bg-white rounded-2xl shadow-2xl
            overflow-hidden
            animate-[slideIn_0.3s_ease-out]
            flex flex-col
          `}
          role="dialog"
          aria-modal="true"
          aria-labelledby="modal-title"
        >
          {/* Header */}
          <div class="flex items-center justify-between p-6 border-b border-gray-100">
            <div class="flex items-center gap-3">
              <div class="p-2 bg-indigo-100 rounded-lg text-indigo-600">
                <SparklesIcon />
              </div>
              <div>
                <h2 id="modal-title" class="text-xl font-bold text-gray-900">
                  {step() === 'success' ? 'Purchase Complete!' : 'Buy Ask Ash Credits'}
                </h2>
                <Show when={step() !== 'success'}>
                  <p class="text-sm text-gray-500">
                    Power your AI-generated content
                  </p>
                </Show>
              </div>
            </div>
            
            <Show when={step() !== 'success' && !credits.isPurchasing()}>
              <button
                type="button"
                onClick={handleClose}
                class="p-2 text-gray-400 hover:text-gray-600 rounded-lg hover:bg-gray-100 transition-colors"
              >
                <CloseIcon />
              </button>
            </Show>
          </div>
          
          {/* Error display */}
          <Show when={credits.purchaseError()}>
            <div class="mx-6 mt-4 p-3 bg-red-50 border border-red-200 rounded-lg text-sm text-red-800">
              <div class="flex items-start gap-2">
                <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 flex-shrink-0" viewBox="0 0 20 20" fill="currentColor">
                  <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
                </svg>
                <div class="flex-1">
                  <p class="font-medium">Purchase failed</p>
                  <p class="text-xs mt-0.5">{credits.purchaseError()}</p>
                </div>
                <button
                  type="button"
                  onClick={() => credits.clearErrors()}
                  class="text-red-600 hover:text-red-800"
                >
                  <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
                    <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
                  </svg>
                </button>
              </div>
            </div>
          </Show>
          
          {/* Body */}
          <div class="flex-1 overflow-y-auto p-6">
            {/* Step 1: Select package */}
            <Show when={step() === 'select'}>
              <div class="space-y-6">
                {/* Current balance */}
                <div class="flex items-center justify-between p-4 bg-gray-50 rounded-xl">
                  <span class="text-sm text-gray-600">Current balance</span>
                  <span class="font-medium text-gray-900">
                    {credits.credits()} credits
                  </span>
                </div>
                
                {/* Package selection */}
                <div>
                  <h3 class="text-sm font-medium text-gray-900 mb-3">
                    Select a credit package
                  </h3>
                  <div class="grid grid-cols-3 gap-3">
                    <For each={CREDIT_PACKAGES}>{(pkg) => (
                      <PackageCard pkg={pkg} />
                    )}</For>
                  </div>
                </div>
                
                {/* Payment method */}
                <div>
                  <h3 class="text-sm font-medium text-gray-900 mb-3">
                    Payment method
                  </h3>
                  <div class="space-y-2">
                    <For each={PAYMENT_METHODS}>{(method) => (
                      <PaymentMethod method={method} />
                    )}</For>
                  </div>
                </div>
                
                {/* Summary */}
                <div class="p-4 bg-indigo-50 rounded-xl">
                  <div class="flex items-center justify-between text-sm">
                    <span class="text-indigo-900">Package</span>
                    <span class="font-medium text-indigo-900">
                      {selectedPackage().credits} credits
                    </span>
                  </div>
                  <div class="flex items-center justify-between text-sm mt-2">
                    <span class="text-indigo-900">Total</span>
                    <span class="text-lg font-bold text-indigo-900">
                      ${selectedPackage().price.toFixed(2)}
                    </span>
                  </div>
                  <div class="text-xs text-indigo-700 mt-2">
                    Estimated {operationsEstimate()} job descriptions
                  </div>
                </div>
              </div>
            </Show>
            
            {/* Step 2: Confirm */}
            <Show when={step() === 'confirm'}>
              <div class="space-y-6">
                <div class="text-center">
                  <div class="inline-flex items-center justify-center w-16 h-16 bg-indigo-100 rounded-full text-indigo-600 mb-4">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" viewBox="0 0 20 20" fill="currentColor">
                      <path fill-rule="evenodd" d="M5 4a3 3 0 00-3 3v6a3 3 0 003 3h10a3 3 0 003-3V7a3 3 0 00-3-3H5zm-1 9v-1h5v2H5a1 1 0 01-1-1zm7 1h4a1 1 0 001-1v-1h-5v2zm0-4h5V8h-5v2zM9 8H4v2h5V8z" clip-rule="evenodd" />
                    </svg>
                  </div>
                  <h3 class="text-lg font-medium text-gray-900">
                    Confirm your purchase
                  </h3>
                  <p class="text-sm text-gray-500 mt-1">
                    You're about to purchase {selectedPackage().credits} credits
                  </p>
                </div>
                
                <div class="space-y-3">
                  <div class="flex justify-between p-3 bg-gray-50 rounded-lg">
                    <span class="text-gray-600">Credits</span>
                    <span class="font-medium">{selectedPackage().credits}</span>
                  </div>
                  <div class="flex justify-between p-3 bg-gray-50 rounded-lg">
                    <span class="text-gray-600">Payment method</span>
                    <span class="font-medium">
                      {PAYMENT_METHODS.find(m => m.id === selectedPayment())?.label}
                    </span>
                  </div>
                  <div class="flex justify-between p-3 bg-indigo-50 rounded-lg">
                    <span class="text-indigo-900 font-medium">Total amount</span>
                    <span class="text-lg font-bold text-indigo-900">
                      ${selectedPackage().price.toFixed(2)}
                    </span>
                  </div>
                </div>
              </div>
            </Show>
            
            {/* Step 3: Success */}
            <Show when={step() === 'success'}>
              <div class="text-center py-4">
                <div class="inline-flex items-center justify-center w-20 h-20 bg-green-100 rounded-full text-green-600 mb-4">
                  <svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10" viewBox="0 0 20 20" fill="currentColor">
                    <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
                  </svg>
                </div>
                <h3 class="text-xl font-medium text-gray-900">
                  Credits added!
                </h3>
                <p class="text-gray-500 mt-2">
                  You now have <strong>{purchaseResult()?.new_balance}</strong> credits available.
                </p>
                <Show when={purchaseResult()?.transaction_id}>
                  <p class="text-xs text-gray-400 mt-4">
                    Transaction ID: {purchaseResult()?.transaction_id}
                  </p>
                </Show>
              </div>
            </Show>
          </div>
          
          {/* Footer */}
          <div class="p-6 border-t border-gray-100 bg-gray-50">
            <Show when={step() === 'select'}>
              <button
                type="button"
                onClick={handleContinue}
                class="w-full py-3 px-4 bg-indigo-600 text-white font-medium rounded-xl hover:bg-indigo-700 transition-colors focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
              >
                Continue
              </button>
            </Show>
            
            <Show when={step() === 'confirm'}>
              <div class="flex gap-3">
                <button
                  type="button"
                  onClick={() => setStep('select')}
                  disabled={credits.isPurchasing()}
                  class="flex-1 py-3 px-4 bg-white text-gray-700 font-medium rounded-xl border border-gray-300 hover:bg-gray-50 transition-colors disabled:opacity-50"
                >
                  Back
                </button>
                <button
                  type="button"
                  onClick={handlePurchase}
                  disabled={credits.isPurchasing()}
                  class="flex-1 py-3 px-4 bg-indigo-600 text-white font-medium rounded-xl hover:bg-indigo-700 transition-colors disabled:opacity-50 flex items-center justify-center gap-2"
                >
                  <Show when={credits.isPurchasing()} fallback="Pay Now">
                    <LoadingSpinner size="sm" />
                    Processing...
                  </Show>
                </button>
              </div>
            </Show>
            
            <Show when={step() === 'success'}>
              <div class="flex gap-3">
                <button
                  type="button"
                  onClick={handleDone}
                  class="flex-1 py-3 px-4 bg-indigo-600 text-white font-medium rounded-xl hover:bg-indigo-700 transition-colors"
                >
                  Done
                </button>
                <button
                  type="button"
                  onClick={handleBuyMore}
                  class="flex-1 py-3 px-4 bg-white text-gray-700 font-medium rounded-xl border border-gray-300 hover:bg-gray-50 transition-colors"
                >
                  Buy More
                </button>
              </div>
            </Show>
          </div>
        </div>
      </div>
    </Show>
  );
};

// CSS animations
const style = `
  @keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
  }
  
  @keyframes slideIn {
    from { 
      opacity: 0;
      transform: scale(0.95) translateY(-10px);
    }
    to { 
      opacity: 1;
      transform: scale(1) translateY(0);
    }
  }
`;

// Inject styles
if (typeof document !== 'undefined') {
  const styleEl = document.createElement('style');
  styleEl.textContent = style;
  document.head.appendChild(styleEl);
}

export default AskAshModal;
