import { SimpleIconButton } from '@simpledotstudio/simple-icon-button'
import { SimpleImage } from '@simpledotstudio/simple-image'
import { SimpleLoader } from '@simpledotstudio/simple-loader'
import { SimpleText } from '@simpledotstudio/simple-text'
import React, { useState, useRef, useEffect, useMemo } from 'react'

import styles from './SimpleMediaPreview.module.scss'

export type MediaType = 'image' | 'video' | 'audio' | 'unknown'

export interface SimpleMediaPreviewProps {
  /** The media source URL or File object */
  src: string | File
  /** Alternative text for images */
  alt?: string
  /** Type of media (auto-detected if not provided) */
  type?: MediaType
  /** Show controls for video/audio */
  controls?: boolean
  /** Autoplay video/audio (muted only for video) */
  autoplay?: boolean
  /** Loop video/audio playback */
  loop?: boolean
  /** Thumbnail URL for video/audio */
  thumbnail?: string
  /** Custom class name */
  className?: string
  /** Width of the media container */
  width?: number | string
  /** Height of the media container */
  height?: number | string
  /** Aspect ratio for responsive sizing */
  aspectRatio?: '16/9' | '4/3' | '1/1' | '9/16' | 'auto'
  /** Show loading state */
  loading?: boolean
  /** Error handler */
  onError?: (error: Error) => void
  /** Click handler */
  onClick?: () => void
  /** Play state change handler */
  onPlayStateChange?: (playing: boolean) => void
}

export const SimpleMediaPreview: React.FC<SimpleMediaPreviewProps> = ({
  src,
  alt = 'Media preview',
  type: providedType,
  controls = true,
  autoplay = false,
  loop = false,
  thumbnail,
  className = '',
  width,
  height,
  aspectRatio = 'auto',
  loading = false,
  onError,
  onClick,
  onPlayStateChange,
}) => {
  const [playing, setPlaying] = useState(false)
  const [duration, setDuration] = useState(0)
  const [currentTime, setCurrentTime] = useState(0)
  const [mediaError, setMediaError] = useState(false)
  const [mediaLoading, setMediaLoading] = useState(true)
  
  const videoRef = useRef<HTMLVideoElement>(null)
  const audioRef = useRef<HTMLAudioElement>(null)

  // Create object URL for File objects
  const mediaUrl = useMemo(() => {
    if (typeof src === 'string') return src
    return URL.createObjectURL(src)
  }, [src])

  // Clean up object URL
  useEffect(() => {
    return () => {
      if (typeof src !== 'string' && mediaUrl) {
        URL.revokeObjectURL(mediaUrl)
      }
    }
  }, [src, mediaUrl])

  // Detect media type
  const mediaType = useMemo<MediaType>(() => {
    if (providedType) return providedType
    
    if (typeof src === 'string') {
      const ext = src.split('.').pop()?.toLowerCase()
      if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'].includes(ext || '')) return 'image'
      if (['mp4', 'webm', 'ogg', 'mov'].includes(ext || '')) return 'video'
      if (['mp3', 'wav', 'ogg', 'aac', 'm4a'].includes(ext || '')) return 'audio'
    } else if (src instanceof File) {
      if (src.type.startsWith('image/')) return 'image'
      if (src.type.startsWith('video/')) return 'video'
      if (src.type.startsWith('audio/')) return 'audio'
    }
    
    return 'unknown'
  }, [src, providedType])

  // Handle play/pause
  const togglePlayPause = () => {
    const media = mediaType === 'video' ? videoRef.current : audioRef.current
    if (!media) return

    if (playing) {
      media.pause()
    } else {
      media.play().catch(err => {
        console.error('Playback failed:', err)
        if (onError) onError(err)
      })
    }
  }

  // Update play state
  useEffect(() => {
    onPlayStateChange?.(playing)
  }, [playing, onPlayStateChange])

  // Handle media events
  const handleLoadedMetadata = () => {
    const media = mediaType === 'video' ? videoRef.current : audioRef.current
    if (media) {
      setDuration(media.duration)
      setMediaLoading(false)
    }
  }

  const handleTimeUpdate = () => {
    const media = mediaType === 'video' ? videoRef.current : audioRef.current
    if (media) {
      setCurrentTime(media.currentTime)
    }
  }

  const handleError = () => {
    setMediaError(true)
    setMediaLoading(false)
    if (onError) {
      onError(new Error(`Failed to load ${mediaType}`))
    }
  }

  // Format time for display
  const formatTime = (seconds: number) => {
    const mins = Math.floor(seconds / 60)
    const secs = Math.floor(seconds % 60)
    return `${mins}:${secs.toString().padStart(2, '0')}`
  }

  const containerStyle: React.CSSProperties = {
    width,
    height,
  }

  const classes = [
    styles.simpleMediaPreview,
    styles[`ratio-${aspectRatio.replace('/', '-')}`],
    mediaError && styles.error,
    className
  ].filter(Boolean).join(' ')

  // Render error state
  if (mediaError) {
    return (
      <div 
        className={classes} 
        style={containerStyle} 
        onClick={onClick}
        role={onClick ? "button" : undefined}
        tabIndex={onClick ? 0 : undefined}
        onKeyDown={onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onClick(); } } : undefined}>
        <div className={styles.errorState}>
          <SimpleIconButton icon="exclamation-circle" size="large" disabled />
          <SimpleText as="p" size="small" variant="secondary">
            Failed to load {mediaType}
          </SimpleText>
        </div>
      </div>
    )
  }

  // Render loading state
  if (loading || (mediaLoading && mediaType !== 'image')) {
    return (
      <div className={classes} style={containerStyle}>
        <div className={styles.loadingState}>
          <SimpleLoader size="medium" />
        </div>
      </div>
    )
  }

  // Render image
  if (mediaType === 'image') {
    return (
      <div 
        className={classes} 
        style={containerStyle} 
        onClick={onClick}
        role={onClick ? "button" : undefined}
        tabIndex={onClick ? 0 : undefined}
        onKeyDown={onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onClick(); } } : undefined}>
        <SimpleImage
          src={mediaUrl}
          alt={alt}
          fill
          showSkeleton={false}
          onError={handleError}
        />
      </div>
    )
  }

  // Render video
  if (mediaType === 'video') {
    return (
      <div 
        className={classes} 
        style={containerStyle} 
        onClick={onClick}
        role={onClick ? "button" : undefined}
        tabIndex={onClick ? 0 : undefined}
        onKeyDown={onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onClick(); } } : undefined}>
        <video
          ref={videoRef}
          src={mediaUrl}
          poster={thumbnail}
          autoPlay={autoplay}
          loop={loop}
          muted={autoplay} // Required for autoplay
          playsInline
          onLoadedMetadata={handleLoadedMetadata}
          onTimeUpdate={handleTimeUpdate}
          onPlay={() => setPlaying(true)}
          onPause={() => setPlaying(false)}
          onEnded={() => setPlaying(false)}
          onError={handleError}
          className={styles.media}
        >
          <track kind="captions" />
        </video>
        {controls && (
          <div className={styles.controls}>
            <SimpleIconButton
              icon={playing ? 'pause-fill' : 'play-fill'}
              size="medium"
              variant="primary"
              onClick={(e) => {
                e.stopPropagation()
                togglePlayPause()
              }}
              className={styles.playButton}
            />
            {duration > 0 && (
              <div className={styles.timeDisplay}>
                <SimpleText as="span" size="small">
                  {formatTime(currentTime)} / {formatTime(duration)}
                </SimpleText>
              </div>
            )}
          </div>
        )}
      </div>
    )
  }

  // Render audio
  if (mediaType === 'audio') {
    return (
      <div 
        className={classes} 
        style={containerStyle} 
        onClick={onClick}
        role={onClick ? "button" : undefined}
        tabIndex={onClick ? 0 : undefined}
        onKeyDown={onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onClick(); } } : undefined}>
        <audio
          ref={audioRef}
          src={mediaUrl}
          autoPlay={autoplay}
          loop={loop}
          onLoadedMetadata={handleLoadedMetadata}
          onTimeUpdate={handleTimeUpdate}
          onPlay={() => setPlaying(true)}
          onPause={() => setPlaying(false)}
          onEnded={() => setPlaying(false)}
          onError={handleError}
        >
          <track kind="captions" />
        </audio>
        <div className={styles.audioPlayer}>
          {thumbnail && (
            <div className={styles.audioThumbnail}>
              <SimpleImage src={thumbnail} alt="Album art" fill />
            </div>
          )}
          <div className={styles.audioControls}>
            <SimpleIconButton
              icon={playing ? 'pause-circle-fill' : 'play-circle-fill'}
              size="large"
              variant="primary"
              onClick={(e) => {
                e.stopPropagation()
                togglePlayPause()
              }}
            />
            <div className={styles.audioInfo}>
              <SimpleText as="p" size="medium" weight="medium">
                {alt || 'Audio file'}
              </SimpleText>
              {duration > 0 && (
                <SimpleText as="p" size="small" variant="secondary">
                  {formatTime(currentTime)} / {formatTime(duration)}
                </SimpleText>
              )}
            </div>
          </div>
        </div>
      </div>
    )
  }

  // Unknown media type
  return (
    <div 
      className={classes} 
      style={containerStyle} 
      onClick={onClick}
      role={onClick ? "button" : undefined}
      tabIndex={onClick ? 0 : undefined}
      onKeyDown={onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onClick(); } } : undefined}>
      <div className={styles.unknownState}>
        <SimpleIconButton icon="file-earmark" size="large" disabled />
        <SimpleText as="p" size="small" variant="secondary">
          Unknown media type
        </SimpleText>
      </div>
    </div>
  )
}