//=============================================================================
// RPG Maker MZ - IM_EventSelector
//
// Copyright 2025 I'm moralist/min-pub.com All rights reserved.
// This source code or any portion thereof must not be
// reproduced or used without licensed in any manner whatsoever.
//=============================================================================
/*:
 * @target MZ
 * @plugindesc 監獄勇者イベント選択プラグイン
 * @author I'm moralist
 * @base PluginCommonBase
 * @base PluginUtils
 * @orderAfter PluginCommonBase
 * @orderAfter PluginUtils
 *
 * @param level
 * @text 判定値
 * @desc 判定に使用する変数(エロステ段階)
 * @type variable
 * @default 0
 *
 * @param stoped
 * @text 打ち止め時イベント
 * @desc 再生出来るイベントが無くなった際のイベント
 * @type common_event
 * @default 0
 *
 * @command selectEvent
 * @text イベント再生
 * @desc イベントを判定して再生
 *
 * @arg playLog
 * @text 再生回数記録用変数
 * @desc 再生回数を記録する変数
 * @type variable
 * @default 0
 *
 * @arg firstPlayed
 * @text 初回再生済フラグ
 * @desc 初回イベントを再生済だとONにします
 * @type switch
 * @default 0
 *
 * @arg level01
 * @text １段階目
 * @desc １段階目のイベント
 * @type struct<EventType>
 * @default
 *
 * @arg level02
 * @text ２段階目
 * @desc ２段階目のイベント
 * @type struct<EventType>
 * @default
 *
 * @arg level03
 * @text ３段階目
 * @desc ３段階目のイベント
 * @type struct<EventType>
 * @default
 *
 * @arg level04
 * @text ４段階目
 * @desc ４段階目のイベント
 * @type struct<EventType>
 * @default
 *
 * @help IM_EventSelector.js
 *
 * Version: 0.0.1
 *
 * 監獄勇者イベント選択プラグイン
 */
/*~struct~EventType:
 *
 * @param firstEvent
 * @text 最初のイベント
 * @desc その段階で最初のイベント
 * @type common_event
 * @default 0
 *
 * @param seconds
 * @text ２回目以降のイベント
 * @desc その段階で２回目以降のイベント
 * @type common_event[]
 * @default []
 *
 */
(() => {
	"use strict";

    const pluginName = "IM_EventSelector";
    const script = document.currentScript;
    const param  = PluginManagerEx.createParameter(script);

    //========================================================================
    // 共通基盤
    //========================================================================

    //========================================================================
    // コアスクリプト変更部 ()
    //========================================================================

    //========================================================================
    // プラグインコマンド
    //========================================================================
    const dataFromVariable = (variable) => {
        const text = PluginUtils.getVariables(variable);
        if (!text || text === 0) {
            return {
                lastPlayLevel: 0,
                firstPlayed: false,
                playedEvents: [],
            };
        } else {
            return JSON.parse(text);
        }
    };

    const decideEvent = (events, data, level) => {
        // 最後に再生したイベント段階にエロステ段階が先行
        if (data.lastPlayLevel < level) {
            let index = data.lastPlayLevel + 1;
            for (index = (data.lastPlayLevel + 1); index <= level; index++) {
                if (events[index].firstEvent !== 0) {
                    // 初回イベント未指定の場合は飛ばす
                    break;
                }
                // 次の初回イベントはまだ見てないので
                data.firstPlayed = false;
            }

            // indexが4以上になることを抑止
            if (index > level) {
                index = level;
            }

            if (data.firstPlayed === false) {
                // まだ初回イベント見てないので初回イベントを流す
                return {
                    data: data,
                    event: events[index].firstEvent,
                    level: index,
                };
            } else {
                // 初回イベントの取りこぼしがあるのでそれを流す
                data.firstPlayed = true;
                const playedIndex = Math.min(index + 1, 3); // 間違ってもLv.4以上の箇所を見ないように
                return {
                    data: data,
                    event: events[playedIndex].firstEvent,
                    level: index,
                };
            }
        } else if (data.firstPlayed === false) {
            // このレベルの初回イベントを見てない
            data.firstPlayed = true;
            return {
                data: data,
                event: events[level].firstEvent,
                level: level,
            };
        } else {
            const randomEvents = events.filter((events, index) => {
                return index <= data.lastPlayLevel;
            }).flatMap(events => {
                return events.seconds;
            }).filter(event => {
                return !!event && event > 0
            // }).filter(event => {
                // return !data.playedEvents.includes(event);
            });

            let event = param.stoped;
            if (randomEvents.length > 0) {
                const randomIndex = Math.floor(Math.random() * randomEvents.length);
                event = randomEvents[randomIndex];
            } else {
                // ２回目イベントが無い
                event = events[level].firstEvent;
            }

            return {
                data: data,
                event: event,
                level: data.lastPlayLevel,
            };
        }
    };

    PluginManagerEx.registerCommand(script, 'selectEvent', args => {
        const events = [
            args.level01._parameter,
            args.level02._parameter,
            args.level03._parameter,
            args.level04._parameter,
        ];

        const level = Number(PluginUtils.getVariables(param.level) - 1).clamp(0, 4);
        const data = dataFromVariable(args.playLog);
        const event = decideEvent(events, data, level);
        // event.data.playedEvents.push(event.event);
        if (args.firstPlayed > 0) {
            const firstPlayed = (level === event.data.lastPlayLevel) && event.data.firstPlayed;
            $gameSwitches.setValue(args.firstPlayed, firstPlayed);
        }
        event.data.lastPlayLevel = event.level;

        $gameVariables.setValue(args.playLog, JSON.stringify(event.data, null, 2));
        PluginUtils.waitCommonEvent(event.event, args.interpreter);
    });
})();
