/**
 * Шиммер воды (полировка прудов): редкие светлые блики на поверхности.
 * Отдельный слой частиц движка — плоские квадраты НА воде (не воксели,
 * не world.set — без ремешинга мира): блики вспыхивают и гаснут фазами
 * от времени цикла, детерминированно (гейты кадр-равенств выключают слой
 * вместе с пеплом мостом setAsh).
 */
import type { ParticleLayer, VoxelRenderer } from '@rpg/engine';

/** Клетка поверхности воды: центр клетки (воксель + 0.5). */
export interface WaterCell {
    x: number; // центр по x
    z: number; // центр по z
}

const STEP = 128; // каждый N-й воксель поверхности — потенциальный блик (редкие)
const GLOW = 0.84; // порог фазы: выше — блик виден (вспышка короткая)
/** Высота поверхности воды (вода — слой y=2, верхняя грань y=3) + сдвиг
 *  против z-fighting с кубом воды. */
const Y = 3.03;
/** Блик: приглушённая рябь и яркая вспышка (поверх W2 #568590). */
const COLORS = ['#8fb8bf', '#cfe4e6'] as const;
const GLOW_ALPHA = 0.9;

export class WaterShimmer {
    private readonly layer: ParticleLayer;
    /** Снапшот для моста: бликов в последней позе. */
    private lastCount = 0;

    constructor(renderer: VoxelRenderer, private readonly cells: readonly WaterCell[]) {
        this.layer = renderer.addFlatParticles();
    }

    /** Вокселей воды в области и бликов сейчас (мост shimmerInfo). */
    get info(): { cells: number; visible: number } {
        return { cells: this.cells.length, visible: this.lastCount };
    }

    /** Поза бликов: время цикла (детерминизм гейтов). */
    update(t: number): void {
        const points: { pos: [number, number, number]; color: string; alpha: number }[] = [];
        for (let i = 0; i < this.cells.length; i += STEP) {
            const c = this.cells[i]!;
            const phase = Math.sin(t * 0.9 + i * 2.399); // золотое сечение фаз
            if (phase <= GLOW) continue;
            points.push({
                pos: [c.x, Y, c.z],
                color: phase > 0.93 ? COLORS[1]! : COLORS[0]!, // яркая вспышка редка
                alpha: GLOW_ALPHA,
            });
        }
        this.lastCount = points.length;
        this.layer.update(points);
    }

    /** Скрыть блики (не водная область / мост setAsh). */
    hide(): void {
        this.layer.update([]);
    }

    dispose(): void {
        this.layer.dispose();
    }
}