<?php

/*
 * @component UserPoints
 * @copyright Copyright (C) 2015-2022 Bernard Gilly - Adrien Roussel - Martin Brampton
 * @license : GNU/GPL
 * @Website : https://remository.com
 */

namespace BlackSheepResearch\Component\UserPoints\Site\Problems;

defined('_JEXEC') or die;

use Joomla\CMS\Language\Text;

class LevelRankData extends ProblemBase {

    protected static $fieldnames = [];
    protected static $fieldtypes = [];
    protected static $count = -1;
    protected static $tablename = '#__alpha_userpoints_levelrank';
    protected static $updatetable = '#__alpha_userpoints_levelrank';
    protected static $keyname = 'id';
    protected static $fetchAllSQL = "SELECT l.*, IFNULL(c.title,'') AS category_title, IFNULL(r.rule_name,'') AS rulename, IFNULL(m.medalcount,0) AS nummedals, IFNULL(u.levelcount,0) AS numrank 
        FROM `%s` AS l 
        LEFT JOIN `#__categories` AS c ON c.id = l.category
        LEFT JOIN `#__alpha_userpoints_rules` AS r ON r.plugin_function = l.rule_id
        LEFT JOIN (SELECT medal, COUNT(medal) AS medalcount FROM #__alpha_userpoints_medals GROUP BY medal) AS m ON m.medal = l.id
        LEFT JOIN (SELECT levelrank, COUNT(levelrank) AS levelcount FROM #__alpha_userpoints GROUP BY levelrank) AS u ON u.levelrank = l.id
        ORDER BY l.typerank ASC, l.ordering ASC, l.levelpoints DESC";
    private static $ranks = [];
    private static $ranks_by_ordering = [];

    public function __construct(int $id = 0) {
        parent::__construct();
        if ($id) {
            if (isset(self::$ranks[$id])) {
                $this->problem_object = self::$ranks[$id];
            }
        }
    }

    protected function initialise() {
        $this->loadRanks();
        self::$count = count(self::$ranks);
    }

    private function loadRanks() {
        foreach ($this->getAllRecords('') as $result) {
            $result->rulename = $result->rulename ? Text::_($result->rulename) : Text::_('AUP_ALL');
            self::$ranks[$result->id] = $result;
            $result->ordering = isset(self::$ranks_by_ordering[$result->typerank]) ? max(array_keys(self::$ranks_by_ordering[$result->typerank])) + 10 : 10;
            self::$ranks_by_ordering[$result->typerank][$result->ordering] = $result->id;
            // self::$ranks_by_name[$result->plugin_function] = $result->id;
        }
    }
    
    public function changeOrder (string $direction) {
        $this->ordering = max(($this->ordering + (('up' == $direction) ? 15 : -15)), 5);
        foreach (self::$ranks as $rank) {
            $rankobject = new self($rank->id);
            $rankobject->save();
        }
    }
    
    public static function reorder (array $ids, array $orderings) {
        foreach ($ids as $i=>$id) {
            $rankobject = new self ($id);
            if (isset($orderings[$i])) {
                $rankobject->ordering = $orderings[$i];
                $rankobject->save();
            }
        }
    }
    
    public static function getLimitedRange(int $limitstart, int $limit, string $fieldname, int $value): array {
        foreach (self::$ranks_by_ordering as $subarray) {
            $count = 0;
            foreach ($subarray as $id) {
                if ($count < $limitstart OR ($value AND self::$ranks[$id]->$fieldname != $value)) {
                    continue;
                }
                if ($count >= $limitstart + $limit) {
                    break;
                }
                $results[] = new self($id);
            }
        }
        return isset($results) ? $results : [];
    }
    
}
