import {AdjustmentFilter} from '@pixi/filter-adjustment';
import {GlowFilter} from '@pixi/filter-glow';
import {Container} from '@pixi/react';
import {useEffect, useState} from 'react';

import {usePacket} from '@/context/client.js';
import {useEcs, useEcsTick} from '@/context/ecs.js';
import {useMainEntity} from '@/context/main-entity.js';

import Entity from './entity.jsx';

export default function Entities({filters, monopolizers}) {
  const [ecs] = useEcs();
  const [entities, setEntities] = useState({});
  const [mainEntity] = useMainEntity();
  const [radians, setRadians] = useState(0);
  const [willInteractWith, setWillInteractWith] = useState(0);
  const [interactionFilters] = useState([new AdjustmentFilter(), new GlowFilter({color: 0x0})]);
  const pulse = (Math.cos(radians) + 1) * 0.5;
  interactionFilters[0].brightness = (pulse * 0.75) + 1;
  interactionFilters[1].outerStrength = pulse * 0.5;
  usePacket('EcsChange', async () => {
    setEntities({});
  }, [setEntities]);
  useEcsTick((payload) => {
    if (!ecs) {
      return;
    }
    const deleting = {};
    const updating = {};
    for (const id in payload) {
      if ('1' === id) {
        continue;
      }
      const update = payload[id];
      if (false === update) {
        deleting[id] = true;
        continue;
      }
      updating[id] = ecs.get(id);
      if (update.Emitter?.emit) {
        updating[id].Emitter.emitting = {
          ...updating[id].Emitter.emitting,
          ...update.Emitter.emit,
        };
      }
    }
    setEntities((entities) => {
      for (const id in deleting) {
        delete entities[id];
      }
      return {
        ...entities,
        ...updating,
      };
    });
  }, [ecs]);
  useEcsTick(() => {
    if (!ecs) {
      return;
    }
    const main = ecs.get(mainEntity);
    if (main) {
      setWillInteractWith(main.Interacts.willInteractWith);
    }
  }, [ecs, mainEntity]);
  useEffect(() => {
    setRadians(0);
    const handle = setInterval(() => {
      setRadians((radians) => (radians + 0.1) % (Math.PI * 2))
    }, 50);
    return () => {
      clearInterval(handle);
    };
  }, []);
  const renderables = [];
  for (const id in entities) {
    const isHighlightedInteraction = 0 === monopolizers.length && id == willInteractWith;
    renderables.push(
      <Entity
        filters={isHighlightedInteraction ? interactionFilters : null}
        entity={entities[id]}
        key={id}
      />
    );
  }
  return (
    <Container
      filters={filters}
      sortableChildren
    >
      {renderables}
    </Container>
  );
}