/**
 * Атмосфера области (v1 Atmosphere, вариант 'ash'): медленные хлопья пепла
 * в воздухе вокруг камеры. Voxel-облако (instanced-кубы рендера): поза
 * каждого хлопка — детерминированные синусы от времени цикла (гейт-стабильно),
 * дрейф по ветру + лёгкое кружение; хлопья всегда в кадре — облако следует
 * за целью камеры (v1: частицы в screen-space, v2 — кубы вокруг target).
 */
import type { VoxelCloud, VoxelRenderer } from '@rpg/engine';

/** Параметры пепла (масштаб мира v2: радиус в вокселях). */
const COUNT = 36; // хлопков в облаке (v1 ~40 частиц)
const RADIUS = 22; // половина ширины облака вокруг камеры
const TOP = 14; // высота верхнего слоя пепла над землёй
const SPEED = 0.35; // дрейф по ветру (вокс/сек)

/** Цвет пепла (палитра сцены: P3 — светлый пепел). */
const ASH_COLOR = '#3e3e48';

export class AshParticles {
    private readonly cloud: VoxelCloud;

    constructor(renderer: VoxelRenderer) {
        this.cloud = renderer.addVoxelCloud([]);
    }

    /** Поза облака: цель камеры и время цикла (детерминизм гейтов). */
    update(t: number, target: readonly [number, number, number]): void {
        const voxels: { pos: [number, number, number]; color: string }[] = [];
        for (let i = 0; i < COUNT; i++) {
            // сид хлопка — от индекса; фазы кружения разнесены
            const p = i * 2.399; // золотое сечение: равномерный разброс фаз
            // базовый дрейф по ветру: хлопок циклично проходит окно вокруг камеры
            const drift = (t * SPEED + i * (RADIUS * 2) / COUNT) % (RADIUS * 2);
            const x = target[0] - RADIUS + drift;
            const z = target[2] - RADIUS + ((i * 7919) % (RADIUS * 2));
            // вертикаль: медленное оседание + лёгкое кружение по горизонтали
            const fall = ((t * (0.25 + (i % 5) * 0.06) + (i * 3.7) % TOP) % TOP);
            const y = TOP - fall;
            voxels.push({
                pos: [
                    x + Math.sin(t * 0.7 + p) * 1.5,
                    y,
                    z + Math.cos(t * 0.5 + p) * 1.5,
                ],
                color: ASH_COLOR,
            });
        }
        this.cloud.update(voxels);
    }

    /** Скрыть облако (область без атмосферы). */
    hide(): void {
        this.cloud.update([]);
    }

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