<?php /*

 Composr
 Copyright (c) Christopher Graham, 2004-2024

 See docs/LICENSE.md for full licensing information.


 NOTE TO PROGRAMMERS:
   Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
   **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****

*/

/**
 * @license    http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
 * @copyright  Christopher Graham
 * @package    leader_board
 */

/**
 * Create a new leader-board.
 *
 * @param  SHORT_TEXT $title The leader-board title
 * @param  SHORT_TEXT $board_type The type of leader-board
 * @set holders earners
 * @param  integer $member_count The number of top members to use for this leader-board
 * @param  SHORT_TEXT $timeframe The frequency which to re-calculate the leader-board
 * @set week month year
 * @param  BINARY $rolling Whether or not re-calculation should be relative to the creation time of the leader-board
 * @param  BINARY $include_staff Whether or not to include staff in the leader-board
 * @param  ?array $usergroups Only allow members in one or more of the defined usergroup IDs to be in the leader-board (null: do nothing) (empty array: no usergroup filtering)
 * @param  BINARY $calculate_voting_power Whether this leader-board should also calculate voting power and control percentages for leaders to display
 * @param  TIME $creation_time The forced creation time of the leader-board (null: do not force / use current time)
 * @return AUTO_LINK The ID of the new leader-board
 */
function add_leader_board(string $title, string $board_type, int $member_count, string $timeframe, int $rolling, int $include_staff, ?array $usergroups = [], int $calculate_voting_power = 0, ?int $creation_time = null) : int
{
    // Cannot have less than one member
    if ($member_count < 1) {
        warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN'));
    }

    // Time frame must be valid
    if (!in_array($timeframe, ['week', 'month', 'year'])) {
        warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN'));
    }

    // leader-board type must be valid
    if (!in_array($board_type, ['holders', 'earners'])) {
        warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN'));
    }

    require_code('global4');
    prevent_double_submit('ADD_LEADER_BOARD', null, $title);

    // Insert the leader-board
    $id = $GLOBALS['SITE_DB']->query_insert('leader_boards', [
        'lb_title' => $title,
        'lb_type' => $board_type,
        'lb_creation_date_and_time' => (($creation_time === null) ? time() : $creation_time),
        'lb_member_count' => $member_count,
        'lb_timeframe' => $timeframe,
        'lb_rolling' => $rolling,
        'lb_include_staff' => $include_staff,
        'lb_calculate_voting_power' => $calculate_voting_power,
    ], true);

    // Insert usergroup references
    if ($usergroups !== null && !empty($usergroups)) {
        foreach ($usergroups as $group) {
            $GLOBALS['SITE_DB']->query_insert('leader_boards_groups', [
                'lb_leader_board_id' => $id,
                'lb_group' => intval($group),
            ]);
        }
    }

    log_it('ADD_LEADER_BOARD', strval($id), strval($title));

    return $id;
}

/**
 * Edit a leader-board.
 *
 * @param  AUTO_LINK $id The ID of the leader-board to edit
 * @param  SHORT_TEXT $title The leader-board title
 * @param  ?SHORT_TEXT $board_type The type of leader-board (null: do not change)
 * @set holders earners
 * @param  integer $member_count The number of top members to use for this leader-board
 * @param  SHORT_TEXT $timeframe The frequency which to re-calculate the leader-board
 * @set week month year
 * @param  BINARY $rolling Whether or not re-calculation should be relative to the creation time of the leader-board
 * @param  BINARY $include_staff Whether or not to include staff in the leader-board
 * @param  ?array $usergroups Only allow members in one or more of the defined usergroup IDs to be in the leader-board (null: do not edit existing usergroups) (empty array: no usergroup filtering)
 * @param  BINARY $calculate_voting_power Whether this leader-board should also calculate voting power and control percentages for leaders to display
 */
function edit_leader_board(int $id, string $title, ?string $board_type, int $member_count, string $timeframe, int $rolling, int $include_staff, ?array $usergroups, int $calculate_voting_power)
{
    $_title = $GLOBALS['SITE_DB']->query_select_value_if_there('leader_boards', 'lb_title', ['id' => $id]);
    if ($_title === null) {
        warn_exit(do_lang_tempcode('MISSING_RESOURCE', 'leader_board'));
    }

    // Cannot have less than one member
    if ($member_count < 1) {
        warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN'));
    }

    // Time frame must be valid
    if (!in_array($timeframe, ['week', 'month', 'year'])) {
        warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN'));
    }

    $map = [
        'lb_title' => $title,
        'lb_member_count' => $member_count,
        'lb_timeframe' => $timeframe,
        'lb_rolling' => $rolling,
        'lb_include_staff' => $include_staff,
        'lb_calculate_voting_power' => $calculate_voting_power,
    ];
    if ($board_type !== null) {
        $map['lb_type'] = $board_type;
    }

    // Update leader-board
    $GLOBALS['SITE_DB']->query_update('leader_boards', $map, ['id' => $id], '', 1);

    // Update usergroup references by deleting old ones then inserting new ones
    if ($usergroups !== null) {
        $GLOBALS['SITE_DB']->query_delete('leader_boards_groups', ['lb_leader_board_id' => $id]);
        if (!empty($usergroups)) {
            foreach ($usergroups as $group) {
                if ($group === null) {
                    continue; // skip empty or null groups
                }
                $GLOBALS['SITE_DB']->query_insert('leader_boards_groups', [
                    'lb_leader_board_id' => $id,
                    'lb_group' => intval($group), // Might be a string from post parameters
                ]);
            }
        }
    }

    log_it('EDIT_LEADER_BOARD', strval($id), strval($title));
}

/**
 * Delete a leader-board and its result sets.
 *
 * @param  AUTO_LINK $id The ID of the leader-board to delete
 */
function delete_leader_board(int $id)
{
    $_title = $GLOBALS['SITE_DB']->query_select_value_if_there('leader_boards', 'lb_title', ['id' => $id]);
    if ($_title === null) {
        warn_exit(do_lang_tempcode('MISSING_RESOURCE', 'leader_board'));
    }

    $GLOBALS['SITE_DB']->query_delete('leader_boards', ['id' => $id], '', 1);
    $GLOBALS['SITE_DB']->query_delete('leader_boards_groups', ['lb_leader_board_id' => $id]);
    $GLOBALS['SITE_DB']->query_delete('leader_board', ['lb_leader_board_id' => $id]);

    log_it('DELETE_LEADER_BOARD', strval($id), strval($_title));
}
