/**
 * ImageWithSkeleton Component
 *
 * Progressive image loading with skeleton placeholder:
 * - Shows skeleton while image loads
 * - Smooth fade transition on load
 * - Supports lazy loading (loads last in priority)
 * - Error state handling
 */

import { useState, useCallback } from 'react';
import styled from 'styled-components';
import { Skeleton } from './Skeleton';

export interface ImageWithSkeletonProps {
  /** Image source URL */
  src: string;
  /** Alt text for accessibility */
  alt: string;
  /** Width (default: 100%) */
  width?: string | number;
  /** Height (default: auto) */
  height?: string | number;
  /** Border radius */
  borderRadius?: string | number;
  /** Object fit style */
  objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
  /** Lazy loading (default: true) */
  lazy?: boolean;
  /** Custom className */
  className?: string;
  /** Fallback image on error */
  fallbackSrc?: string;
  /** Aspect ratio (e.g., "16/9", "1/1") */
  aspectRatio?: string;
  /** Loading priority (for fetch priority API) */
  priority?: 'high' | 'low' | 'auto';
  /** Callback when image loads */
  onLoad?: () => void;
  /** Callback when image fails to load */
  onError?: () => void;
}

const ImageContainer = styled.div<{
  $width?: string | number;
  $height?: string | number;
  $aspectRatio?: string;
  $borderRadius?: string | number;
}>`
  position: relative;
  width: ${({ $width }) =>
    $width ? (typeof $width === 'number' ? `${$width}px` : $width) : '100%'};
  height: ${({ $height }) =>
    $height ? (typeof $height === 'number' ? `${$height}px` : $height) : 'auto'};
  aspect-ratio: ${({ $aspectRatio }) => $aspectRatio || 'auto'};
  border-radius: ${({ $borderRadius }) =>
    $borderRadius
      ? typeof $borderRadius === 'number'
        ? `${$borderRadius}px`
        : $borderRadius
      : '0'};
  overflow: hidden;
`;

const StyledImage = styled.img<{
  $loaded: boolean;
  $objectFit?: ImageWithSkeletonProps['objectFit'];
}>`
  width: 100%;
  height: 100%;
  object-fit: ${({ $objectFit }) => $objectFit || 'cover'};
  opacity: ${({ $loaded }) => ($loaded ? 1 : 0)};
  transition: opacity 0.3s ease-in-out;
`;

const SkeletonOverlay = styled.div<{ $visible: boolean }>`
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: ${({ $visible }) => ($visible ? 1 : 0)};
  transition: opacity 0.3s ease-in-out;
  pointer-events: none;
`;

const ErrorPlaceholder = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  min-height: 100px;
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.5);
  font-size: 14px;
`;

export function ImageWithSkeleton({
  src,
  alt,
  width,
  height,
  borderRadius,
  objectFit = 'cover',
  lazy = true,
  className,
  fallbackSrc,
  aspectRatio,
  priority = 'low',
  onLoad,
  onError,
}: ImageWithSkeletonProps) {
  const [loaded, setLoaded] = useState(false);
  const [error, setError] = useState(false);
  const [currentSrc, setCurrentSrc] = useState(src);

  const handleLoad = useCallback(() => {
    setLoaded(true);
    onLoad?.();
  }, [onLoad]);

  const handleError = useCallback(() => {
    if (fallbackSrc && currentSrc !== fallbackSrc) {
      setCurrentSrc(fallbackSrc);
    } else {
      setError(true);
      onError?.();
    }
  }, [fallbackSrc, currentSrc, onError]);

  if (error) {
    return (
      <ImageContainer
        $width={width}
        $height={height}
        $aspectRatio={aspectRatio}
        $borderRadius={borderRadius}
        className={className}
      >
        <ErrorPlaceholder>Failed to load image</ErrorPlaceholder>
      </ImageContainer>
    );
  }

  return (
    <ImageContainer
      $width={width}
      $height={height}
      $aspectRatio={aspectRatio}
      $borderRadius={borderRadius}
      className={className}
    >
      <SkeletonOverlay $visible={!loaded}>
        <Skeleton
          variant="rectangular"
          width="100%"
          height="100%"
          animation="wave"
        />
      </SkeletonOverlay>
      <StyledImage
        src={currentSrc}
        alt={alt}
        loading={lazy ? 'lazy' : 'eager'}
        fetchPriority={priority}
        onLoad={handleLoad}
        onError={handleError}
        $loaded={loaded}
        $objectFit={objectFit}
      />
    </ImageContainer>
  );
}

/**
 * Avatar image with skeleton
 */
export function AvatarWithSkeleton({
  src,
  alt,
  size = 40,
  className,
  fallbackSrc,
}: {
  src: string;
  alt: string;
  size?: number;
  className?: string;
  fallbackSrc?: string;
}) {
  return (
    <ImageWithSkeleton
      src={src}
      alt={alt}
      width={size}
      height={size}
      borderRadius="50%"
      objectFit="cover"
      className={className}
      fallbackSrc={fallbackSrc}
      priority="low"
    />
  );
}

/**
 * Hero image with skeleton (higher priority)
 */
export function HeroImageWithSkeleton({
  src,
  alt,
  aspectRatio = '16/9',
  className,
}: {
  src: string;
  alt: string;
  aspectRatio?: string;
  className?: string;
}) {
  return (
    <ImageWithSkeleton
      src={src}
      alt={alt}
      aspectRatio={aspectRatio}
      borderRadius={8}
      objectFit="cover"
      className={className}
      priority="high"
      lazy={false}
    />
  );
}
