import { useState, useCallback, useEffect } from "react";
import { Upload, Image as ImageIcon, Loader2, Copy, Check } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { useToast } from "@/hooks/use-toast";
import { supabase } from "@/integrations/supabase/client";
import { User } from "@supabase/supabase-js";

interface ImageUploaderProps {
  user: User | null;
}

export const ImageUploader = ({ user }: ImageUploaderProps) => {
  const [isDragging, setIsDragging] = useState(false);
  const [imageFile, setImageFile] = useState<File | null>(null);
  const [imagePreview, setImagePreview] = useState<string | null>(null);
  const [isGenerating, setIsGenerating] = useState(false);
  const [altText, setAltText] = useState<string | null>(null);
  const [isCopied, setIsCopied] = useState(false);
  const { toast } = useToast();

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(true);
  }, []);

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
  }, []);

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
    
    const file = e.dataTransfer.files[0];
    if (file && file.type.startsWith('image/')) {
      handleImageFile(file);
    } else {
      toast({
        title: "Invalid file type",
        description: "Please upload an image file",
        variant: "destructive",
      });
    }
  }, [toast]);

  const handleFileInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      handleImageFile(file);
    }
  };

  const handleImageFile = (file: File) => {
    setImageFile(file);
    setAltText(null);
    setIsCopied(false);
    
    const reader = new FileReader();
    reader.onloadend = () => {
      setImagePreview(reader.result as string);
    };
    reader.readAsDataURL(file);
  };

  const generateAltText = async () => {
    if (!imageFile || !user) {
      toast({
        title: "Authentication required",
        description: "Please sign in to generate alt text",
        variant: "destructive",
      });
      return;
    }

    setIsGenerating(true);
    setAltText(null);
    const startTime = Date.now();

    try {
      // Upload image to custom CDN
      const formData = new FormData();
      formData.append('file', imageFile);
      
      const uploadResponse = await fetch('https://cdn.madebydanny.uk/upload', {
        method: 'POST',
        body: formData,
      });

      if (!uploadResponse.ok) {
        throw new Error('Failed to upload image to CDN');
      }

      const uploadData = await uploadResponse.json();
      const imageUrl = uploadData.url;

      // Get auth token for authenticated request
      const { data: { session } } = await supabase.auth.getSession();
      if (!session) {
        throw new Error('Not authenticated');
      }

      // Call edge function to generate alt text (authenticated)
      const { data, error } = await supabase.functions.invoke('generate-alt-text', {
        body: { 
          imageUrl,
          generationTimeStart: startTime
        }
      });

      if (error) throw error;

      setAltText(data.altText);
      toast({
        title: "Success!",
        description: "Alt text generated successfully",
      });

    } catch (error: any) {
      console.error('Error generating alt text:', error);
      
      let errorMessage = "Failed to generate alt text";
      if (error?.message?.includes('Rate limit')) {
        errorMessage = "Daily limit reached (20 per day). Try again tomorrow.";
      } else if (error?.message?.includes('Authentication')) {
        errorMessage = "Please sign in to continue";
      }
      
      toast({
        title: "Error",
        description: errorMessage,
        variant: "destructive",
      });
    } finally {
      setIsGenerating(false);
    }
  };

  const copyToClipboard = async () => {
    if (!altText) return;
    
    try {
      await navigator.clipboard.writeText(altText);
      setIsCopied(true);
      toast({
        title: "Copied!",
        description: "Alt text copied to clipboard",
      });
      setTimeout(() => setIsCopied(false), 2000);
    } catch (error) {
      toast({
        title: "Error",
        description: "Failed to copy to clipboard",
        variant: "destructive",
      });
    }
  };

  return (
    <Card className="bg-card border-border/50 p-8">
      <div className="flex items-center gap-3 mb-6">
        <ImageIcon className="w-6 h-6 text-primary" />
        <h2 className="text-xl font-semibold text-foreground">Upload Image</h2>
      </div>

      {!imagePreview ? (
        <div
          onDragOver={handleDragOver}
          onDragLeave={handleDragLeave}
          onDrop={handleDrop}
          className={`
            border-2 border-dashed rounded-lg p-12 text-center transition-all
            ${isDragging 
              ? 'border-primary bg-primary/5' 
              : 'border-border/50 bg-upload-area hover:border-primary/50'
            }
          `}
        >
          <Upload className="w-12 h-12 text-muted-foreground mx-auto mb-4" />
          <p className="text-muted-foreground mb-4">
            Drag & drop your image here, or click to select
          </p>
          <input
            type="file"
            accept="image/*"
            onChange={handleFileInput}
            className="hidden"
            id="file-upload"
          />
          <label htmlFor="file-upload">
            <Button variant="secondary" className="cursor-pointer" asChild>
              <span>Choose Image</span>
            </Button>
          </label>
        </div>
      ) : (
        <div className="space-y-6">
          <div className="relative rounded-lg overflow-hidden bg-upload-area">
            <img 
              src={imagePreview} 
              alt="Preview" 
              className="w-full h-auto max-h-96 object-contain"
            />
          </div>

          <Button
            onClick={generateAltText}
            disabled={isGenerating}
            className="w-full bg-primary hover:bg-primary/90 text-primary-foreground font-medium"
            size="lg"
          >
            {isGenerating ? (
              <>
                <Loader2 className="w-5 h-5 mr-2 animate-spin" />
                Generating...
              </>
            ) : (
              <>
                <ImageIcon className="w-5 h-5 mr-2" />
                Generate Alt Text
              </>
            )}
          </Button>

          {altText && (
            <Card className="bg-upload-area border-primary/20 p-6">
              <div className="flex items-start justify-between gap-4 mb-3">
                <h3 className="text-sm font-medium text-muted-foreground">Generated Alt Text</h3>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={copyToClipboard}
                  className="h-8 px-3"
                >
                  {isCopied ? (
                    <Check className="w-4 h-4 text-primary" />
                  ) : (
                    <Copy className="w-4 h-4" />
                  )}
                </Button>
              </div>
              <p className="text-foreground leading-relaxed">{altText}</p>
            </Card>
          )}

          <Button
            variant="outline"
            onClick={() => {
              setImageFile(null);
              setImagePreview(null);
              setAltText(null);
              setIsCopied(false);
            }}
            className="w-full"
          >
            Upload Another Image
          </Button>
        </div>
      )}
    </Card>
  );
};
