// /AIWK_COMMON/group/aiwk_zone_class.js
// AIWK EXT4 v007
(function () {
    "use strict";

    const AIWK = window.AIWK;
    const zones = {};

    class AIWKZone {
        constructor(cfg) {
            if (!cfg || !cfg.id) {
                throw new Error("ZONE_CONSTRUCTOR_STOPPED: zone id is required. 해결: cfg.id를 지정하십시오.");
            }
            this.id = cfg.id;
            this.title = cfg.title || cfg.id;
            this.order = Number(cfg.order || 0);
            this.useOrder = cfg.useOrder ? 1 : 0;
            this.children = [];
            this.state = {};
            this.createdAt = Date.now();
        }

        addWin(winId) {
            if (!winId) {
                throw new Error("ZONE_ADD_WIN_STOPPED: win id is required. 해결: 추가할 win id를 지정하십시오.");
            }
            if (!AIWK.win || !AIWK.win.get(winId)) {
                throw new Error("ZONE_ADD_WIN_STOPPED: win not found: " + winId + ". 해결: 먼저 AIWK.win.create()로 창을 생성한 뒤 zone에 추가하십시오.");
            }
            if (this.children.indexOf(winId) < 0) {
                this.children.push(winId);
            }
            AIWK.events.emit("zone:addWin", { zoneId: this.id, winId: winId });
            return this;
        }

        removeWin(winId) {
            this.children = this.children.filter(function (id) {
                return id !== winId;
            });
            AIWK.events.emit("zone:removeWin", { zoneId: this.id, winId: winId });
            return this;
        }

        listWins() {
            return this.children.map(function (id) {
                const win = AIWK.win && AIWK.win.get(id) ? AIWK.win.get(id) : null;
                return {
                    id: id,
                    exists: win ? 1 : 0,
                    title: win ? win.title : "",
                    module: win ? win.moduleName : ""
                };
            });
        }

        async run(msg) {
            const input = msg || {};
            const results = [];
            for (let i = 0; i < this.children.length; i += 1) {
                const winId = this.children[i];
                if (!AIWK.win || !AIWK.win.get(winId)) {
                    throw new Error("ZONE_RUN_STOPPED: child win not found: " + winId + ". 해결: zone children에는 존재하는 win id만 넣으십시오.");
                }
                const result = await AIWK.win.run(winId, {
                    source: "zone.run",
                    zone_id: this.id,
                    index: i,
                    input: input
                });
                results.push({
                    win_id: winId,
                    result: result
                });
            }
            return {
                ok: 1,
                type: "zone.run",
                zone_id: this.id,
                title: this.title,
                count: results.length,
                results: results,
                received: input,
                message: "zone.run completed"
            };
        }

        toJSON() {
            return {
                id: this.id,
                title: this.title,
                order: this.order,
                useOrder: this.useOrder,
                children: this.children.slice(),
                wins: this.listWins(),
                state: this.state
            };
        }
    }

    AIWK.AIWKZone = AIWKZone;

    AIWK.zone = {
        registry: zones,
        create: function (cfg) {
            if (!cfg || !cfg.id) {
                throw new Error("ZONE_CREATE_STOPPED: zone id is required. 해결: zone 생성 시 id를 지정하십시오.");
            }
            if (zones[cfg.id]) {
                return zones[cfg.id];
            }
            const zone = new AIWKZone(cfg);
            zones[zone.id] = zone;
            AIWK.events.emit("zone:create", zone.toJSON());
            return zone;
        },
        get: function (id) {
            return zones[id] || null;
        },
        list: function () {
            return Object.keys(zones).map(function (id) {
                return zones[id].toJSON();
            });
        },
        addWin: function (zoneId, winId) {
            const zone = zones[zoneId];
            if (!zone) {
                throw new Error("ZONE_NOT_FOUND: " + zoneId + ". 해결: 먼저 AIWK.zone.create({id: ...})로 zone을 생성하십시오.");
            }
            return zone.addWin(winId);
        },
        run: async function (zoneId, msg) {
            const zone = zones[zoneId];
            if (!zone) {
                throw new Error("ZONE_NOT_FOUND: " + zoneId + ". 해결: Zone 목록에서 존재하는 id를 선택하십시오.");
            }
            return await zone.run(msg || {});
        }
    };
}());
