import {Container, Graphics} from '@pixi/react';
import {memo, useCallback} from 'react';

import {useDebug} from '@/react/context/debug.js';
import {useMainEntity} from '@/react/context/main-entity.js';

import Light from './light.jsx';
import SpriteComponent from './sprite.jsx';

function Aabb({color, width = 0.5, x0, y0, x1, y1, ...rest}) {
  const draw = useCallback((g) => {
    g.clear();
    g.lineStyle(width, color);
    g.moveTo(x0, y0);
    g.lineTo(x1, y0);
    g.lineTo(x1, y1);
    g.lineTo(x0, y1);
    g.lineTo(x0, y0);
  }, [color, width, x0, x1, y0, y1]);
  return (
    <Graphics draw={draw} x={0} y={0} {...rest} />
  );
}

function Crosshair() {
  const draw = useCallback((g) => {
    g.clear();
    g.lineStyle(1, 0x000000);
    g.moveTo(-5, 0);
    g.lineTo(5, 0);
    g.moveTo(0, -5);
    g.lineTo(0, 5);
    g.lineStyle(0.5, 0xffffff);
    g.moveTo(-5, 0);
    g.lineTo(5, 0);
    g.moveTo(0, -5);
    g.lineTo(0, 5);
    g.lineStyle(1, 0x000000);
    g.drawCircle(0, 0, 3);
    g.lineStyle(0.5, 0xffffff);
    g.drawCircle(0, 0, 3);
  }, []);
  return (
    <Graphics draw={draw} />
  );
}

function Entity({entity, ...rest}) {
  const [debug] = useDebug();
  const [mainEntity] = useMainEntity();
  if (!entity) {
    return false;
  }
  const {Direction, id, Sprite} = entity;
  return (
    <>
      <Container
        x={entity.Position.x}
        y={entity.Position.y}
        zIndex={entity.Position?.y || 0}
      >
        {entity.Sprite && (
          <SpriteComponent
            alpha={Sprite.alpha}
            anchor={Sprite.anchor}
            animation={Sprite.animation}
            direction={Direction?.direction}
            frame={Sprite.frame}
            id={id}
            scale={Sprite.scale}
            rotates={Sprite.rotates}
            rotation={Sprite.rotation}
            source={Sprite.source}
            tint={Sprite.tint}
            {...rest}
          />
        )}
        {entity.Light && (
          <Light
            brightness={entity.Light.brightness}
          />
        )}
        {debug && entity.Position && (
          <Crosshair />
        )}
      </Container>
      {debug && (
        <Aabb
          color={0xff00ff}
          {...entity.VisibleAabb}
        />
      )}
      {debug && entity.Collider && (
        <>
          <Aabb
            color={0xffffff}
            width={0.5}
            {...entity.Collider.aabb}
          />
          {entity.Collider.aabbs.map((aabb, i) => (
            <Aabb
              color={0xffff00}
              width={0.25}
              key={i}
              {...aabb}
            />
          ))}
        </>
      )}
      {debug && mainEntity == entity.id && (
        <Aabb
          color={0x00ff00}
          {...entity.Interacts.aabb()}
        />
      )}
    </>
  );
}

export default memo(Entity);
