<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Teacher_Rating extends Controller_Environment_Teacher
{
    public function before() {
        parent::before();

        // make it possible to download files
        Cookie::set('fD', 'true');
    }

    // Получить из кука SGID выбранную ранее группу для данной дисциплины
    private function getFilterGroupID($disciplineID) {
        $groups = json_decode(Cookie::get('SGID', null), true);
        if ($groups && isset($groups[$disciplineID])) {
            return $groups[$disciplineID];
        }
        return 0;
    }


    private static function getTitle($pageType, $try, &$module) {
        if ($pageType == 'rate') {
            $title = $module['SubmoduleName'];
        } else if ($module['ModuleType'] == 'extra') {
            $title = 'Добор баллов';
        } else if ($try === 0) {
            $title = 'Основная сдача';
        } else {
            $title = 'Пересдача ' . $try;
        }
        return $title;
    }

    // Шапка таблицы: структура УКД (модули и мероприятия)
    private function getStructure($id, $pageType) {
        $structure = Model_Map::getRoadmap($id, $pageType);
        if ($structure->count() == 0) {
            throw HTTP_Exception::factory(404, "Страница не найдена");
        }

        $structureHandled = [];
        $maxRate = $i = $try = 0; // try = 1 - экзамен, = 2, 3 - пересдачи
        $lastModuleID = -1;

        foreach ($structure as $row) {

            if ($row['ModuleID'] != $lastModuleID) {
                $lastModuleID = $row['ModuleID'];
                $structureHandled[++$i] = [
                    'SubmodulesCount' => 0,
                    'MaxRate'         => 0,
                    'ModuleTitle'     => $row['ModuleName'],
                    'ModuleType'      => $row['ModuleType'],
                ];
            }

            $j = $structureHandled[$i]['SubmodulesCount'] += 1;
            $structureHandled[$i]['MaxRate'] += (int) $row['MaxRate'];

            $curSubmodule = &$structureHandled[$i][$j];
            $curSubmodule = $row;
            $curSubmodule['MaxRate'] = (int) $curSubmodule['MaxRate'];
            $curSubmodule['Title'] = self::getTitle($pageType, $try, $row);

            if ($pageType == 'rate' || $row['ModuleType'] == 'extra') {
                $maxRate += $row['MaxRate'];
            } else {
                ++$try;
            }
        }
        $structureHandled['ModulesCount'] = $i;
        $structureHandled['MaxRate'] = (int) $maxRate;
        return $structureHandled;
    }

    // TODO: extract to view
    private function processGroupInfo(&$groupInfo) {
        //GroupID, GroupNum, GradeNum, isAttached etc.
        $out = $groupInfo;

        //Формирование заголовка курса
        $gradeNum = $groupInfo['GradeNum'];
        $out['GradeTitle'] = ($groupInfo['Degree'] == 'master')
            ? 'Магистратура, ' . $gradeNum . ' год'
            : $gradeNum . ' курс';

        //Формирование заголовка группы
        $out['GroupTitle'] = $out['GradeTitle'] . " " . $groupInfo['GroupNum'] . " группа";
        return $out;
    }

    private function getRatesForRatingPage($info, &$rateResult) {
        $rateResult = 0;
        $rates = [];

        foreach ($info as $row) {
            $rateResult += $rate = $row['Rate'];
            $moduleType = $row['ModuleType'];
            $submoduleID =
                ($moduleType == 'exam') ? -1 :
                    (($moduleType == 'extra') ? -2
                        : $row['SubmoduleID']);

            $rates[] = [
                'Type'        => $moduleType,
                'SubmoduleID' => $submoduleID,
                'Rate'        => $rate,
            ];

        }
        return $rates;
    }

    private function correctExtra(&$curStudent, $examType, $lastExtraIndex, $firstEmptyExtraIndex, $totalExtraRate) {
        $bottomLimit = 0;
        $maxExtraRate = 0;
        $topLimit = ($examType == 'exam') ? 38 : 60;

        if ($curStudent['RateSemesterResult'] >= $bottomLimit &&
            $curStudent['RateSemesterResult'] < $topLimit
        ) // студент задолженик
        {
            $maxExtraRate = $topLimit - $curStudent['RateSemesterResult'];
        }
        if ($lastExtraIndex >= 0) {
            $curStudent['Rates'][$lastExtraIndex]['MaxRate'] = $maxExtraRate - $totalExtraRate
                + $curStudent['Rates'][$lastExtraIndex]['Rate'];
        }
        if ($firstEmptyExtraIndex >= 0) {
            $curStudent['Rates'][$firstEmptyExtraIndex]['MaxRate'] = $maxExtraRate - $totalExtraRate;
        }
    }

    private function getRatesForExamPage(&$curStudent, $rateList, $examType, $disciplineID) {
        $rowIndex = 0;
        $lastExam = $lastExtraIndex = $lastNilExam = $firstEmptyExtra = -1;
        $rateExtra = 0;
        $curStudent['RateSemesterResult'] = 0;

        foreach ($rateList as $curRate) {

            $moduleType = $curRate['ModuleType'];
            if ($moduleType == 'exam' || $moduleType == 'extra') {
                $curStudent['Rates'][$rowIndex] = [
                    'SubmoduleID'      => $curRate['SubmoduleID'],
                    'Rate'             => $curRate['Rate'],
                    'ModuleType'       => $moduleType,
                    'ExamPeriodOption' => $curRate['ExamPeriodOption'],
                ];
            }

            $points = $curRate['Rate'];

            switch ($moduleType) {
                case 'regular':
                    $curStudent['RateSemesterResult'] += $points;
                    break;
                case 'exam':
                    if (!is_null($points)) {
                        if ($lastExam >= 0) {
                            $curStudent['Rates'][$lastExam]['Blocked'] = true;
                        }
                        $lastExam = $rowIndex;
                    } else {
                        if ($lastNilExam < 0) {
                            $lastNilExam = $rowIndex;
                        } else {
                            $curStudent['Rates'][$rowIndex]['Blocked'] = true;
                        }
                    }
                    break;
                case 'bonus':
                    $curStudent['Bonus'] = $points;
                    break;
                case 'extra':
                    if ($points) {
                        if ($lastExtraIndex >= 0) {
                            $curStudent['Rates'][$lastExtraIndex]['Blocked'] = true;
                        }
                        $lastExtraIndex = $rowIndex;
                        $curStudent['Rate'] += $curRate['Rate'];
                        $rateExtra += $curRate['Rate'];
                    } else {
                        if ($firstEmptyExtra < 0) {
                            $firstEmptyExtra = $rowIndex;
                        } else {
                            $curStudent['Rates'][$rowIndex]['Blocked'] = true;
                        }
                    }
                    break;
                default:
                    throw HTTP_Exception::factory(500, "Некорректный тип модуля!");
            }
            $rowIndex++;
        }

//        $total = Model_Rating->GetStudentRate($curStudent['ID'], $disciplineID);
//        $total = ($total[0])?$total[0]['Num']:0;
//        if ($total)
//            $total = 0;

        $curStudent['RateResult'] = $curStudent['RateSemesterResult'] + $rateExtra;
        if ($lastExam >= 0) {
            $curStudent['RateResult'] += $curStudent['Rates'][$lastExam]['Rate'];
        }
        $this->correctExtra($curStudent, $examType, $lastExtraIndex, $firstEmptyExtra, $rateExtra);
    }

    private function showRatingHistory($disciplineID) {
        $this->twig->set([
            'log' =>  Model_Rating::getHistory($disciplineID),
        ])->set_filename('teacher/history');
    }

    /**
     * @throws HTTP_Exception
     */
    protected function action_rate() {
        $id = $this->request->param('id');
        $pageType = $this->request->param('type'); // 'rate', 'exam', 'history'

        if ($pageType == 'history') {
            $this->showRatingHistory($id);
            return;
        }


        $discipline = Model_Discipline::load($id);
        $discipline['GroupID_Filter'] = $this->getFilterGroupID($id);
        $discipline['LocalizedExamType'] = RusLang::tr($discipline->Type);

        // Студенты и их баллы
        $students = Model_Rating::GetStudentsForRating($id);
        $rateHandled = [];
        $groupsHandled = [];
        $groupInd = $studentInd = $curGroupID = 0;

        foreach ($students as $row) {

            if ($curGroupID !== $row['GroupID']) {
                $curGroupID = $row['GroupID'];
                $studentInd = 0;
                $group = &$rateHandled[++$groupInd];
                $group = $this->processGroupInfo($row);
                $groupsHandled[$curGroupID] = $group['GroupTitle'];
            }

            // Студенты
            $group['Students'][$studentInd] = $row;
            $curStudent = &$group['Students'][$studentInd++]; //ID, Name, isAttached

            // Баллы студента
            if ($pageType == 'rate') {
                $ratesRaw = Model_Rating::getRates($id, $row['ID']);
                $curStudent['Rates'] = $this->getRatesForRatingPage($ratesRaw, $curStudent['RateResult']);
            } else {
                $rate = Model_Rating::getExamRates($id, $row['ID']);
                $this->getRatesForExamPage($curStudent, $rate, $discipline->Type, $id);
            }
        }

        $twigType = ($pageType == 'rate') ? 'rating' : $pageType;
        // Шапка таблицы: структура УКД (модули и мероприятия)
        $this->twig->set([
            'groups'          => $groupsHandled,
            'rateTable'       => $rateHandled,
            'headerRate'      => $this->getStructure($id, $pageType),
            'Discipline'      => $discipline,
            'Discipline_JSON' => json_encode($discipline),
        ])->set_filename("teacher/" . $twigType);
    }

}