import {Container} from '@pixi/display';
import {Graphics} from '@pixi/graphics';
import {PixiComponent} from '@pixi/react';
import {useEffect, useState} from 'react';

const tileSize = {x: 16, y: 16};

const TargetingGhostInternal = PixiComponent('TargetingGhost', {
  create: () => {
    // Solid target square.
    const target = new Graphics();
    target.lineStyle(1, 0xffffff);
    target.drawRect(0.5, 0.5, tileSize.x, tileSize.y);
    target.pivot = {x: tileSize.x / 2, y: tileSize.y / 2};
    // Inner spinny part.
    const targetInner = new Graphics();
    targetInner.alpha = 0.6;
    targetInner.lineStyle(3, 0x333333);
    targetInner.beginFill(0xdddddd);
    targetInner.pivot = {x: tileSize.x / 2, y: tileSize.y / 2};
    targetInner.drawRect(0, 0, tileSize.x, tileSize.y);
    targetInner.position.x = 0.5;
    targetInner.position.y = 0.5;
    // ...
    const container = new Container();
    container.addChild(target, targetInner);
    return container;
  },
  applyProps: (container, oldProps, {x, y, radians}) => {
    container.position.set(x, y);
    container.children[1].rotation = radians / 4;
    container.children[1].scale.set(0.3 + 0.2 * (Math.cos(radians) + 1));
  },
})

export default function TargetingGhost({entity, projection}) {
  const [radians, setRadians] = useState(0);
  useEffect(() => {
    const handle = setInterval(() => {
      setRadians((radians) => (radians + 0.2) % (Math.PI * 2))
    }, 50);
    return () => {
      clearInterval(handle);
    };
  }, []);
  const {Direction: {direction}, Position: {x, y}} = entity;
  const tileX = x - (x % tileSize.x);
  const tileY = y - (y % tileSize.y);
  let startX = tileX + (tileSize.x / 2);
  let startY = tileY + (tileSize.y / 2);
  switch (direction) {
    case 0:
      startX += projection.distance[1] * tileSize.x;
      startY -= projection.distance[0] * tileSize.y;
      break;
    case 1:
      startX += projection.distance[0] * tileSize.x;
      startY += projection.distance[1] * tileSize.y;
      break;
    case 2:
      startX -= projection.distance[1] * tileSize.x;
      startY += projection.distance[0] * tileSize.y;
      break;
    case 3:
      startX -= projection.distance[0] * tileSize.x;
      startY -= projection.distance[1] * tileSize.y;
      break;
  }
  const ghosts = [];
  for (const row in projection.grid) {
    const columns = projection.grid[row];
    for (const column in columns) {
      const targeted = projection.grid[row][column];
      if (targeted) {
        let axe;
        switch (direction) {
          case 0:
            axe = [column, row];
            break;
          case 1:
            axe = [-row, column];
            break;
          case 2:
            axe = [-column, -row];
            break;
          case 3:
            axe = [row, -column];
            break;
        }
        ghosts.push(
          <TargetingGhostInternal
            key={JSON.stringify({column, row})}
            x={startX + (tileSize.x * parseInt(axe[0]))}
            y={startY + (tileSize.y * parseInt(axe[1]))}
            radians={radians}
          />
        );
      }
    }
  }
  return <>{ghosts}</>;
}
