import React, { useState, useRef } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Progress } from '@/components/ui/progress';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog';
import { Upload, X, Music, FileAudio } from 'lucide-react';
import { apiService, type AddTrackRequest } from '@/services/api';
import { useToast } from '@/hooks/use-toast';

interface UploadModalProps {
  onUploadComplete?: () => void;
  children?: React.ReactNode;
  isOpen?: boolean;
  onClose?: () => void;
}

export function UploadModal({ onUploadComplete, children, isOpen: controlledIsOpen, onClose }: UploadModalProps) {
  const [internalOpen, setInternalOpen] = useState(false);
  
  // Use controlled state if provided, otherwise use internal state
  const open = controlledIsOpen !== undefined ? controlledIsOpen : internalOpen;
  const handleOpenChange = (newOpen: boolean) => {
    if (onClose && !newOpen) {
      // Controlled mode: call onClose when dialog should close
      onClose();
    } else {
      // Uncontrolled mode: use internal state
      setInternalOpen(newOpen);
    }
  };
  const [uploading, setUploading] = useState(false);
  const [progress, setProgress] = useState(0);
  const [formData, setFormData] = useState({
    title: '',
    artist: '',
    album: '',
  });
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const { toast } = useToast();

  const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      // Validate file type
      const allowedTypes = ['audio/mpeg', 'audio/mp3', 'audio/wav', 'audio/flac', 'audio/aac', 'audio/ogg'];
      if (!allowedTypes.includes(file.type)) {
        toast({
          title: 'Invalid file type',
          description: 'Please select an audio file (MP3, WAV, FLAC, AAC, OGG)',
          variant: 'destructive',
        });
        return;
      }

      // Validate file size (500MB max)
      const maxSize = 500 * 1024 * 1024; // 500MB
      if (file.size > maxSize) {
        toast({
          title: 'File too large',
          description: 'Please select a file smaller than 500MB',
          variant: 'destructive',
        });
        return;
      }

      setSelectedFile(file);
      
      // Auto-fill title if empty
      if (!formData.title) {
        const fileName = file.name.replace(/\.[^/.]+$/, ''); // Remove extension
        setFormData(prev => ({ ...prev, title: fileName }));
      }
    }
  };

  const handleInputChange = (field: keyof typeof formData) => (
    event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    setFormData(prev => ({ ...prev, [field]: event.target.value }));
  };

  const handleUpload = async () => {
    if (!selectedFile || !formData.title || !formData.artist) {
      toast({
        title: 'Missing information',
        description: 'Please fill in all required fields and select a file',
        variant: 'destructive',
      });
      return;
    }

    setUploading(true);
    setProgress(0);

    try {
      // Simulate progress
      const progressInterval = setInterval(() => {
        setProgress(prev => {
          if (prev >= 90) {
            clearInterval(progressInterval);
            return prev;
          }
          return prev + Math.random() * 10;
        });
      }, 200);

      const trackData: AddTrackRequest = {
        title: formData.title,
        artist: formData.artist,
        album: formData.album || undefined,
        file: selectedFile,
      };

      const result = await apiService.uploadTrack(trackData);
      
      clearInterval(progressInterval);
      setProgress(100);

      toast({
        title: 'Upload successful',
        description: result.message,
      });

      // Reset form
      setFormData({ title: '', artist: '', album: '' });
      setSelectedFile(null);
      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
      // Close modal
      if (onClose) {
        onClose();
      } else {
        setInternalOpen(false);
      }
      
      // Notify parent component
      onUploadComplete?.();

    } catch (error: any) {
      console.error('Upload failed:', error);
      toast({
        title: 'Upload failed',
        description: error.response?.data?.error || error.message || 'An error occurred during upload',
        variant: 'destructive',
      });
    } finally {
      setUploading(false);
      setProgress(0);
    }
  };

  const handleCancel = () => {
    if (!uploading) {
      setFormData({ title: '', artist: '', album: '' });
      setSelectedFile(null);
      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
      // Close modal properly
      if (onClose) {
        onClose();
      } else {
        setInternalOpen(false);
      }
    }
  };

  const formatFileSize = (bytes: number): string => {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))  } ${  sizes[i]}`;
  };

  // Render dialog content
  const dialogContent = (
    <DialogContent className="sm:max-w-[500px]">
        <DialogHeader>
          <DialogTitle>Upload New Track</DialogTitle>
          <DialogDescription>
            Upload an audio file to add it to your library. Supported formats: MP3, WAV, FLAC, AAC, OGG
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          {/* File Selection */}
          <div className="space-y-2">
            <Label htmlFor="file">Audio File *</Label>
            <div className="flex items-center space-x-2">
              <Input
                ref={fileInputRef}
                id="file"
                type="file"
                accept="audio/*"
                onChange={handleFileSelect}
                disabled={uploading}
                className="flex-1"
              />
              {selectedFile && (
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => {
                    setSelectedFile(null);
                    if (fileInputRef.current) {
                      fileInputRef.current.value = '';
                    }
                  }}
                  disabled={uploading}
                >
                  <X className="w-4 h-4" />
                </Button>
              )}
            </div>
            {selectedFile && (
              <div className="flex items-center space-x-2 text-sm text-muted-foreground">
                <FileAudio className="w-4 h-4" />
                <span>{selectedFile.name}</span>
                <span>({formatFileSize(selectedFile.size)})</span>
              </div>
            )}
          </div>

          {/* Track Information */}
          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label htmlFor="title">Title *</Label>
              <Input
                id="title"
                value={formData.title}
                onChange={handleInputChange('title')}
                placeholder="Track title"
                disabled={uploading}
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="artist">Artist *</Label>
              <Input
                id="artist"
                value={formData.artist}
                onChange={handleInputChange('artist')}
                placeholder="Artist name"
                disabled={uploading}
              />
            </div>
          </div>

          <div className="space-y-2">
            <Label htmlFor="album">Album</Label>
            <Input
              id="album"
              value={formData.album}
              onChange={handleInputChange('album')}
              placeholder="Album name (optional)"
              disabled={uploading}
            />
          </div>

          {/* Upload Progress */}
          {uploading && (
            <div className="space-y-2">
              <div className="flex items-center justify-between text-sm">
                <span>Uploading...</span>
                <span>{Math.round(progress)}%</span>
              </div>
              <Progress value={progress} className="w-full" />
            </div>
          )}
        </div>

        <DialogFooter>
          <Button
            variant="outline"
            onClick={handleCancel}
            disabled={uploading}
          >
            Cancel
          </Button>
          <Button
            onClick={handleUpload}
            disabled={uploading || !selectedFile || !formData.title || !formData.artist}
          >
            {uploading ? (
              <>
                <Music className="w-4 h-4 mr-2 animate-spin" />
                Uploading...
              </>
            ) : (
              <>
                <Upload className="w-4 h-4 mr-2" />
                Upload Track
              </>
            )}
          </Button>
        </DialogFooter>
      </DialogContent>
  );

  // Return based on mode (controlled vs uncontrolled)
  if (children) {
    // Uncontrolled mode with trigger
    return (
      <Dialog open={open} onOpenChange={handleOpenChange}>
        <DialogTrigger asChild>
          {children}
        </DialogTrigger>
        {dialogContent}
      </Dialog>
    );
  }

  // Controlled mode without trigger
  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      {dialogContent}
    </Dialog>
  );
}
