/**
 * VideoUploadForm Component
 * Multi-step form for uploading educational videos with metadata
 * Epic: OQI-002 Modulo Educativo
 */

import React, { useState, useRef, useCallback, useMemo } from 'react';
import {
  CloudArrowUpIcon,
  DocumentTextIcon,
  PhotoIcon,
  XMarkIcon,
  CheckCircleIcon,
  ExclamationCircleIcon,
  PlayIcon,
  PauseIcon,
  ArrowPathIcon,
} from '@heroicons/react/24/solid';
import { videoUploadService } from '../../../services/video-upload.service';

// Types
export interface VideoMetadata {
  title: string;
  description: string;
  duration?: number;
  thumbnail?: string;
  tags: string[];
  language: string;
  difficulty: 'beginner' | 'intermediate' | 'advanced' | 'expert';
  transcript?: string;
  captions?: { language: string; url: string }[];
}

export interface UploadProgress {
  status: 'idle' | 'uploading' | 'processing' | 'completed' | 'error';
  progress: number;
  message?: string;
  videoId?: string;
}

interface VideoUploadFormProps {
  courseId: string;
  lessonId?: string;
  onUploadComplete?: (videoId: string, metadata: VideoMetadata) => void;
  onCancel?: () => void;
  maxFileSizeMB?: number;
  acceptedFormats?: string[];
  compact?: boolean;
}

const DEFAULT_ACCEPTED_FORMATS = ['video/mp4', 'video/webm', 'video/quicktime'];
const DIFFICULTY_OPTIONS = [
  { value: 'beginner', label: 'Beginner', color: 'text-green-400' },
  { value: 'intermediate', label: 'Intermediate', color: 'text-yellow-400' },
  { value: 'advanced', label: 'Advanced', color: 'text-orange-400' },
  { value: 'expert', label: 'Expert', color: 'text-red-400' },
];

const VideoUploadForm: React.FC<VideoUploadFormProps> = ({
  courseId,
  lessonId,
  onUploadComplete,
  onCancel,
  maxFileSizeMB = 500,
  acceptedFormats = DEFAULT_ACCEPTED_FORMATS,
  compact = false,
}) => {
  // File state
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [thumbnailFile, setThumbnailFile] = useState<File | null>(null);
  const [thumbnailPreview, setThumbnailPreview] = useState<string | null>(null);

  // Metadata state
  const [metadata, setMetadata] = useState<VideoMetadata>({
    title: '',
    description: '',
    tags: [],
    language: 'en',
    difficulty: 'beginner',
  });
  const [tagInput, setTagInput] = useState('');

  // Upload state
  const [uploadProgress, setUploadProgress] = useState<UploadProgress>({
    status: 'idle',
    progress: 0,
  });
  const [currentStep, setCurrentStep] = useState<1 | 2 | 3>(1);
  const [errors, setErrors] = useState<Record<string, string>>({});

  // Refs
  const fileInputRef = useRef<HTMLInputElement>(null);
  const thumbnailInputRef = useRef<HTMLInputElement>(null);
  const videoRef = useRef<HTMLVideoElement>(null);

  // File validation
  const validateFile = useCallback(
    (file: File): string | null => {
      if (!acceptedFormats.includes(file.type)) {
        return `Invalid format. Accepted: ${acceptedFormats.map((f) => f.split('/')[1]).join(', ')}`;
      }
      if (file.size > maxFileSizeMB * 1024 * 1024) {
        return `File too large. Maximum: ${maxFileSizeMB}MB`;
      }
      return null;
    },
    [acceptedFormats, maxFileSizeMB]
  );

  // Handle file selection
  const handleFileSelect = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0];
      if (!file) return;

      const error = validateFile(file);
      if (error) {
        setErrors({ file: error });
        return;
      }

      setSelectedFile(file);
      setErrors({});

      // Create preview URL
      const url = URL.createObjectURL(file);
      setPreviewUrl(url);

      // Auto-fill title from filename
      const nameWithoutExt = file.name.replace(/\.[^/.]+$/, '');
      setMetadata((prev) => ({
        ...prev,
        title: prev.title || nameWithoutExt.replace(/[-_]/g, ' '),
      }));

      // Get video duration
      const video = document.createElement('video');
      video.preload = 'metadata';
      video.onloadedmetadata = () => {
        setMetadata((prev) => ({ ...prev, duration: Math.floor(video.duration) }));
        URL.revokeObjectURL(video.src);
      };
      video.src = url;
    },
    [validateFile]
  );

  // Handle thumbnail selection
  const handleThumbnailSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    if (!file.type.startsWith('image/')) {
      setErrors((prev) => ({ ...prev, thumbnail: 'Please select an image file' }));
      return;
    }

    setThumbnailFile(file);
    setThumbnailPreview(URL.createObjectURL(file));
    setErrors((prev) => {
      const { thumbnail, ...rest } = prev;
      return rest;
    });
  }, []);

  // Handle drag and drop
  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      const file = e.dataTransfer.files[0];
      if (file && file.type.startsWith('video/')) {
        const fakeEvent = {
          target: { files: [file] },
        } as unknown as React.ChangeEvent<HTMLInputElement>;
        handleFileSelect(fakeEvent);
      }
    },
    [handleFileSelect]
  );

  // Handle tag management
  const addTag = useCallback(() => {
    const tag = tagInput.trim().toLowerCase();
    if (tag && !metadata.tags.includes(tag) && metadata.tags.length < 10) {
      setMetadata((prev) => ({ ...prev, tags: [...prev.tags, tag] }));
      setTagInput('');
    }
  }, [tagInput, metadata.tags]);

  const removeTag = useCallback((tag: string) => {
    setMetadata((prev) => ({ ...prev, tags: prev.tags.filter((t) => t !== tag) }));
  }, []);

  // Validate metadata
  const validateMetadata = useCallback((): boolean => {
    const newErrors: Record<string, string> = {};

    if (!metadata.title.trim()) {
      newErrors.title = 'Title is required';
    } else if (metadata.title.length > 100) {
      newErrors.title = 'Title must be less than 100 characters';
    }

    if (!metadata.description.trim()) {
      newErrors.description = 'Description is required';
    } else if (metadata.description.length > 5000) {
      newErrors.description = 'Description must be less than 5000 characters';
    }

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  }, [metadata]);

  // Handle video upload using real API
  const handleUpload = useCallback(async () => {
    if (!selectedFile || !validateMetadata()) return;

    setUploadProgress({ status: 'uploading', progress: 0 });

    try {
      // Upload video using multipart upload service
      const video = await videoUploadService.uploadVideo(
        selectedFile,
        {
          courseId,
          lessonId,
          metadata,
        },
        (progress, status, message) => {
          setUploadProgress({
            status,
            progress,
            message,
            videoId: undefined, // Will be set on completion
          });
        }
      );

      // Upload completed successfully
      setUploadProgress({
        status: 'completed',
        progress: 100,
        message: 'Upload complete! Video is being processed.',
        videoId: video.id,
      });

      onUploadComplete?.(video.id, metadata);
    } catch (error) {
      console.error('Video upload error:', error);
      setUploadProgress({
        status: 'error',
        progress: 0,
        message: error instanceof Error ? error.message : 'Upload failed',
      });
    }
  }, [selectedFile, metadata, validateMetadata, onUploadComplete, courseId, lessonId]);

  // Format file size
  const formatFileSize = (bytes: number): string => {
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  };

  // Format duration
  const formatDuration = (seconds: number): string => {
    const h = Math.floor(seconds / 3600);
    const m = Math.floor((seconds % 3600) / 60);
    const s = seconds % 60;
    if (h > 0) return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
    return `${m}:${s.toString().padStart(2, '0')}`;
  };

  // Step validation
  const canProceedToStep2 = selectedFile !== null;
  const canProceedToStep3 = metadata.title.trim() !== '' && metadata.description.trim() !== '';

  return (
    <div className={`bg-gray-800/50 rounded-lg ${compact ? 'p-3' : 'p-6'}`}>
      {/* Header */}
      <div className="flex items-center justify-between mb-6">
        <div className="flex items-center gap-3">
          <CloudArrowUpIcon className="w-6 h-6 text-blue-400" />
          <h2 className="text-lg font-semibold text-white">Upload Video</h2>
        </div>
        {onCancel && (
          <button
            onClick={onCancel}
            className="p-2 text-gray-400 hover:text-white hover:bg-gray-700 rounded-lg transition-colors"
          >
            <XMarkIcon className="w-5 h-5" />
          </button>
        )}
      </div>

      {/* Progress Steps */}
      <div className="flex items-center gap-4 mb-8">
        {[1, 2, 3].map((step) => (
          <React.Fragment key={step}>
            <div
              className={`flex items-center gap-2 ${
                currentStep >= step ? 'text-blue-400' : 'text-gray-500'
              }`}
            >
              <div
                className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium ${
                  currentStep > step
                    ? 'bg-green-500 text-white'
                    : currentStep === step
                    ? 'bg-blue-500 text-white'
                    : 'bg-gray-700 text-gray-400'
                }`}
              >
                {currentStep > step ? <CheckCircleIcon className="w-5 h-5" /> : step}
              </div>
              <span className="text-sm hidden sm:inline">
                {step === 1 ? 'Select File' : step === 2 ? 'Details' : 'Upload'}
              </span>
            </div>
            {step < 3 && <div className="flex-1 h-px bg-gray-700" />}
          </React.Fragment>
        ))}
      </div>

      {/* Step 1: File Selection */}
      {currentStep === 1 && (
        <div className="space-y-4">
          {!selectedFile ? (
            <div
              onDrop={handleDrop}
              onDragOver={(e) => e.preventDefault()}
              onClick={() => fileInputRef.current?.click()}
              className="border-2 border-dashed border-gray-600 rounded-lg p-8 text-center hover:border-blue-500 hover:bg-gray-700/30 transition-colors cursor-pointer"
            >
              <CloudArrowUpIcon className="w-12 h-12 mx-auto text-gray-400 mb-4" />
              <p className="text-white font-medium mb-2">Drop your video here or click to browse</p>
              <p className="text-gray-400 text-sm">
                Accepted formats: {acceptedFormats.map((f) => f.split('/')[1].toUpperCase()).join(', ')}
              </p>
              <p className="text-gray-500 text-sm mt-1">Maximum size: {maxFileSizeMB}MB</p>
            </div>
          ) : (
            <div className="bg-gray-900/50 rounded-lg p-4">
              <div className="flex items-start gap-4">
                {/* Video Preview */}
                <div className="relative w-48 aspect-video bg-black rounded-lg overflow-hidden flex-shrink-0">
                  {previewUrl && (
                    <video
                      ref={videoRef}
                      src={previewUrl}
                      className="w-full h-full object-cover"
                      muted
                    />
                  )}
                  <div className="absolute inset-0 flex items-center justify-center bg-black/30">
                    <PlayIcon className="w-10 h-10 text-white/80" />
                  </div>
                </div>

                {/* File Info */}
                <div className="flex-1 min-w-0">
                  <p className="text-white font-medium truncate">{selectedFile.name}</p>
                  <p className="text-gray-400 text-sm mt-1">
                    {formatFileSize(selectedFile.size)}
                    {metadata.duration && ` • ${formatDuration(metadata.duration)}`}
                  </p>
                  <button
                    onClick={() => {
                      setSelectedFile(null);
                      setPreviewUrl(null);
                    }}
                    className="text-red-400 text-sm mt-2 hover:underline"
                  >
                    Remove
                  </button>
                </div>
              </div>
            </div>
          )}

          <input
            ref={fileInputRef}
            type="file"
            accept={acceptedFormats.join(',')}
            onChange={handleFileSelect}
            className="hidden"
          />

          {errors.file && (
            <div className="flex items-center gap-2 text-red-400 text-sm">
              <ExclamationCircleIcon className="w-4 h-4" />
              {errors.file}
            </div>
          )}

          <div className="flex justify-end">
            <button
              onClick={() => setCurrentStep(2)}
              disabled={!canProceedToStep2}
              className="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
            >
              Continue
            </button>
          </div>
        </div>
      )}

      {/* Step 2: Metadata */}
      {currentStep === 2 && (
        <div className="space-y-4">
          {/* Title */}
          <div>
            <label className="block text-sm font-medium text-gray-300 mb-1">Title *</label>
            <input
              type="text"
              value={metadata.title}
              onChange={(e) => setMetadata((prev) => ({ ...prev, title: e.target.value }))}
              placeholder="Enter video title"
              className={`w-full bg-gray-900/50 border ${
                errors.title ? 'border-red-500' : 'border-gray-700'
              } rounded-lg px-4 py-2 text-white placeholder-gray-500 focus:border-blue-500 focus:outline-none`}
            />
            {errors.title && <p className="text-red-400 text-sm mt-1">{errors.title}</p>}
          </div>

          {/* Description */}
          <div>
            <label className="block text-sm font-medium text-gray-300 mb-1">Description *</label>
            <textarea
              value={metadata.description}
              onChange={(e) => setMetadata((prev) => ({ ...prev, description: e.target.value }))}
              placeholder="Enter video description"
              rows={4}
              className={`w-full bg-gray-900/50 border ${
                errors.description ? 'border-red-500' : 'border-gray-700'
              } rounded-lg px-4 py-2 text-white placeholder-gray-500 focus:border-blue-500 focus:outline-none resize-none`}
            />
            {errors.description && <p className="text-red-400 text-sm mt-1">{errors.description}</p>}
          </div>

          {/* Thumbnail */}
          <div>
            <label className="block text-sm font-medium text-gray-300 mb-1">Thumbnail</label>
            <div className="flex items-center gap-4">
              {thumbnailPreview ? (
                <div className="relative w-32 aspect-video rounded-lg overflow-hidden">
                  <img src={thumbnailPreview} alt="Thumbnail" className="w-full h-full object-cover" />
                  <button
                    onClick={() => {
                      setThumbnailFile(null);
                      setThumbnailPreview(null);
                    }}
                    className="absolute top-1 right-1 p-1 bg-black/50 rounded-full hover:bg-black/70"
                  >
                    <XMarkIcon className="w-3 h-3 text-white" />
                  </button>
                </div>
              ) : (
                <button
                  onClick={() => thumbnailInputRef.current?.click()}
                  className="w-32 aspect-video border-2 border-dashed border-gray-600 rounded-lg flex items-center justify-center hover:border-blue-500 transition-colors"
                >
                  <PhotoIcon className="w-8 h-8 text-gray-500" />
                </button>
              )}
              <input
                ref={thumbnailInputRef}
                type="file"
                accept="image/*"
                onChange={handleThumbnailSelect}
                className="hidden"
              />
            </div>
          </div>

          {/* Difficulty & Language */}
          <div className="grid grid-cols-2 gap-4">
            <div>
              <label className="block text-sm font-medium text-gray-300 mb-1">Difficulty</label>
              <select
                value={metadata.difficulty}
                onChange={(e) =>
                  setMetadata((prev) => ({
                    ...prev,
                    difficulty: e.target.value as VideoMetadata['difficulty'],
                  }))
                }
                className="w-full bg-gray-900/50 border border-gray-700 rounded-lg px-4 py-2 text-white focus:border-blue-500 focus:outline-none"
              >
                {DIFFICULTY_OPTIONS.map((opt) => (
                  <option key={opt.value} value={opt.value}>
                    {opt.label}
                  </option>
                ))}
              </select>
            </div>
            <div>
              <label className="block text-sm font-medium text-gray-300 mb-1">Language</label>
              <select
                value={metadata.language}
                onChange={(e) => setMetadata((prev) => ({ ...prev, language: e.target.value }))}
                className="w-full bg-gray-900/50 border border-gray-700 rounded-lg px-4 py-2 text-white focus:border-blue-500 focus:outline-none"
              >
                <option value="en">English</option>
                <option value="es">Spanish</option>
                <option value="fr">French</option>
                <option value="de">German</option>
                <option value="pt">Portuguese</option>
              </select>
            </div>
          </div>

          {/* Tags */}
          <div>
            <label className="block text-sm font-medium text-gray-300 mb-1">Tags</label>
            <div className="flex flex-wrap gap-2 mb-2">
              {metadata.tags.map((tag) => (
                <span
                  key={tag}
                  className="inline-flex items-center gap-1 px-2 py-1 bg-blue-500/20 text-blue-400 rounded text-sm"
                >
                  {tag}
                  <button onClick={() => removeTag(tag)} className="hover:text-blue-300">
                    <XMarkIcon className="w-3 h-3" />
                  </button>
                </span>
              ))}
            </div>
            <div className="flex gap-2">
              <input
                type="text"
                value={tagInput}
                onChange={(e) => setTagInput(e.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), addTag())}
                placeholder="Add a tag..."
                className="flex-1 bg-gray-900/50 border border-gray-700 rounded-lg px-4 py-2 text-white placeholder-gray-500 focus:border-blue-500 focus:outline-none text-sm"
              />
              <button
                onClick={addTag}
                disabled={!tagInput.trim() || metadata.tags.length >= 10}
                className="px-4 py-2 bg-gray-700 text-white rounded-lg hover:bg-gray-600 disabled:opacity-50 text-sm"
              >
                Add
              </button>
            </div>
          </div>

          <div className="flex justify-between pt-4">
            <button
              onClick={() => setCurrentStep(1)}
              className="px-6 py-2 bg-gray-700 text-white rounded-lg hover:bg-gray-600 transition-colors"
            >
              Back
            </button>
            <button
              onClick={() => validateMetadata() && setCurrentStep(3)}
              disabled={!canProceedToStep3}
              className="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
            >
              Continue
            </button>
          </div>
        </div>
      )}

      {/* Step 3: Upload */}
      {currentStep === 3 && (
        <div className="space-y-6">
          {/* Summary */}
          <div className="bg-gray-900/50 rounded-lg p-4 space-y-3">
            <h3 className="text-white font-medium">Upload Summary</h3>
            <div className="grid grid-cols-2 gap-4 text-sm">
              <div>
                <span className="text-gray-400">Title:</span>
                <p className="text-white truncate">{metadata.title}</p>
              </div>
              <div>
                <span className="text-gray-400">File:</span>
                <p className="text-white truncate">{selectedFile?.name}</p>
              </div>
              <div>
                <span className="text-gray-400">Duration:</span>
                <p className="text-white">
                  {metadata.duration ? formatDuration(metadata.duration) : 'Unknown'}
                </p>
              </div>
              <div>
                <span className="text-gray-400">Difficulty:</span>
                <p className="text-white capitalize">{metadata.difficulty}</p>
              </div>
            </div>
          </div>

          {/* Upload Progress */}
          {uploadProgress.status !== 'idle' && (
            <div className="space-y-3">
              <div className="flex items-center justify-between">
                <span className="text-sm text-gray-400">{uploadProgress.message}</span>
                <span className="text-sm text-white">{uploadProgress.progress}%</span>
              </div>
              <div className="h-2 bg-gray-700 rounded-full overflow-hidden">
                <div
                  className={`h-full transition-all duration-300 ${
                    uploadProgress.status === 'error'
                      ? 'bg-red-500'
                      : uploadProgress.status === 'completed'
                      ? 'bg-green-500'
                      : 'bg-blue-500'
                  }`}
                  style={{ width: `${uploadProgress.progress}%` }}
                />
              </div>
            </div>
          )}

          {/* Status Icons */}
          {uploadProgress.status === 'completed' && (
            <div className="flex items-center gap-3 text-green-400">
              <CheckCircleIcon className="w-6 h-6" />
              <span>Video uploaded successfully!</span>
            </div>
          )}

          {uploadProgress.status === 'error' && (
            <div className="flex items-center gap-3 text-red-400">
              <ExclamationCircleIcon className="w-6 h-6" />
              <span>{uploadProgress.message}</span>
            </div>
          )}

          <div className="flex justify-between pt-4">
            <button
              onClick={() => setCurrentStep(2)}
              disabled={uploadProgress.status === 'uploading' || uploadProgress.status === 'processing'}
              className="px-6 py-2 bg-gray-700 text-white rounded-lg hover:bg-gray-600 disabled:opacity-50 transition-colors"
            >
              Back
            </button>
            <button
              onClick={handleUpload}
              disabled={
                uploadProgress.status === 'uploading' ||
                uploadProgress.status === 'processing' ||
                uploadProgress.status === 'completed'
              }
              className="px-6 py-2 bg-green-600 text-white rounded-lg hover:bg-green-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-2"
            >
              {uploadProgress.status === 'uploading' || uploadProgress.status === 'processing' ? (
                <>
                  <ArrowPathIcon className="w-4 h-4 animate-spin" />
                  {uploadProgress.status === 'uploading' ? 'Uploading...' : 'Processing...'}
                </>
              ) : uploadProgress.status === 'completed' ? (
                <>
                  <CheckCircleIcon className="w-4 h-4" />
                  Done
                </>
              ) : (
                <>
                  <CloudArrowUpIcon className="w-4 h-4" />
                  Upload Video
                </>
              )}
            </button>
          </div>
        </div>
      )}
    </div>
  );
};

export default VideoUploadForm;
