import { ReactNode, useState, useEffect } from 'react';
import Button from '../ui/button/Button';
import { useToast } from '../ui/toast/ToastContainer';
import { fetchAPI } from '../../services/api';

interface ImageGenerationCardProps {
  title: string;
  description?: string;
  integrationId: string;
  icon?: ReactNode;
}

interface GeneratedImage {
  url: string;
  revised_prompt?: string;
  model?: string;
  provider?: string;
  size?: string;
  format?: string;
  cost?: string;
}

interface ImageSettings {
  service?: string;
  model?: string;
  runwareModel?: string;
}

/**
 * Image Generation Testing Card Component
 * Full implementation with form fields and image display
 */
export default function ImageGenerationCard({
  title,
  description,
  integrationId,
  icon,
}: ImageGenerationCardProps) {
  const toast = useToast();
  const [isGenerating, setIsGenerating] = useState(false);
  const [prompt, setPrompt] = useState('');
  const [negativePrompt, setNegativePrompt] = useState('text, watermark, logo, overlay, title, caption, writing on walls, writing on objects, UI, infographic elements, post title');
  const [imageType, setImageType] = useState('realistic');
  const [imageSize, setImageSize] = useState('1024x1024');
  const [imageFormat, setImageFormat] = useState('webp');
  const [imageSettings, setImageSettings] = useState<ImageSettings>({});

  // Valid image sizes per model (from OpenAI official documentation)
  const VALID_SIZES_BY_MODEL: Record<string, string[]> = {
    'dall-e-3': ['1024x1024', '1024x1792', '1792x1024'],
    'dall-e-2': ['256x256', '512x512', '1024x1024'],
  };

  // Get valid sizes for current model
  const getValidSizes = (): string[] => {
    const service = imageSettings.service || 'openai';
    const model = service === 'openai' 
      ? (imageSettings.model || 'dall-e-3')
      : null;
    
    if (model && VALID_SIZES_BY_MODEL[model]) {
      return VALID_SIZES_BY_MODEL[model];
    }
    // Default to DALL-E 3 sizes if unknown
    return VALID_SIZES_BY_MODEL['dall-e-3'];
  };

  // Update size if current size is invalid for the selected model
  useEffect(() => {
    const validSizes = getValidSizes();
    if (validSizes.length > 0 && !validSizes.includes(imageSize)) {
      // Reset to first valid size (usually the default)
      setImageSize(validSizes[0]);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [imageSettings.model, imageSettings.service]); // imageSize intentionally omitted to avoid infinite loop
  const [generatedImage, setGeneratedImage] = useState<GeneratedImage | null>(null);
  const [error, setError] = useState<string | null>(null);

  const API_BASE_URL = import.meta.env.VITE_BACKEND_URL || 'https://api.igny8.com/api';

  // Load default image generation settings on mount
  useEffect(() => {
    const loadImageSettings = async () => {
      try {
        const response = await fetch(
          `${API_BASE_URL}/v1/system/settings/integrations/image_generation/`,
          { credentials: 'include' }
        );
        if (response.ok) {
          const data = await response.json();
          if (data.success && data.data) {
            setImageSettings(data.data);
          }
        }
      } catch (error) {
        console.error('Error loading image settings:', error);
      }
    };
    loadImageSettings();
  }, [API_BASE_URL]);

  const handleGenerate = async () => {
    console.log('[ImageGenerationCard] handleGenerate called');
    
    if (!prompt.trim()) {
      toast.error('Please enter a prompt description');
      return;
    }

    setIsGenerating(true);
    setError(null);
    setGeneratedImage(null);

    try {
      // Get the default service and model from settings
      const service = imageSettings.service || 'openai';
      const model = service === 'openai' 
        ? (imageSettings.model || 'dall-e-3')
        : (imageSettings.runwareModel || 'runware:97@1');

      console.log('[ImageGenerationCard] Service and model:', { service, model, imageSettings });

      // Build prompt with template (similar to reference plugin)
      const fullPrompt = `Create a high-quality ${imageType} image. ${prompt}`;
      console.log('[ImageGenerationCard] Full prompt:', fullPrompt.substring(0, 100) + '...');

      const requestBody = {
        prompt: fullPrompt,
        negative_prompt: negativePrompt,
        image_type: imageType,
        image_size: imageSize,
        image_format: imageFormat,
        provider: service,
        model: model,
      };

      console.log('[ImageGenerationCard] Making request to image generation endpoint');
      console.log('[ImageGenerationCard] Request body:', requestBody);

      const data = await fetchAPI('/v1/system/settings/integrations/image_generation/generate/', {
        method: 'POST',
        body: JSON.stringify(requestBody),
      });

      console.log('[ImageGenerationCard] Response data:', data);

      if (!data.success) {
        throw new Error(data.error || 'Failed to generate image');
      }

      const imageData = {
        url: data.image_url,
        revised_prompt: data.revised_prompt,
        model: data.model || model,
        provider: data.provider || service,
        size: imageSize,
        format: imageFormat.toUpperCase(),
        cost: data.cost,
      };

      setGeneratedImage(imageData);

      // Emit custom event for ImageResultCard to listen to
      window.dispatchEvent(
        new CustomEvent('imageGenerated', {
          detail: imageData,
        })
      );

      console.log('[ImageGenerationCard] Image generation successful:', imageData);
      toast.success('Image generated successfully!');
    } catch (err: any) {
      console.error('[ImageGenerationCard] Error in handleGenerate:', {
        error: err,
        message: err.message,
        stack: err.stack,
      });
      
      const errorMessage = err.message || 'Failed to generate image';
      setError(errorMessage);
      
      // Emit error event for ImageResultCard
      window.dispatchEvent(
        new CustomEvent('imageGenerationError', {
          detail: errorMessage,
        })
      );
      
      toast.error(errorMessage);
    } finally {
      console.log('[ImageGenerationCard] handleGenerate completed');
      setIsGenerating(false);
    }
  };

  // Get display name for provider and model
  const getProviderDisplay = () => {
    const service = imageSettings.service || 'openai';
    if (service === 'openai') {
      const model = imageSettings.model || 'dall-e-3';
      const modelNames: Record<string, string> = {
        'dall-e-3': 'DALL·E 3',
        'dall-e-2': 'DALL·E 2',
        'gpt-image-1': 'GPT Image 1 (Full)',
        'gpt-image-1-mini': 'GPT Image 1 Mini',
      };
      return `OpenAI ${modelNames[model] || model}`;
    } else {
      return 'Runware';
    }
  };

  // Image size options - dynamically generated based on selected model
  const sizeLabels: Record<string, string> = {
    '1024x1024': 'Square - 1024 x 1024',
    '1024x1792': 'Portrait - 1024 x 1792',
    '1792x1024': 'Landscape - 1792 x 1024',
    '256x256': 'Small - 256 x 256',
    '512x512': 'Medium - 512 x 512',
  };

  const sizeOptions = getValidSizes().map(size => ({
    value: size,
    label: sizeLabels[size] || size,
  }));

  // Image type options
  const typeOptions = [
    { value: 'realistic', label: 'Realistic' },
    { value: 'illustration', label: 'Illustration' },
    { value: '3D render', label: '3D Render' },
    { value: 'minimalist', label: 'Minimalist' },
    { value: 'cartoon', label: 'Cartoon' },
  ];

  // Format options
  const formatOptions = [
    { value: 'webp', label: 'WEBP' },
    { value: 'jpg', label: 'JPG' },
    { value: 'png', label: 'PNG' },
  ];

  return (
    <article className="rounded-2xl border border-gray-200 bg-white dark:border-gray-800 dark:bg-white/3">
      <div className="relative p-5 pb-6">
        {icon && (
          <div className="mb-4 inline-flex h-10 w-10 items-center justify-center">
            {icon}
          </div>
        )}
        <h3 className="mb-2 text-base font-semibold text-gray-800 dark:text-white/90">
          {title}
        </h3>
        {description && (
          <p className="text-sm text-gray-500 dark:text-gray-400">
            {description}
          </p>
        )}
      </div>
      <div className="border-t border-gray-200 p-5 dark:border-gray-800">
        <div className="space-y-5">
          {/* API Provider and Model Display */}
          <div className="flex items-center gap-3 rounded-lg bg-blue-50 px-4 py-3 dark:bg-blue-900/20">
            <svg
              xmlns="http://www.w3.org/2000/svg"
              width="20"
              height="20"
              viewBox="0 0 20 20"
              fill="none"
              className="text-blue-600 dark:text-blue-400"
            >
              <path
                d="M10 2L3 7V17C3 17.5304 3.21071 18.0391 3.58579 18.4142C3.96086 18.7893 4.46957 19 5 19H15C15.5304 19 16.0391 18.7893 16.4142 18.4142C16.7893 18.0391 17 17.5304 17 17V7L10 2Z"
                stroke="currentColor"
                strokeWidth="1.5"
                strokeLinecap="round"
                strokeLinejoin="round"
              />
            </svg>
            <div>
              <p className="text-xs font-medium text-blue-600 dark:text-blue-400">Provider & Model</p>
              <p className="text-sm font-semibold text-blue-900 dark:text-blue-200">
                {getProviderDisplay()}
              </p>
            </div>
          </div>

          {/* Prompt Description - Full Width */}
          <div>
            <label className="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">
              Prompt Description *
            </label>
            <textarea
              value={prompt}
              onChange={(e) => setPrompt(e.target.value)}
              rows={6}
              className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
              placeholder="Describe the visual elements, style, mood, and composition you want in the image..."
            />
            <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
              Describe the visual elements, style, mood, and composition you want in the image.
            </p>
          </div>

          {/* Negative Prompt - Small */}
          <div>
            <label className="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">
              Negative Prompt
            </label>
            <textarea
              value={negativePrompt}
              onChange={(e) => setNegativePrompt(e.target.value)}
              rows={2}
              className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
              placeholder="Describe what you DON'T want in the image..."
            />
            <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
              Specify elements to avoid in the generated image (text, watermarks, logos, etc.).
            </p>
          </div>

          {/* 3 Column Dropdowns */}
          <div className="grid grid-cols-3 gap-4">
            {/* Image Type */}
            <div>
              <label className="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">
                Image Type
              </label>
              <select
                value={imageType}
                onChange={(e) => setImageType(e.target.value)}
                className="w-full rounded-lg border border-gray-300 px-4 py-2.5 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
              >
                {typeOptions.map((option) => (
                  <option key={option.value} value={option.value}>
                    {option.label}
                  </option>
                ))}
              </select>
            </div>

            {/* Image Size */}
            <div>
              <label className="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">
                Image Size
              </label>
              <select
                value={imageSize}
                onChange={(e) => setImageSize(e.target.value)}
                className="w-full rounded-lg border border-gray-300 px-4 py-2.5 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
              >
                {sizeOptions.map((option) => (
                  <option key={option.value} value={option.value}>
                    {option.label}
                  </option>
                ))}
              </select>
            </div>

            {/* Image Format */}
            <div>
              <label className="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">
                Image Format
              </label>
              <select
                value={imageFormat}
                onChange={(e) => setImageFormat(e.target.value)}
                className="w-full rounded-lg border border-gray-300 px-4 py-2.5 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
              >
                {formatOptions.map((option) => (
                  <option key={option.value} value={option.value}>
                    {option.label}
                  </option>
                ))}
              </select>
            </div>
          </div>

          {/* Generate Button - Bottom Right */}
          <div className="flex justify-end">
            <Button
              onClick={handleGenerate}
              disabled={isGenerating || !prompt.trim()}
              className="inline-flex items-center gap-2 px-6 py-2.5"
            >
              {isGenerating ? (
                <>
                  <svg
                    className="h-4 w-4 animate-spin"
                    xmlns="http://www.w3.org/2000/svg"
                    fill="none"
                    viewBox="0 0 24 24"
                  >
                    <circle
                      className="opacity-25"
                      cx="12"
                      cy="12"
                      r="10"
                      stroke="currentColor"
                      strokeWidth="4"
                    />
                    <path
                      className="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>
                  Generating...
                </>
              ) : (
                <>
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    width="16"
                    height="16"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  >
                    <rect x="3" y="3" width="18" height="18" rx="2" />
                    <circle cx="9" cy="9" r="2" />
                    <path d="M21 15l-3.086-3.086a2 2 0 00-2.828 0L6 21" />
                  </svg>
                  Generate Image
                </>
              )}
            </Button>
          </div>
        </div>
      </div>

      {/* Error display */}
      {error && (
        <div className="mt-4 rounded-lg border border-red-200 bg-red-50 p-4 dark:border-red-800 dark:bg-red-900/20">
          <p className="text-sm text-red-600 dark:text-red-400">{error}</p>
        </div>
      )}
    </article>
  );
}
