import { 
  Component, 
  Show, 
  createSignal, 
  createMemo,
  splitProps,
  JSX 
} from 'solid-js';
import { useAiCredits, CREDIT_COSTS, GenerateRequest } from '../../hooks/useAiCredits';

// Props interface
export interface AiGenerateButtonProps {
  /** The type of content to generate */
  type: 'job_description' | 'interview_question' | 'resume_review';
  /** Context data for generation (e.g., job title, company, etc.) */
  context: Record<string, unknown>;
  /** Callback when generation succeeds */
  onSuccess: (content: string) => void;
  /** Callback when generation fails */
  onError?: (error: Error) => void;
  /** Custom button text */
  buttonText?: string;
  /** Additional CSS classes */
  class?: string;
  /** Disabled state */
  disabled?: boolean;
  /** Whether to show the cost badge */
  showCost?: boolean;
  /** Custom icon element */
  icon?: JSX.Element;
}

// Loading spinner component
const LoadingSpinner: Component = () => (
  <svg 
    class="animate-spin h-5 w-5 text-white" 
    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>
);

// Sparkles icon for AI button
const SparklesIcon: 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="M5 2a1 1 0 011 1v1h1a1 1 0 010 2H6v1a1 1 0 01-2 0V6H3a1 1 0 010-2h1V3a1 1 0 011-1zm0 8a1 1 0 011 1v1h1a1 1 0 110 2H6v1a1 1 0 11-2 0v-1H3a1 1 0 110-2h1v-1a1 1 0 011-1zm7-8a1 1 0 011 1v1h1a1 1 0 110 2h-1v1a1 1 0 11-2 0V6h-1a1 1 0 110-2h1V3a1 1 0 011-1zm0 8a1 1 0 011 1v1h1a1 1 0 110 2h-1v1a1 1 0 11-2 0v-1h-1a1 1 0 110-2h1v-1a1 1 0 011-1z" 
      clip-rule="evenodd" 
    />
  </svg>
);

// Credit icon
const CreditIcon: Component = () => (
  <svg 
    xmlns="http://www.w3.org/2000/svg" 
    class="h-4 w-4" 
    viewBox="0 0 20 20" 
    fill="currentColor"
  >
    <path 
      d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V7z" 
    />
  </svg>
);

// Warning icon
const WarningIcon: Component = () => (
  <svg 
    xmlns="http://www.w3.org/2000/svg" 
    class="h-5 w-5 text-amber-500" 
    viewBox="0 0 20 20" 
    fill="currentColor"
  >
    <path 
      fill-rule="evenodd" 
      d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" 
      clip-rule="evenodd" 
    />
  </svg>
);

export const AiGenerateButton: Component<AiGenerateButtonProps> = (props) => {
  // Split props
  const [local, rest] = splitProps(props, [
    'type',
    'context',
    'onSuccess',
    'onError',
    'buttonText',
    'class',
    'disabled',
    'showCost',
    'icon',
  ]);

  // Get credit hook
  const credits = useAiCredits();
  
  // Local state for showing insufficient credits warning
  const [showWarning, setShowWarning] = createSignal(false);
  
  // Compute cost for this operation
  const cost = createMemo(() => CREDIT_COSTS[local.type] ?? 1);
  
  // Check if user has enough credits
  const hasEnoughCredits = createMemo(() => credits.hasEnoughCredits(cost()));
  
  // Determine button state
  const isDisabled = createMemo(() => 
    local.disabled || credits.isGenerating() || credits.isLoading()
  );
  
  // Handle button click
  const handleClick = async () => {
    // Clear previous errors
    credits.clearErrors();
    setShowWarning(false);
    
    // Check if user has enough credits
    if (!hasEnoughCredits()) {
      setShowWarning(true);
      return;
    }
    
    try {
      const request: GenerateRequest = {
        type: local.type,
        context: local.context,
      };
      
      const response = await credits.generate(request);
      
      if (response) {
        local.onSuccess(response.content);
      }
    } catch (err) {
      const error = err instanceof Error ? err : new Error('Generation failed');
      
      if (local.onError) {
        local.onError(error);
      }
      
      // Show warning for insufficient credits
      if (error.message.toLowerCase().includes('insufficient')) {
        setShowWarning(true);
      }
    }
  };
  
  // Handle buy credits click
  const handleBuyCredits = () => {
    // Emit event to open purchase modal
    // Parent component should listen for this event
    const event = new CustomEvent('open-credit-purchase-modal', {
      detail: { requiredCredits: cost() },
      bubbles: true,
    });
    document.dispatchEvent(event);
    
    // Hide the warning
    setShowWarning(false);
  };

  return (
    <div class={`flex flex-col gap-2 ${local.class || ''}`}>
      {/* Main button container */}
      <div class="flex items-center gap-2">
        {/* AI Generate Button */}
        <button
          type="button"
          onClick={handleClick}
          disabled={isDisabled()}
          class={`
            inline-flex items-center gap-2 px-4 py-2 
            rounded-lg font-medium text-sm
            transition-colors duration-200
            focus:outline-none focus:ring-2 focus:ring-offset-2
            ${hasEnoughCredits() 
              ? 'bg-indigo-600 text-white hover:bg-indigo-700 focus:ring-indigo-500' 
              : 'bg-gray-300 text-gray-500 cursor-not-allowed'
            }
            ${credits.isGenerating() && 'cursor-wait'}
          `}
          {...rest}
        >
          <Show 
            when={!credits.isGenerating()} 
            fallback={<LoadingSpinner />}
          >
            {local.icon ?? <SparklesIcon />}
          </Show>
          
          <span>
            {credits.isGenerating() 
              ? 'Generating...' 
              : (local.buttonText ?? 'Ask Ash')
            }
          </span>
          
          {/* Cost indicator badge */}
          <Show when={local.showCost !== false}>
            <span 
              class={`
                inline-flex items-center gap-1 
                px-1.5 py-0.5 rounded text-xs font-medium
                ${hasEnoughCredits()
                  ? 'bg-indigo-500/30 text-indigo-100'
                  : 'bg-red-500/30 text-red-100'
                }
              `}
              title={`Costs ${cost()} credit${cost() > 1 ? 's' : ''}`}
            >
              <CreditIcon />
              -{cost()}
            </span>
          </Show>
        </button>
        
        {/* Credit meter badge */}
        <div 
          class={`
            inline-flex items-center gap-1.5 px-3 py-2 
            rounded-lg text-sm font-medium
            transition-colors duration-200
            ${credits.credits() > 0 
              ? 'bg-green-100 text-green-800 border border-green-200' 
              : 'bg-red-100 text-red-800 border border-red-200'
            }
            ${credits.isLoading() && 'opacity-70'}
          `}
          title="Available AI credits"
        >
          <CreditIcon />
          <Show when={!credits.isLoading()} fallback="Loading...">
            <span>
              {credits.credits()} credit{credits.credits() !== 1 ? 's' : ''}
            </span>
          </Show>
        </div>
      </div>
      
      {/* Insufficient credits warning */}
      <Show when={showWarning()}>
        <div class="flex items-center gap-3 p-3 bg-amber-50 border border-amber-200 rounded-lg">
          <WarningIcon />
          <div class="flex-1">
            <p class="text-sm text-amber-800 font-medium">
              Insufficient credits
            </p>
            <p class="text-xs text-amber-700 mt-0.5">
              You need {cost()} credit{cost() > 1 ? 's' : ''} to generate this content.
              You currently have {credits.credits()}.
            </p>
          </div>
          <button
            type="button"
            onClick={handleBuyCredits}
            class="
              inline-flex items-center px-3 py-1.5
              bg-amber-600 text-white text-sm font-medium
              rounded-md hover:bg-amber-700
              transition-colors duration-200
              focus:outline-none focus:ring-2 focus:ring-amber-500 focus:ring-offset-1
            "
          >
            Buy Credits
          </button>
        </div>
      </Show>
      
      {/* Error message display */}
      <Show when={credits.generationError()}>
        <div class="flex items-center gap-2 p-3 bg-red-50 border border-red-200 rounded-lg text-sm text-red-800">
          <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>
          <span>{credits.generationError()}</span>
          <button
            type="button"
            onClick={() => credits.clearErrors()}
            class="ml-auto text-red-600 hover:text-red-800"
            title="Dismiss"
          >
            <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>
      </Show>
      
      {/* Low credits indicator (optional) */}
      <Show when={credits.credits() > 0 && credits.credits() < 3 && !showWarning()}>
        <p class="text-xs text-amber-600 flex items-center gap-1">
          <WarningIcon />
          Low on credits. Only {credits.credits()} remaining.
        </p>
      </Show>
    </div>
  );
};

export default AiGenerateButton;
