/* eslint-disable @typescript-eslint/ban-ts-comment */
// @ts-nocheck

import { BlurFilter, Sprite, Texture } from "pixi.js";
import { getWorldBorderThickness, parseHexColor } from "./pixiSurfaceHelpers";

function createBorderSprite(x, y, width, height, tint, alpha) {
  const border = new Sprite(Texture.WHITE);
  border.x = x;
  border.y = y;
  border.width = width;
  border.height = height;
  border.tint = tint;
  border.alpha = alpha;
  return border;
}

export function rebuildHeightOverlay(state, scope, helpers) {
  if (!helpers.isReady() || !state.heightOverlayRoot) {
    return;
  }
  const overlayMode = scope.isEditingHeightLayer && scope.isEditingHeightLayer() ? "height" : "";
  const activeEntry = scope.getActiveHeightLayer ? scope.getActiveHeightLayer() : null;
  const activeId = String(activeEntry?.id || "").trim();
  if (
    !state.dirty
    && state.lastHeightLayersRef === scope.heightLayers
    && state.lastHeightOverlayMode === overlayMode
    && state.lastHeightActiveId === activeId
    && state.lastHeightTileSize === scope.tileSize
  ) {
    return;
  }

  state.heightPatchEntries.forEach((entry) => {
    helpers.destroyHeightPatchEntry(entry);
  });
  state.heightPatchEntries.clear();
  state.heightOverlayRoot.removeChildren();
  state.lastHeightLayersRef = scope.heightLayers;
  state.lastHeightOverlayMode = overlayMode;
  state.lastHeightActiveId = activeId;
  state.lastHeightTileSize = scope.tileSize;

  if (overlayMode !== "height" || !activeEntry) {
    state.heightOverlayRoot.visible = false;
    return;
  }
  state.heightOverlayRoot.visible = true;
  const activeZ = Math.max(1, Number(activeEntry.z) || 1);
  const visibleEntries = (Array.isArray(scope.heightLayers) ? scope.heightLayers : [])
    .filter((entry) => Math.max(1, Number(entry?.z) || 1) === activeZ);
  const borderThickness = getWorldBorderThickness(scope.tileSize);
  visibleEntries.forEach((entry) => {
    const entryId = String(entry?.id || "").trim();
    if (!entryId) {
      return;
    }
    const isActive = entryId === activeId;
    const patchContainer = new helpers.Container();
    patchContainer.label = `height_${entryId}`;
    patchContainer.x = Math.max(0, Number(entry?.x) || 0);
    patchContainer.y = Math.max(0, Number(entry?.y) || 0);
    patchContainer.alpha = isActive ? 0.92 : 0.56;
    patchContainer.roundPixels = true;
    state.heightOverlayRoot.addChild(patchContainer);
    const rows = Array.isArray(entry?.rows) ? entry.rows : [];
    let patchWidth = 0;
    rows.forEach((rawRow, localY) => {
      const row = String(rawRow || "");
      patchWidth = Math.max(patchWidth, row.length);
      for (let localX = 0; localX < row.length; localX += 1) {
        const symbol = String(row.charAt(localX) || " ").charAt(0) || " ";
        if (symbol === " " || symbol === ".") {
          continue;
        }
        const sprite = new Sprite(helpers.getTileTexture(symbol));
        sprite.x = localX;
        sprite.y = localY;
        sprite.width = 1;
        sprite.height = 1;
        sprite.roundPixels = true;
        patchContainer.addChild(sprite);
        if (isActive) {
          const shade = new Sprite(Texture.WHITE);
          shade.x = localX;
          shade.y = localY;
          shade.width = 1;
          shade.height = 1;
          shade.tint = parseHexColor("#9198A8", 0x9198A8);
          shade.alpha = 0.28;
          shade.roundPixels = true;
          patchContainer.addChild(shade);
        }
      }
    });
    if (patchWidth > 0 && rows.length > 0) {
      const drawW = patchWidth;
      const drawH = rows.length;
      const tint = isActive ? parseHexColor("#FFEB8C", 0xFFEB8C) : parseHexColor("#6EA0EB", 0x6EA0EB);
      const alpha = isActive ? 0.92 : 0.55;
      patchContainer.addChild(createBorderSprite(0, 0, drawW, borderThickness, tint, alpha));
      patchContainer.addChild(createBorderSprite(0, drawH - borderThickness, drawW, borderThickness, tint, alpha));
      patchContainer.addChild(createBorderSprite(0, 0, borderThickness, drawH, tint, alpha));
      patchContainer.addChild(createBorderSprite(drawW - borderThickness, 0, borderThickness, drawH, tint, alpha));
    }
    state.heightPatchEntries.set(entryId, {
      id: entryId,
      container: patchContainer,
    });
  });
}

export function resetSceneRoots(state, scope) {
  if (!state.backgroundSprite || !state.baseWorldRoot) {
    state.backgroundSprite = new Sprite(Texture.WHITE);
    state.backgroundSprite.zIndex = -1;
    state.backgroundSprite.roundPixels = true;
  }
  state.backgroundSprite.tint = parseHexColor(scope.normalizeMapBackgroundColor(scope.backgroundColor));
  state.backgroundSprite.width = Math.max(1, Number(scope.width) || 1);
  state.backgroundSprite.height = Math.max(1, Number(scope.height) || 1);
  if (state.backgroundSprite.parent !== state.baseWorldRoot) {
    state.baseWorldRoot.addChildAt(state.backgroundSprite, 0);
  }
  if (state.heightOverlayRoot?.parent !== state.worldContainer) {
    state.worldContainer.addChild(state.heightOverlayRoot);
  }
}

export function syncHeightFocusEffect(state, scope) {
  if (!state.baseWorldRoot) {
    return;
  }
  const activeHeightLayer = scope.getActiveHeightLayer ? scope.getActiveHeightLayer() : null;
  const activeHeightZ = Math.max(0, Number(activeHeightLayer?.z) || 0);
  const isHeightModeActive = !!(scope.isEditingHeightLayer && scope.isEditingHeightLayer()) && activeHeightZ > 0;
  const blurStep = Math.max(
    0,
    Math.min(
      1,
      Number(scope.getEffectiveHeightBlurStep?.() ?? scope.heightBlurStep ?? scope.heightDetailStep) || 0.1,
    ),
  );
  const tileReferenceSize = Math.max(8, Number(scope.baseTileSize) || Number(scope.tileSize) || 32);
  const nextBlurStrength = isHeightModeActive
    ? Math.min(8, activeHeightZ * blurStep * (tileReferenceSize / 4))
    : 0;
  if (!state.heightFocusBlurFilter) {
    state.heightFocusBlurFilter = new BlurFilter({ strength: 0, quality: 2, kernelSize: 5 });
    state.heightFocusBlurFilter.repeatEdgePixels = true;
  }
  if (isHeightModeActive) {
    if (!state.heightFocusCacheEnabled || Math.abs(nextBlurStrength - state.heightFocusBlurStrength) > 0.001) {
      state.heightFocusBlurFilter.strength = nextBlurStrength;
      state.baseWorldRoot.filters = [state.heightFocusBlurFilter];
      state.heightFocusCacheEnabled = true;
      state.heightFocusBlurStrength = nextBlurStrength;
    }
  } else if (state.heightFocusCacheEnabled) {
    state.baseWorldRoot.filters = [];
    state.heightFocusCacheEnabled = false;
    state.heightFocusBlurStrength = 0;
  }
  state.baseWorldRoot.alpha = isHeightModeActive
    ? Math.max(0.92, 1 - (activeHeightZ * 0.015))
    : 1;
}
