import { UpdateController } from "@24tools/playable_template";
import { Group } from "@tweenjs/tween.js";
import { GatherC } from "../Map/GatherC";
import { DepositZoneC } from "../Map/DepositZoneC";
import { InteractiveZoneC } from "../Map/InteractiveZoneC";
import { Player } from "../Presets/Player";
import { ResourceInventoryC } from "./ResourceInventoryC";
import { ResourceScreenFly } from "./ResourceScreenFly";
import { ResourceType } from "./ResourceType";
import { ResourceUIC } from "./ResourceUIC";

const DEPOSIT_FLY_MS = 520;
const DEPOSIT_FLY_SCALE = 0.35;
const CHAIN_DEPOSIT_DELAY_MS = 140;

export class ResourceDepositC {
  private static inited = false;
  private static tweenGroup = new Group();
  private static isProcessing = false;

  static init() {
    if (this.inited) return;
    this.inited = true;

    DepositZoneC.onPlayerEnter.addDelegate(() => {
      this.tryStart();
    });

    GatherC.onCombatIdle.addDelegate(() => {
      this.tryStart();
    });

    ResourceInventoryC.onChanged.addDelegate(() => {
      this.tryStart();
    });

    UpdateController.Instance.onUpdate.addDelegate(() => {
      this.tweenGroup.update(performance.now());
    });
  }

  static tryStart() {
    if (!this.canDeposit()) return;
    this.processNext();
  }

  private static canDeposit() {
    return DepositZoneC.isPlayerInside
      && !Player.isAutoAttackActive()
      && !Player.isCombatBusy()
      && this.getDepositableType() !== null;
  }

  private static getDepositableType() {
    for (const type of Object.values(ResourceType)) {
      if (ResourceInventoryC.get(type) > 0) {
        return type;
      }
    }

    return null;
  }

  private static processNext() {
    if (this.isProcessing) return;

    const type = this.getDepositableType();
    if (!type || !this.canDeposit()) {
      this.isProcessing = false;
      return;
    }

    const iconCenter = ResourceUIC.getIconCenter(type);
    const zoneScreen = InteractiveZoneC.getScreenCenter();
    if (!iconCenter) return;

    const pickup = ResourceScreenFly.createPickup(type);
    if (!pickup) return;

    this.isProcessing = true;

    const startScreen = ResourceScreenFly.screenPointFromClient(
      iconCenter.x,
      iconCenter.y,
      zoneScreen.z,
    );

    ResourceScreenFly.flyAlongScreen(
      pickup,
      startScreen,
      zoneScreen,
      this.tweenGroup,
      DEPOSIT_FLY_MS,
      DEPOSIT_FLY_SCALE,
      () => {
        ResourceInventoryC.remove(type, 1);
        ResourceUIC.refresh(type);
        InteractiveZoneC.addDeposit(1);

        window.setTimeout(() => {
          this.isProcessing = false;
          this.processNext();
        }, CHAIN_DEPOSIT_DELAY_MS);
      },
    );
  }
}
