'use client';

import { observer } from 'mobx-react-lite';
import { useEffect, useRef, useState } from 'react';
import { useDropzone } from 'react-dropzone';

import Button, { ButtonVariant } from '@/components/button/Button';
import {
  DISPLAY_HEIGHT,
  DISPLAY_WIDTH,
} from '@/components/modal/editClipMetadata/constants';
import ModalHeader from '@/components/modal/publishSong/ModalHeader';
import PublishModalFooter from '@/components/modal/publishSong/PublishModalFooter';
import { toast } from '@/components/toast/Toast';
import { Tooltip } from '@/components/tooltip/Tooltip';
import { TrashIcon, UploadIcon } from '@/icons';

type MediaType = 'image' | 'video' | null;

export const AddMediaModalContent = observer(
  ({
    onMediaSelect,
    selectedMedia,
    mediaType: initialMediaType,
    onClose,
    onCancel,
    onSave,
    onGenerateCoverArt,
    showBackButton = false,
  }: {
    onMediaSelect: (file: File | null, type: MediaType) => void;
    selectedMedia?: File | null;
    mediaType?: MediaType;
    onClose: () => void;
    onCancel: () => void;
    onSave: () => void;
    onGenerateCoverArt?: () => void;
    showBackButton?: boolean;
  }) => {
    const [mediaType, setMediaType] = useState<MediaType>(
      initialMediaType || null
    );
    const [previewUrl, setPreviewUrl] = useState<string | null>(null);
    const videoRef = useRef<HTMLVideoElement>(null);

    const getMediaType = (file: File): MediaType => {
      if (file.type.startsWith('image/')) return 'image';
      if (file.type.startsWith('video/')) return 'video';
      return null;
    };

    const handleMediaDrop = async (files: File[]) => {
      if (!files?.[0]) return;

      const file = files[0];
      const type = getMediaType(file);

      if (!type) {
        toast({
          title: 'Invalid file type',
          description:
            'Please upload an image (JPG, PNG, WEBP) or video (MP4, MOV)',
          status: 'error',
          duration: 4000,
          isClosable: true,
        });
        return;
      }

      // Video-specific validation
      if (type === 'video') {
        const video = document.createElement('video');
        video.preload = 'metadata';

        try {
          const duration = await new Promise<number>((resolve) => {
            video.onloadedmetadata = () => {
              const duration = video.duration;
              URL.revokeObjectURL(video.src);
              resolve(duration);
            };
            video.src = URL.createObjectURL(file);
          });

          if (duration >= 11) {
            toast({
              title: 'Video too long',
              description:
                'Please upload a video that is 10 seconds or shorter',
              status: 'error',
              duration: 4000,
              isClosable: true,
            });
            return;
          }

          if (duration < 1) {
            toast({
              title: 'Video too short',
              description:
                'Please upload a video that is at least 1 second long',
              status: 'error',
              duration: 4000,
              isClosable: true,
            });
            return;
          }
        } catch (error) {
          console.error('Error checking video duration:', error);
          toast({
            title: 'Error',
            description: 'Failed to validate video',
            status: 'error',
            duration: 4000,
            isClosable: true,
          });
          return;
        }
      }

      // Create preview URL
      const objectUrl = URL.createObjectURL(file);
      setPreviewUrl(objectUrl);
      setMediaType(type);
      onMediaSelect(file, type);
    };

    const { getRootProps, getInputProps, isDragActive } = useDropzone({
      accept: {
        'image/jpeg': ['.jpg', '.jpeg'],
        'image/png': ['.png'],
        'image/webp': ['.webp'],
        'video/mp4': ['.mp4'],
        'video/quicktime': ['.mov'],
      },
      maxFiles: 1,
      onDrop: handleMediaDrop,
    });

    const handleRemove = () => {
      if (previewUrl) {
        URL.revokeObjectURL(previewUrl);
      }
      setPreviewUrl(null);
      setMediaType(null);
      onMediaSelect(null, null);
    };

    // Cleanup object URL on unmount or when previewUrl changes
    useEffect(() => {
      return () => {
        if (previewUrl) {
          URL.revokeObjectURL(previewUrl);
        }
      };
    }, [previewUrl]);

    return (
      <div className='flex h-full w-full flex-col justify-between'>
        <ModalHeader
          title='Add Photo/Video'
          onBack={showBackButton ? onCancel : undefined}
          onClose={onClose}
        />
        <div className='flex flex-1 flex-col items-center justify-center overflow-y-auto'>
          <div className='flex flex-col items-center gap-4 p-6 md:flex-row'>
            {/* Media Preview/Uploader */}
            <div className='flex shrink-0 flex-col items-center gap-4'>
              {selectedMedia && previewUrl ? (
                // Preview selected media
                <div className='relative'>
                  {mediaType === 'image' ? (
                    <img
                      src={previewUrl}
                      alt='Preview'
                      style={{
                        width: DISPLAY_WIDTH,
                        height: DISPLAY_HEIGHT,
                        objectFit: 'cover',
                      }}
                      className='rounded'
                    />
                  ) : (
                    <video
                      ref={videoRef}
                      src={previewUrl}
                      controls
                      style={{
                        width: DISPLAY_WIDTH,
                        height: DISPLAY_HEIGHT,
                        objectFit: 'cover',
                      }}
                      className='rounded'
                    />
                  )}
                  <Button
                    variant={ButtonVariant.Secondary}
                    onClick={handleRemove}
                    className='absolute top-2 right-2'
                    aria-label='Remove media'
                  >
                    <TrashIcon className='h-5 w-5' />
                  </Button>
                </div>
              ) : (
                // Upload dropzone
                <div
                  {...getRootProps()}
                  style={{
                    width: DISPLAY_WIDTH,
                    height: DISPLAY_HEIGHT,
                  }}
                  className={`relative flex cursor-pointer flex-col items-center justify-center rounded border-1 ${
                    isDragActive
                      ? 'border-border-active bg-background-fog-thin'
                      : 'border-border-primary bg-background-fog-thin'
                  }`}
                >
                  <input {...getInputProps()} />
                  <UploadIcon className='text-foreground-active mb-4 h-8 w-8' />
                  <p className='text-foreground-active text-center text-sm'>
                    {isDragActive
                      ? 'Drop file here to upload a photo or video'
                      : 'Drag & drop or click to upload a photo or video'}
                  </p>
                  <Tooltip
                    label={
                      <div className='text-left'>
                        <div className='mb-1 font-semibold'>
                          File requirements
                        </div>
                        <ul className='list-disc space-y-0.5 pl-4'>
                          <li>MP4, MOV, JPG, PNG, WEBP files</li>
                          <li>At least 720px tall</li>
                          <li>9x16 aspect ratio</li>
                          <li>Videos must be 10 seconds long or less</li>
                          <li>Compliant with our policies</li>
                        </ul>
                      </div>
                    }
                    placement='top'
                  >
                    <p className='absolute bottom-4 cursor-help text-center text-xs text-foreground-tertiary underline'>
                      Cover Art Guidelines
                    </p>
                  </Tooltip>
                </div>
              )}
              {onGenerateCoverArt && (
                <Button
                  onClick={onGenerateCoverArt}
                  variant={ButtonVariant.Secondary}
                  style={{ width: DISPLAY_WIDTH }}
                >
                  Generate Cover Art
                </Button>
              )}
            </div>
          </div>
        </div>

        <PublishModalFooter>
          <Button variant={ButtonVariant.Secondary} onClick={onCancel}>
            Cancel
          </Button>
          <Button
            variant={ButtonVariant.Primary}
            onClick={onSave}
            className='px-6'
            disabled={!selectedMedia}
          >
            Save
          </Button>
        </PublishModalFooter>
      </div>
    );
  }
);
