'use client';

import { useState, useCallback, useRef } from 'react';
import { useSession } from 'next-auth/react';
import { Button } from '@/components/ui/button';
import { Upload, X, CheckCircle2, AlertCircle, Loader2, Play, Pause } from 'lucide-react';

interface UploadedFile {
  file: File;
  preview: string;
  id: string;
  status: 'pending' | 'uploading' | 'success' | 'error';
  error?: string;
}

interface FilePreviewItemProps {
  uploadedFile: UploadedFile;
  onRemove: (id: string) => void;
}

function FilePreviewItem({ uploadedFile, onRemove }: FilePreviewItemProps) {
  const videoRef = useRef<HTMLVideoElement>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const isVideo = uploadedFile.file.type.startsWith('video/');

  const togglePlay = useCallback(async (e: React.MouseEvent) => {
    e.stopPropagation();
    e.preventDefault();
    const video = videoRef.current;
    if (!video) return;
    
    try {
      if (video.paused) {
        await video.play();
        setIsPlaying(true);
      } else {
        video.pause();
        setIsPlaying(false);
      }
    } catch (error) {
      console.error('Error playing video:', error);
      // If play() fails, try with muted
      try {
        video.muted = true;
        await video.play();
        setIsPlaying(true);
      } catch (mutedError) {
        console.error('Error playing video even when muted:', mutedError);
      }
    }
  }, []);

  return (
    <div className="group relative aspect-square overflow-hidden rounded-lg border border-gray-200 dark:border-gray-800 bg-gray-100 dark:bg-gray-900">
      {isVideo ? (
        <>
          <video
            ref={videoRef}
            src={uploadedFile.preview}
            className="h-full w-full object-cover"
            playsInline
            preload="metadata"
            onPlay={() => setIsPlaying(true)}
            onPause={() => setIsPlaying(false)}
            onEnded={() => setIsPlaying(false)}
            onLoadedMetadata={() => {
              // Video is ready to play
            }}
          />
          {/* Play/Pause Button Overlay */}
          {uploadedFile.status === 'pending' && (
            <button
              onClick={togglePlay}
              type="button"
              className="absolute inset-0 z-20 flex items-center justify-center bg-black/20 hover:bg-black/30 transition-colors"
              aria-label={isPlaying ? 'Pause video' : 'Play video'}
            >
              {isPlaying ? (
                <Pause className="h-12 w-12 text-white opacity-80" />
              ) : (
                <Play className="h-12 w-12 text-white opacity-80" />
              )}
            </button>
          )}
        </>
      ) : (
        <img
          src={uploadedFile.preview}
          alt={uploadedFile.file.name}
          className="h-full w-full object-cover"
        />
      )}
      {!isVideo && (
        <div className="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors" />
      )}
      
      {/* Status Overlay */}
      {uploadedFile.status !== 'pending' && (
        <div className="absolute inset-0 flex items-center justify-center bg-black/50">
          {uploadedFile.status === 'uploading' && (
            <Loader2 className="h-8 w-8 animate-spin text-white" />
          )}
          {uploadedFile.status === 'success' && (
            <CheckCircle2 className="h-8 w-8 text-green-400" />
          )}
          {uploadedFile.status === 'error' && (
            <AlertCircle className="h-8 w-8 text-red-400" />
          )}
        </div>
      )}

      {/* Remove Button */}
      {uploadedFile.status === 'pending' && (
        <button
          onClick={(e) => {
            e.stopPropagation();
            e.preventDefault();
            onRemove(uploadedFile.id);
          }}
          className="absolute right-2 top-2 z-30 rounded-full bg-red-500 p-1.5 text-white opacity-0 transition-opacity group-hover:opacity-100 hover:bg-red-600"
          aria-label="Remove file"
          type="button"
        >
          <X className="h-4 w-4" />
        </button>
      )}

      {/* File Name */}
      <div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent p-2">
        <p className="truncate text-xs text-white">
          {uploadedFile.file.name}
        </p>
        {uploadedFile.error && (
          <p className="mt-1 text-xs text-red-300">
            {uploadedFile.error}
          </p>
        )}
      </div>
    </div>
  );
}

export function UploadContent() {
  const { data: session } = useSession();
  const [files, setFiles] = useState<UploadedFile[]>([]);
  const [isDragging, setIsDragging] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const fileInputRef = useRef<HTMLInputElement | null>(null);

  const handleFileSelect = useCallback((selectedFiles: FileList | null) => {
    if (!selectedFiles) return;

    const newFiles: UploadedFile[] = Array.from(selectedFiles)
      .filter((file) => file.type.startsWith('image/') || file.type.startsWith('video/'))
      .map((file) => ({
        file,
        preview: URL.createObjectURL(file),
        id: `${Date.now()}-${Math.random()}`,
        status: 'pending' as const,
      }));

    setFiles((prev) => [...prev, ...newFiles]);
  }, []);

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

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

  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      e.stopPropagation();
      setIsDragging(false);
      handleFileSelect(e.dataTransfer.files);
    },
    [handleFileSelect]
  );

  const removeFile = useCallback((id: string) => {
    setFiles((prev) => {
      const file = prev.find((f) => f.id === id);
      if (file) {
        URL.revokeObjectURL(file.preview);
      }
      return prev.filter((f) => f.id !== id);
    });
  }, []);

  const handleSubmit = useCallback(async () => {
    if (files.length === 0 || !session?.user) return;

    setIsSubmitting(true);

    try {
      const formData = new FormData();
      files.forEach((uploadedFile) => {
        formData.append('photos', uploadedFile.file);
      });

      // Update files to uploading status
      setFiles((prev) =>
        prev.map((f) => ({ ...f, status: 'uploading' as const }))
      );

      const response = await fetch('/api/photos/upload', {
        method: 'POST',
        body: formData,
      });

      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.error || 'Failed to upload files');
      }

      const result = await response.json();

      // Update files to success status
      setFiles((prev) =>
        prev.map((f) => ({ ...f, status: 'success' as const }))
      );

      // Clear files after 3 seconds
      setTimeout(() => {
        setFiles((currentFiles) => {
          // Revoke object URLs to free memory
          currentFiles.forEach((f) => URL.revokeObjectURL(f.preview));
          return [];
        });
      }, 3000);
    } catch (error) {
      const errorMessage =
        error instanceof Error ? error.message : 'Failed to upload files';

      // Update files to error status
      setFiles((prev) =>
        prev.map((f) => ({
          ...f,
          status: 'error' as const,
          error: errorMessage,
        }))
      );
    } finally {
      setIsSubmitting(false);
    }
  }, [files, session]);

  const pendingFiles = files.filter((f) => f.status === 'pending');
  const hasPendingFiles = pendingFiles.length > 0;
  const allSuccess = files.length > 0 && files.every((f) => f.status === 'success');

  return (
    <div className="space-y-6">
      {/* Upload Area */}
      <div
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
        className={`relative rounded-lg border-2 border-dashed p-12 text-center transition-colors ${
          isDragging
            ? 'border-primary bg-primary/5'
            : 'border-gray-300 dark:border-gray-700 hover:border-gray-400 dark:hover:border-gray-600'
        }`}
      >
        <input
          type="file"
          id="file-upload"
          ref={fileInputRef}
          multiple
          accept="image/*,video/*"
          className="hidden"
          onChange={(e) => handleFileSelect(e.target.files)}
        />
        <label
          htmlFor="file-upload"
          className="flex cursor-pointer flex-col items-center justify-center space-y-4"
        >
          <Upload
            className={`h-12 w-12 ${
              isDragging
                ? 'text-primary'
                : 'text-gray-400 dark:text-gray-500'
            }`}
          />
          <div>
            <span className="text-lg font-medium text-secondary dark:text-gray-50">
              Drop photos and videos here or click to browse
            </span>
            <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
              Images: JPEG, PNG, GIF, WebP (max 50MB) | Videos: MP4, MOV, AVI, WebM (max 500MB)
            </p>
          </div>
          <Button
            type="button"
            variant="outline"
            size="sm"
            onClick={(event) => {
              event.preventDefault();
              fileInputRef.current?.click();
            }}
          >
            Select Files
          </Button>
        </label>
      </div>

      {/* File List */}
      {files.length > 0 && (
        <div className="space-y-4">
          <div className="flex items-center justify-between">
            <h2 className="text-lg font-semibold text-secondary dark:text-gray-50">
              Selected Files ({files.length})
            </h2>
            {!allSuccess && (
              <Button
                onClick={handleSubmit}
                disabled={!hasPendingFiles || isSubmitting}
                size="sm"
              >
                {isSubmitting ? (
                  <>
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                    Submitting...
                  </>
                ) : (
                  <>
                    <Upload className="mr-2 h-4 w-4" />
                    Submit for Review
                  </>
                )}
              </Button>
            )}
          </div>

          <div className="grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5">
            {files.map((uploadedFile) => (
              <FilePreviewItem
                key={uploadedFile.id}
                uploadedFile={uploadedFile}
                onRemove={removeFile}
              />
            ))}
          </div>

          {allSuccess && (
            <div className="rounded-lg bg-green-50 dark:bg-green-900/20 p-4">
              <div className="flex items-center space-x-2">
                <CheckCircle2 className="h-5 w-5 text-green-600 dark:text-green-400" />
                <p className="text-sm font-medium text-green-800 dark:text-green-200">
                  Files submitted successfully! They are now pending admin review.
                </p>
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

