import React, { useState, useRef, useEffect } from 'react';
import { Tabs, TabsContent, TabsList, TabsTrigger } from './tabs';
import { Button } from './button';
import { Input } from './input';
import { Label } from './label';
import { Alert, AlertDescription } from './alert';
import { 
  Upload, 
  Link as LinkIcon, 
  X, 
  Loader2, 
  CheckCircle, 
  AlertCircle,
  Image as ImageIcon,
  Info
} from 'lucide-react';
import {
  validateImageInput,
  validateImageUrlWithBase64,
  getImageDisplayName,
  fileToDataURL,
  type ImageValidationResult
} from '../../lib/image-validation';

export interface ImageInputProps {
  value?: File | string | null;
  onChange: (file: File | string | null) => void;
  onValidation?: (result: ImageValidationResult) => void;
  disabled?: boolean;
  className?: string;
  maxSize?: number; // in bytes, default 10MB
  accept?: string; // file accept attribute
  placeholder?: string;
  showPreview?: boolean;
  previewClassName?: string;
}

export interface ImageInputState {
  mode: 'file' | 'url';
  validation: ImageValidationResult | null;
  isValidating: boolean;
  error: string | null;
  previewUrl: string | null;
}

export function ImageInput({
  value,
  onChange,
  onValidation,
  disabled = false,
  className = '',
  maxSize = 10 * 1024 * 1024, // 10MB
  accept = 'image/*',
  placeholder = 'Enter image URL or select a file',
  showPreview = true,
  previewClassName = ''
}: ImageInputProps) {
  const [state, setState] = useState<ImageInputState>({
    mode: 'file',
    validation: null,
    isValidating: false,
    error: null,
    previewUrl: null
  });

  const [urlInput, setUrlInput] = useState('');
  const fileInputRef = useRef<HTMLInputElement>(null);
  const validationTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  // Handle external value changes
  useEffect(() => {
    if (value === null) {
      setState(prev => ({
        ...prev,
        validation: null,
        error: null,
        previewUrl: null
      }));
      setUrlInput('');
      return;
    }

    if (value instanceof File) {
      // File mode
      setState(prev => ({
        ...prev,
        mode: 'file',
        validation: null,
        error: null,
        previewUrl: null
      }));
      setUrlInput('');

      // Validate file immediately
      handleFileValidation(value);
    } else {
      // URL mode - value is a string (not File, not null)
      // Don't set preview URL yet, wait for validation to complete
      setState(prev => ({
        ...prev,
        mode: 'url',
        validation: null,
        error: null,
        previewUrl: null
      }));
      // value should be a string here, but cast it to be safe
      setUrlInput(value || '');

      // Validate URL (with debounce)
      if (validationTimeoutRef.current) {
        clearTimeout(validationTimeoutRef.current);
      }
      validationTimeoutRef.current = setTimeout(() => {
        // Only validate if we have a non-empty string
        const urlValue = typeof value === 'string' ? value : null;
        if (urlValue && urlValue.trim()) {
          handleUrlValidation(urlValue);
        } else {
          handleUrlValidation(null);
        }
      }, 500);
    }
  }, [value, maxSize]);

  // Cleanup timeout on unmount
  useEffect(() => {
    return () => {
      if (validationTimeoutRef.current) {
        clearTimeout(validationTimeoutRef.current);
      }
    };
  }, []);

  const handleFileValidation = async (file: File) => {
    setState(prev => ({ ...prev, isValidating: true, error: null }));
    
    const result = await validateImageInput(file);
    
    let previewUrl: string | null = null;
    if (result.isValid) {
      try {
        previewUrl = await fileToDataURL(file);
      } catch (error) {
        console.error('Failed to create preview URL:', error);
      }
    }
    
    setState(prev => ({
      ...prev,
      isValidating: false,
      validation: result,
      error: result.isValid ? null : (result.error || null),
      previewUrl
    }));

    onValidation?.(result);
  };

  const handleUrlValidation = async (url: string | null) => {
    if (!url || !url.trim()) {
      setState(prev => ({
        ...prev,
        validation: null,
        error: null,
        previewUrl: null
      }));
      onValidation?.({ isValid: false, error: 'Please enter a URL' });
      return;
    }

    setState(prev => ({ ...prev, isValidating: true, error: null }));
    
    try {
      const result = await validateImageUrlWithBase64(url);
      
      // Use base64 data for preview if available, otherwise use original URL
      const previewUrl = result.isValid ? (result.base64Data || url) : null;
      
      setState(prev => ({
        ...prev,
        isValidating: false,
        validation: result,
        error: result.isValid ? null : (result.error || null),
        previewUrl
      }));

      onValidation?.(result);
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Failed to validate URL';
      setState(prev => ({
        ...prev,
        isValidating: false,
        validation: { isValid: false, error: errorMessage },
        error: errorMessage,
        previewUrl: null
      }));
      onValidation?.({ isValid: false, error: errorMessage });
    }
  };

  const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      onChange(file);
    }
  };

  const handleUrlInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const url = event.target.value;
    setUrlInput(url);
    onChange(url || null);
  };

  const handleModeChange = (mode: 'file' | 'url') => {
    setState(prev => ({
      ...prev,
      mode,
      validation: null,
      error: null,
      previewUrl: null
    }));
    onChange(null);
    setUrlInput('');
  };

  const handleClear = () => {
    onChange(null);
    setUrlInput('');
    setState(prev => ({
      ...prev,
      validation: null,
      error: null,
      previewUrl: null
    }));
  };

  const isValid = state.validation?.isValid;
  const hasError = state.error && !isValid;
  const canPreview = isValid && state.previewUrl;
  const isCorsBlocked = state.validation?.isCorsBlocked;
  const hasBase64Data = !!state.validation?.base64Data;

  return (
    <div className={`image-input ${className}`}>
      <Tabs value={state.mode} onValueChange={(value) => handleModeChange(value as 'file' | 'url')}>
        <TabsList className="grid w-full grid-cols-2">
          <TabsTrigger value="file" disabled={disabled}>
            <Upload className="w-4 h-4 mr-2" />
            Upload File
          </TabsTrigger>
          <TabsTrigger value="url" disabled={disabled}>
            <LinkIcon className="w-4 h-4 mr-2" />
            From URL
          </TabsTrigger>
        </TabsList>

        <TabsContent value="file" className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="file-upload">Choose Image File</Label>
            <div className="flex gap-2">
              <Input
                ref={fileInputRef}
                id="file-upload"
                type="file"
                accept={accept}
                onChange={handleFileSelect}
                disabled={disabled}
                className="flex-1"
              />
              {value instanceof File && (
                <Button
                  type="button"
                  variant="outline"
                  onClick={() => fileInputRef.current?.click()}
                  disabled={disabled}
                >
                  Browse
                </Button>
              )}
            </div>
            {typeof value === 'string' && value && (
              <p className="text-sm text-gray-500">
                Current: {getImageDisplayName(value)}
              </p>
            )}
          </div>
        </TabsContent>

        <TabsContent value="url" className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="url-input">Image URL</Label>
            <Input
              id="url-input"
              type="url"
              value={urlInput}
              onChange={handleUrlInputChange}
              placeholder={placeholder}
              disabled={disabled}
              className="flex-1"
            />
            <p className="text-xs text-gray-500">
              Enter a URL that ends with an image extension (.jpg, .png, .gif, etc.)
            </p>
          </div>
        </TabsContent>
      </Tabs>

      {/* Validation Status */}
      {state.isValidating && (
        <div className="flex items-center gap-2 text-sm text-gray-500">
          <Loader2 className="w-4 h-4 animate-spin" />
          Validating and downloading image...
        </div>
      )}

      {isValid && (
        <Alert className="mt-4">
          <CheckCircle className="h-4 w-4" />
          <AlertDescription>
            Image is valid and ready to use
            {state.validation?.filename && ` (${state.validation.filename})`}
            {hasBase64Data && (
              <span className="block mt-1 text-xs text-green-600">
                ✓ Image downloaded and cached for preview
              </span>
            )}
            {isCorsBlocked && (
              <span className="block mt-1 text-xs text-yellow-600">
                Note: Downloaded using fallback method due to CORS restrictions
              </span>
            )}
          </AlertDescription>
        </Alert>
      )}

      {hasError && (
        <Alert variant="destructive" className="mt-4">
          <AlertCircle className="h-4 w-4" />
          <AlertDescription>
            {state.error}
            {state.error?.includes('CORS') && (
              <span className="block mt-1 text-xs">
                Try using a different image URL or upload the file directly
              </span>
            )}
          </AlertDescription>
        </Alert>
      )}

      {/* Image Preview */}
      {showPreview && canPreview && (
        <div className={`mt-4 ${previewClassName}`}>
          <Label>Preview</Label>
          <div className="mt-2 border rounded-lg p-4 bg-gray-50">
            <div className="flex items-center justify-center h-48 bg-white rounded border">
              <img
                src={state.previewUrl || ''}
                alt="Image preview"
                className="max-w-full max-h-full object-contain"
              />
            </div>
          </div>
        </div>
      )}

      {/* Clear Button */}
      {value && (
        <div className="mt-4 flex justify-end">
          <Button
            type="button"
            variant="outline"
            onClick={handleClear}
            disabled={disabled}
            className="text-red-600 hover:text-red-700"
          >
            <X className="w-4 h-4 mr-2" />
            Clear Selection
          </Button>
        </div>
      )}
    </div>
  );
}

export default ImageInput;