import MaskedView from '@react-native-masked-view/masked-view';
import { Image, ImageProps, ImageStyle, ImageTransition, ImageContentFit } from 'expo-image';
import { SquircleView } from 'expo-squircle-view';
import React from 'react';
import { DimensionValue, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  maskBase: {
    flex: 1,
    backgroundColor: 'black',
  },
  imageFill: {
    width: '100%',
    height: '100%',
  },
});

export type SquircleImageProps = Omit<ImageProps, 'style' | 'placeholder' | 'transition' | 'cachePolicy'> & {
  /**
   * Style for the image. Must include width, height, and borderRadius.
   */
  style?: ImageStyle & {
    width?: DimensionValue;
    height?: DimensionValue;
    borderRadius?: number;
  };
  /**
   * Controls the amount of smoothing for the radius.
   * 0 means no smoothing, 100 means maximum smoothing.
   * @default 100
   */
  cornerSmoothing?: number;
  /**
   * Enhanced rounding for larger borderRadius values when true.
   * @default true
   */
  preserveSmoothing?: boolean;
  /**
   * Blurhash string for placeholder image while loading.
   * @see https://blurha.sh/
   */
  placeholderHash?: string;
  /**
   * Content fit mode for the placeholder.
   * @default 'cover'
   */
  placeholderContentFit?: ImageContentFit;
  /**
   * Image transition configuration.
   * Can be a number (duration in ms) or an ImageTransition object.
   * @default { duration: 300, effect: 'cross-dissolve', timing: 'ease-in-out' }
   */
  transition?: ImageTransition | number | null;
  /**
   * Determines whether and where to cache the image.
   * - 'none' - Image is not cached at all.
   * - 'disk' - Image is cached on disk.
   * - 'memory' - Image is cached in memory only.
   * - 'memory-disk' - Image is cached in memory with disk fallback.
   * @default 'memory-disk'
   */
  cachePolicy?: 'none' | 'disk' | 'memory' | 'memory-disk';
};

const DEFAULT_TRANSITION: ImageTransition = {
  duration: 300,
  effect: 'cross-dissolve',
  timing: 'ease-in-out',
};

/**
 * An image component with squircle (iOS-style smooth corner) clipping.
 * Uses MaskedView with SquircleView to properly clip images with smooth corners.
 * Supports blurhash placeholders, smooth transitions, and configurable caching.
 *
 * @example
 * ```tsx
 * <SquircleImage
 *   source={{ uri: 'https://example.com/image.jpg' }}
 *   style={{ width: 200, height: 200, borderRadius: 40 }}
 *   cornerSmoothing={100}
 *   contentFit="cover"
 *   placeholderHash="L6PZfSi_.AyE_3t7t7R**0o#DgR4"
 *   transition={{ duration: 300, effect: 'cross-dissolve' }}
 *   cachePolicy="memory-disk"
 * />
 * ```
 */
export function SquircleImage({
  style,
  cornerSmoothing = 100,
  preserveSmoothing = true,
  placeholderHash,
  placeholderContentFit = 'cover',
  transition = DEFAULT_TRANSITION,
  cachePolicy = 'memory-disk',
  ...imageProps
}: SquircleImageProps) {
  const flatStyle = StyleSheet.flatten(style);
  const { width, height, borderRadius = 0 } = flatStyle || {};

  if (typeof __DEV__ !== 'undefined' && __DEV__ && (!width || !height)) {
    console.warn(
      'SquircleImage: width and height must be specified in style for proper rendering'
    );
  }

  return (
    <MaskedView
      style={{ width, height }}
      maskElement={
        <SquircleView
          cornerSmoothing={cornerSmoothing}
          preserveSmoothing={preserveSmoothing}
          style={[styles.maskBase, { borderRadius: typeof borderRadius === 'number' ? borderRadius : 0 }]}
        />
      }
    >
      <Image
        style={styles.imageFill}
        placeholder={placeholderHash ? { blurhash: placeholderHash } : undefined}
        placeholderContentFit={placeholderContentFit}
        transition={transition}
        cachePolicy={cachePolicy}
        {...imageProps}
      />
    </MaskedView>
  );
}

export default SquircleImage;
