import {Sprite as PixiSprite} from '@pixi/react';
import {useEffect, useState} from 'react';

import {useAsset} from '@/react/context/assets.js';

import {deferredLighting} from './lights.js';

function textureFromAsset(asset, animation, frame) {
  if (!asset) {
    return undefined;
  }
  let texture;
  if (asset.data.animations) {
    if (!animation) {
      return undefined;
    }
    texture = asset.animations[animation][frame];
  }
  else {
    texture = asset.textures[''];
  }
  return texture;
}

export default function Sprite({entity, ...rest}) {
  const [mounted, setMounted] = useState();
  const [normals, setNormals] = useState();
  const [normalsMounted, setNormalsMounted] = useState();
  const {alpha, anchor, animation, frame, scale, rotates, rotation, source} = entity.Sprite;
  const asset = useAsset(source);
  const normalsAsset = useAsset(normals);
  useEffect(() => {
    if (!asset) {
      return;
    }
    const {normals} = asset.data.meta;
    if (normals) {
      const {pathname} = new URL(
        source.split('/').slice(0, -1).concat(normals).join('/'),
        'http://example.org',
      );
      setNormals(pathname);
    }
  }, [asset, source]);
  const texture = textureFromAsset(
    asset,
    animation,
    frame,
  );
  const normalsTexture = textureFromAsset(
    normalsAsset,
    animation,
    frame,
  );
  if (mounted) {
    mounted.parentGroup = deferredLighting.diffuseGroup;
  }
  if (normalsMounted) {
    normalsMounted.parentGroup = deferredLighting.normalGroup;
  }
  return (
    <>
      {texture && (
        <PixiSprite
          alpha={alpha}
          anchor={anchor}
          ref={setMounted}
          {...(rotates ? {rotation: entity.Direction.direction + rotation} : {})}
          scale={scale}
          texture={texture}
          x={Math.round(entity.Position.x)}
          y={Math.round(entity.Position.y)}
          {...rest}
        />
      )}
      {normalsTexture && (
        <PixiSprite
          alpha={alpha}
          anchor={anchor}
          ref={setNormalsMounted}
          {...(rotates ? {rotation: entity.Direction.direction + rotation} : {})}
          scale={scale}
          texture={normalsTexture}
          x={Math.round(entity.Position.x)}
          y={Math.round(entity.Position.y)}
          {...rest}
        />
      )}
    </>
  );
}