#include "..\script_component.hpp"

/*
 * File: fnc_initRepository.sqf
 * Author: IDSolutions
 * Date: 2026-03-27
 * Public: No
 *
 * Description:
 * Initializes the actor repository for managing player actor data.
 *
 * Arguments:
 * None
 *
 * Return Value:
 * Actor repository object [HASHMAP OBJECT]
 *
 * Example:
 * call forge_client_actor_fnc_initRepository;
 */

#pragma hemtt ignore_variables ["_self"]
GVAR(ActorRepositoryBaseClass) = compileFinal createHashMapFromArray [
    ["#type", "ActorRepositoryBaseClass"],
    ["#create", compileFinal {
        _self set ["uid", getPlayerUID player];
        _self set ["actor", createHashMap];
        _self set ["isLoaded", false];
        _self set ["lastSave", time];
    }],
    ["init", compileFinal {
        private _uid = _self get "uid";
        [SRPC(actor,requestInitActor), [_uid]] call CFUNC(serverEvent);
        _self set ["lastSave", time];

        systemChat format ["Loading actor for %1", name player];
        diag_log "[FORGE:Client:Actor] Actor Repository Initialized!";
    }],
    ["save", compileFinal {
        params [["_sync", false, [false]]];

        private _uid = _self get "uid";
        [SRPC(actor,requestSaveActor), [_uid, _sync]] call CFUNC(serverEvent);

        _self set ["lastSave", time];
    }],
    ["sync", compileFinal {
        params [["_data", createHashMap, [createHashMap]], ["_jip", false, [false]]];

        private _actor = _self get "actor";
        private _isLoaded = _self get "isLoaded";

        {
            _actor set [_x, _y];

            if (_jip) then {
                switch (_x) do {
                    case "position": { _self call ["applyPosition"]; };
                    case "direction": { _self call ["applyDirection"]; };
                    case "stance": { _self call ["applyStance"]; };
                    case "rank": { _self call ["applyRank"]; };
                    case "loadout": { _self call ["applyLoadout"]; };
                    default {};
                };
            };
        } forEach _data;

        _self set ["actor", _actor];
        SETPVAR(player,FORGE_isLoaded,true);
        if !(_isLoaded) then { _self set ["isLoaded", true]; };
        diag_log "[FORGE:Client:Actor] Sync completed";
    }],
    ["get", compileFinal {
        params [["_key", "", [""]], ["_default", nil, [[], "", 0, false, createHashMap]]];
        private _actor = _self get "actor";
        _actor getOrDefault [_key, _default];
    }],
    ["applyPosition", compileFinal {
        private _position = _self call ["get", ["position", [0, 0, 0]]];
        if (GVAR(enableLoc)) then {
            player setPosASL _position;
            private _pAlt = ((getPosATLVisual player) select 2);
            private _pVelZ = ((velocity player) select 2);
            if (_pAlt > 5 && _pVelZ < 0) then {
                player setVelocity [0, 0, 0];
                player setPosATL [((getPosATLVisual player) select 0), ((getPosATLVisual player) select 1), 1];
                hint "You logged off mid air. You were moved to a safe position on the ground";
            };
        };
    }],
    ["applyDirection", compileFinal {
        private _direction = _self call ["get", ["direction", 0]];
        if (GVAR(enableLoc)) then { player setDir _direction; };
    }],
    ["applyStance", compileFinal {
        private _stance = _self call ["get", ["stance", "STAND"]];
        if (GVAR(enableLoc)) then { player playAction _stance; };
    }],
    ["applyRank", compileFinal {
        private _rank = _self call ["get", ["rank", "PRIVATE"]];
        player setUnitRank _rank;
    }],
    ["applyLoadout", compileFinal {
        private _loadout = _self call ["get", ["loadout", []]];
        if (GVAR(enableGear) && count _loadout > 0) then { player setUnitLoadout _loadout; };
    }],
    ["getNearbyActions", compileFinal {
        params [["_control", controlNull, [controlNull]]];
        private _nearbyActions = [];
        {
            private _isAtm = _x getVariable ["isAtm", false];
            private _isBank = _x getVariable ["isBank", false];
            private _isGarage = _x getVariable ["isGarage", false];
            private _isLocker = _x getVariable ["isLocker", false];
            private _isStore = _x getVariable ["isStore", false];
            private _garageType = _x getVariable ["garageType", ""];
            private _deviceType = _x getVariable ["deviceType", ""];
            private _isPlayer = _x isKindOf "Man" && isPlayer _x;

            if (_isStore) then { _nearbyActions pushBack ["store", true]; };
            if (_isAtm) then { _nearbyActions pushBack ["atm", true]; };
            if (_isBank) then { _nearbyActions pushBack ["bank", true]; };
            if (_isLocker && GVAR(enableVA)) then { _nearbyActions pushBack ["va", true]; };
            if (_isGarage) then { _nearbyActions pushBack ["garage", _garageType]; };
            if (_isGarage && GVAR(enableVG)) then { _nearbyActions pushBack ["vg", true]; };
            if (_deviceType isNotEqualTo "") then { _nearbyActions pushBack ["device", _deviceType]; };
            if (_isPlayer && { _x isNotEqualTo player }) then { _nearbyActions pushBack ["player", name _x]; };
        } forEach (player nearObjects 5);

        _control ctrlWebBrowserAction ["ExecJS", format ["updateAvailableActions(%1)", (toJSON _nearbyActions)]];
    }]
];

GVAR(ActorRepository) = createHashMapObject [GVAR(ActorRepositoryBaseClass)];
GVAR(ActorRepository)
