import { GRID_HEIGHT, GRID_WIDTH } from '@rpg-engine/shared';
import React from 'react';
import styled, { css } from 'styled-components';
import { toUppercaseHexColor } from '../../utils/colorUtils';

interface IProps {
  atlasJSON: any;
  atlasIMG: any;
  spriteKey: string;
  width?: number;
  height?: number;
  grayScale?: boolean;
  opacity?: number;
  tintColor?: string;
  onPointerDown?: () => void;
  containerStyle?: any;
  imgStyle?: any;
  imgScale?: number;
  imgClassname?: string;
  centered?: boolean;
  borderRadius?: string;
}

export const SpriteFromAtlas: React.FC<IProps> = ({
  atlasJSON,
  atlasIMG,
  spriteKey,
  width = GRID_WIDTH,
  height = GRID_HEIGHT,
  imgScale = 2,
  imgStyle,
  onPointerDown,
  containerStyle,
  grayScale = false,
  opacity = 1,
  tintColor,
  imgClassname,
  centered,
  borderRadius,
}) => {
  //! If an item is not showing, remember that you MUST run yarn atlas:copy everytime you add a new item to the atlas (it will sync our public folder atlas with src/atlas).
  //!Due to React's limitations, we cannot import it from the public folder directly!

  const spriteData =
    atlasJSON?.frames?.[spriteKey] ||
    atlasJSON?.frames?.['others/no-image.png'];

  if (!spriteData) {
    console.error(
      `SpriteFromAtlas: Could not find sprite with key ${spriteKey} in atlasJSON.`
    );
    return null;
  }

  const normalizedTintColor = toUppercaseHexColor(tintColor);
  // For white tint, we'll use a very light gray instead
  const effectiveTintColor =
    normalizedTintColor === '#FFFFFF' ? '#EEEEEE' : normalizedTintColor;

  return (
    <Container
      width={width}
      height={height}
      hasHover={grayScale}
      onPointerDown={onPointerDown}
      style={containerStyle}
    >
      <ImgSprite
        className={`sprite-from-atlas-img ${imgClassname || ''}`}
        atlasIMG={atlasIMG}
        frame={spriteData.frame}
        scale={imgScale}
        grayScale={grayScale}
        opacity={opacity}
        style={imgStyle}
        centered={centered}
        borderRadius={borderRadius}
        tintColor={effectiveTintColor}
      />
    </Container>
  );
};

interface IImgSpriteProps {
  atlasIMG: any;
  frame: {
    x: number;
    y: number;
    w: number;
    h: number;
  };
  scale: number;
  grayScale: boolean;
  opacity: number;
  centered?: boolean;
  borderRadius?: string;
  tintColor?: string;
}

interface IContainerProps {
  width: number;
  height: number;
  hasHover: boolean;
}

const Container = styled.div`
  width: ${(props: IContainerProps) => props.width}px;
  height: ${(props: IContainerProps) => props.height}px;
  ${(props: IContainerProps) =>
    !props.hasHover
      ? `&:hover {
    filter: sepia(100%) saturate(300%) brightness(70%) hue-rotate(180deg);
  }`
      : ``}
`;

const ImgSprite = styled.div<IImgSpriteProps>`
  width: ${props => props.frame.w}px;
  height: ${props => props.frame.h}px;
  background-image: url(${props => props.atlasIMG});
  background-position: -${props => props.frame.x}px -${props =>
  props.frame.y}px;
  transform: scale(${props => props.scale});
  position: relative;
  top: ${props => (props.centered ? '0' : '8px')};
  left: ${props => (props.centered ? '0' : '8px')};
  opacity: ${props => props.opacity};
  border-radius: ${props => props.borderRadius || '0'};
  overflow: hidden;

  /* Apply grayscale if needed */
  ${props =>
    props.grayScale &&
    css`
      filter: grayscale(100%);
    `}

  /* Add tint overlay if tintColor is provided */
  ${props =>
    props.tintColor &&
    css`
      &::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: ${props.frame.w}px;
        height: ${props.frame.h}px;
        background-color: ${props.tintColor};
        mix-blend-mode: multiply;
        opacity: 0.6;
        pointer-events: none;
        -webkit-mask-image: url(${props.atlasIMG});
        -webkit-mask-position: -${props.frame.x}px -${props.frame.y}px;
        mask-image: url(${props.atlasIMG});
        mask-position: -${props.frame.x}px -${props.frame.y}px;
      }

      &::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: ${props.frame.w}px;
        height: ${props.frame.h}px;
        background-color: ${props.tintColor};
        mix-blend-mode: soft-light;
        opacity: 0.6;
        pointer-events: none;
        -webkit-mask-image: url(${props.atlasIMG});
        -webkit-mask-position: -${props.frame.x}px -${props.frame.y}px;
        mask-image: url(${props.atlasIMG});
        mask-position: -${props.frame.x}px -${props.frame.y}px;
      }
    `}
`;
