#include "..\script_component.hpp"

/*
 * Author: IDSolutions
 * Initialize contact store for contact management
 *
 * Arguments:
 * N/A
 *
 * Return Value:
 * Contact Store Object
 *
 * Examples:
 * [] call forge_server_phone_fnc_initContactStore
 *
 * Public: No
 */

GVAR(ContactStore) = createHashMapObject [[
    ["#type", "IContactStore"],
    ["#create", {
        GVAR(ContactRegistry) = createHashMap; // uid -> Array of contact UIDs
        diag_log "[FORGE:Server:Phone] Contact Store Initialized!";
    }],
    ["init", {
        params [["_uid", "", [""]]];

        if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Phone:Contact] Empty UID provided to init"; createHashMap };

        // Initialize contact registry for player
        GVAR(ContactRegistry) set [_uid, []];

        // Load existing contacts and populate FORGE_Contacts
        _self call ["refreshContacts", [_uid]];

        diag_log format ["[FORGE:Server:Phone:Contact] Contacts initialized for %1", _uid];
        true
    }],
    ["addContact", {
        params [["_uid", "", [""]], ["_contactUid", "", [""]]];

        if (_uid isEqualTo "" || _contactUid isEqualTo "") exitWith {
            diag_log "[FORGE:Server:Phone:Contact] Invalid UIDs provided to addContact";
            false
        };

        if (_uid isEqualTo _contactUid) exitWith {
            diag_log "[FORGE:Server:Phone:Contact] Cannot add self as contact";
            false
        };

        // Get current contacts
        private _contacts = GVAR(ContactRegistry) getOrDefault [_uid, []];

        // Check if contact already exists
        if (_contactUid in _contacts) exitWith {
            diag_log format ["[FORGE:Server:Phone:Contact] Contact %1 already exists for %2", _contactUid, _uid];
            false
        };

        // Add contact to registry
        _contacts pushBack _contactUid;
        GVAR(ContactRegistry) set [_uid, _contacts];

        // Refresh FORGE_Contacts variable
        _self call ["refreshContacts", [_uid]];

        diag_log format ["[FORGE:Server:Phone:Contact] Added contact %1 for %2", _contactUid, _uid];
        true
    }],
    ["removeContact", {
        params [["_uid", "", [""]], ["_contactUid", "", [""]]];

        if (_uid isEqualTo "" || _contactUid isEqualTo "") exitWith {
            diag_log "[FORGE:Server:Phone:Contact] Invalid UIDs provided to removeContact";
            false
        };

        // Get current contacts
        private _contacts = GVAR(ContactRegistry) getOrDefault [_uid, []];

        // Find and remove contact
        private _index = _contacts find _contactUid;
        if (_index == -1) exitWith {
            diag_log format ["[FORGE:Server:Phone:Contact] Contact %1 not found for %2", _contactUid, _uid];
            false
        };

        _contacts deleteAt _index;
        GVAR(ContactRegistry) set [_uid, _contacts];

        // Refresh FORGE_Contacts variable
        _self call ["refreshContacts", [_uid]];

        diag_log format ["[FORGE:Server:Phone:Contact] Removed contact %1 for %2", _contactUid, _uid];
        true
    }],
    ["addContactByPhone", {
        params [["_uid", "", [""]], ["_phoneNumber", "", [""]]];

        if (_uid isEqualTo "" || _phoneNumber isEqualTo "") exitWith {
            diag_log "[FORGE:Server:Phone:Contact] Invalid parameters provided to addContactByPhone";
            false
        };

        // Use Actor Store to find UID by phone number
        private _contactUid = EGVAR(actor,ActorStore) call ["findByPhoneNumber", [_phoneNumber]];

        if (_contactUid isEqualTo "") exitWith {
            diag_log format ["[FORGE:Server:Phone:Contact] Phone number %1 not found in phonebook", _phoneNumber];
            false
        };

        // Add the contact
        _self call ["addContact", [_uid, _contactUid]]
    }],
    ["addContactByEmail", {
        params [["_uid", "", [""]], ["_email", "", [""]]];

        if (_uid isEqualTo "" || _email isEqualTo "") exitWith {
            diag_log "[FORGE:Server:Phone:Contact] Invalid parameters provided to addContactByEmail";
            false
        };

        // Use Actor Store to find UID by email
        private _contactUid = EGVAR(actor,ActorStore) call ["findByEmail", [_email]];

        if (_contactUid isEqualTo "") exitWith {
            diag_log format ["[FORGE:Server:Phone:Contact] Email %1 not found in addressbook", _email];
            false
        };

        // Add the contact
        _self call ["addContact", [_uid, _contactUid]]
    }],
    ["getContacts", {
        params [["_uid", "", [""]]];

        if (_uid isEqualTo "") exitWith {
            diag_log "[FORGE:Server:Phone:Contact] Empty UID provided to getContacts";
            []
        };

        GVAR(ContactRegistry) getOrDefault [_uid, []]
    }],
    ["refreshContacts", {
        params [["_uid", "", [""]]];

        if (_uid isEqualTo "") exitWith {
            diag_log "[FORGE:Server:Phone:Contact] Empty UID provided to refreshContacts";
            false
        };

        private _contactUids = GVAR(ContactRegistry) getOrDefault [_uid, []];
        private _contactObjects = [];

        // Build contact objects with player data
        {
            private _contactUid = _x;
            private _contactData = EGVAR(actor,ActorStore) call ["get", [_contactUid]];

            if (_contactData isNotEqualTo createHashMap) then {
                private _player = [_contactUid] call EFUNC(common,getPlayer);
                private _isOnline = !isNull _player;
                private _name = if (_isOnline) then { name _player } else { "Unknown Player" };

                private _contactObject = createHashMapFromArray [
                    ["uid", _contactUid],
                    ["name", _name],
                    ["phone", _contactData getOrDefault ["phoneNumber", ""]],
                    ["email", _contactData getOrDefault ["email", ""]],
                    ["online", _isOnline]
                ];

                _contactObjects pushBack _contactObject;
            };
        } forEach _contactUids;

        // Set FORGE_Contacts on player
        private _player = [_uid] call EFUNC(common,getPlayer);
        if (!isNull _player) then {
            _player setVariable ["FORGE_Contacts", _contactObjects, true];
            diag_log format ["[FORGE:Server:Phone:Contact] Updated FORGE_Contacts for %1 with %2 contacts", _uid, count _contactObjects];
        };

        _contactObjects
    }],
    ["remove", {
        params [["_uid", "", [""]]];

        if (_uid isEqualTo "") exitWith {
            diag_log "[FORGE:Server:Phone:Contact] Empty UID provided to remove";
            false
        };

        // Remove from contact registry
        GVAR(ContactRegistry) deleteAt _uid;

        diag_log format ["[FORGE:Server:Phone:Contact] Removed contact data for %1", _uid];
        true
    }]
]];

SETMVAR(FORGE_ContactStore,GVAR(ContactStore));
GVAR(ContactStore)
