import React, { useState, useEffect } from 'react'
import { Image, View, StyleSheet } from 'react-native'

interface Props {
  uri: string
  originalWidth?: number
  originalHeight?: number
  minWidth?: number
  maxWidth?: number
  minHeight?: number
  maxHeight?: number
  borderRadius?: number
  style?: object
}

function computeDimensions(
  srcWidth: number,
  srcHeight: number,
  minWidth: number,
  maxWidth: number,
  minHeight: number,
  maxHeight: number,
): { width: number; height: number } {
  if (srcWidth <= 0 || srcHeight <= 0) {
    return { width: minWidth, height: minHeight }
  }

  const aspectRatio = srcWidth / srcHeight

  // Start from maxWidth and compute height
  let width = maxWidth
  let height = width / aspectRatio

  // If height exceeds maxHeight, clamp by height
  if (height > maxHeight) {
    height = maxHeight
    width = height * aspectRatio
  }

  // Enforce minimums
  if (width < minWidth) {
    width = minWidth
    height = width / aspectRatio
  }
  if (height < minHeight) {
    height = minHeight
    width = height * aspectRatio
  }

  // Final clamp to maximums after minimum adjustments
  width = Math.min(width, maxWidth)
  height = Math.min(height, maxHeight)

  return { width: Math.round(width), height: Math.round(height) }
}

export function ScaledImage(props: Props): JSX.Element {
  const {
    uri,
    originalWidth,
    originalHeight,
    minWidth = 120,
    maxWidth = 240,
    minHeight = 80,
    maxHeight = 320,
    borderRadius,
    style,
  } = props

  const [dimensions, setDimensions] = useState<{ width: number; height: number } | null>(() => {
    if (originalWidth !== undefined && originalHeight !== undefined) {
      return computeDimensions(originalWidth, originalHeight, minWidth, maxWidth, minHeight, maxHeight)
    }
    return null
  })

  useEffect(() => {
    if (originalWidth !== undefined && originalHeight !== undefined) {
      setDimensions(
        computeDimensions(originalWidth, originalHeight, minWidth, maxWidth, minHeight, maxHeight),
      )
      return
    }

    // Use Image.getSize to determine dimensions at runtime
    Image.getSize(
      uri,
      (w, h) => {
        setDimensions(computeDimensions(w, h, minWidth, maxWidth, minHeight, maxHeight))
      },
      () => {
        // Fallback to min dimensions on error
        setDimensions({ width: minWidth, height: minHeight })
      },
    )
  }, [uri, originalWidth, originalHeight, minWidth, maxWidth, minHeight, maxHeight])

  if (!dimensions) {
    // Placeholder while size is being resolved
    return <View style={[styles.placeholder, { width: minWidth, height: minHeight, borderRadius }, style]} />
  }

  return (
    <Image
      source={{ uri }}
      style={[{ width: dimensions.width, height: dimensions.height, borderRadius }, style]}
      resizeMode="cover"
    />
  )
}

const styles = StyleSheet.create({
  placeholder: {
    backgroundColor: '#e0e0e0',
  },
})
