<?php

namespace TdySports\Controller\Rest;

use TdySports\Model\Schedule;
use TdySports\InputFilter\Schedule as ScheduleInputFilter;
use TdyCommons\Controller\BaseRestController;
use Zend\Filter\File\RenameUpload;
use Zend\Http\PhpEnvironment\Request;
use Zend\View\Model\JsonModel;

class SchedulesController extends BaseRestController
{
    protected $identifierName = 'id';

    /**
     * @return JsonModel
     */
    public function getList()
    {
        $this->getLogger()->debug('SchedulesController::getList() start.');

        $q = $this->params()->fromQuery('q', '');
        $p = (int) $this->params()->fromQuery('p', 1);
        $l = (int) $this->params()->fromQuery(
            'l', $this->getSettingsTable()->get('items-per-page')
        );
        $s = $this->params()->fromQuery('s', []);
        $f = $this->params()->fromQuery('f', []);
        $x = [];

        $resultSet = $this->getSchedulesTable()->setIndent(self::LOGGER_INDENT)->fetch($q, $x, $f, $s, true);
        $resultSet->setCurrentPageNumber((int) $p);
        $resultSet->setItemCountPerPage($l);

        if ($p > 0) {
            $i = (($p - 1) * $l);
        } else {
            $i = 0;
        }

        $schedules = iterator_to_array($resultSet, false);

        /**
         * @var int      $k
         * @var Schedule $schedule
         */
        foreach ($schedules as $k => $schedule) {
            $schedule->setServiceLocator($this->getServiceLocator());
            $schedules[$k]->row = ++$i;
            $schedules[$k]      = $schedule->toStdClass();
        }

        $this->getLogger()->debug('SchedulesController::getList() end.');

        return $this->statusOk(
            [
                'entries'    => $schedules,
                'pagination' => [
                    'pageNumber' => $p,
                    'pageSize'   => $l,
                    'totalItems' => $resultSet->getTotalItemCount(),
                    'totalPages' => $resultSet->count(),
                ],

            ]
        );
    }

    /**
     * @param int|string $id
     *
     * @return JsonModel
     */
    public function get($id)
    {
        $schedule = $this->getSchedulesTable()->get($id);
        $schedule->setServiceLocator($this->getServiceLocator());

        return $this->statusOk(
            [
                'entry'      => $schedule->toStdClass(),
                'pagination' => [
                    'pageNumber' => 1,
                    'pageSize'   => 1,
                    'totalItems' => 1,
                    'totalPages' => 1,
                ],
            ]
        );
    }

    /**
     * @param mixed $data
     *
     * @return JsonModel
     */
    public function create($data)
    {
        $this->getLogger()->debug('SchedulesController::create() start.');

        /** @var Request $httpRequest */
        $httpRequest      = $this->getRequest();
        $contentTypeValue = $httpRequest->getHeaders()->get('Content-Type')->getFieldValue();

        list($contentType) = explode(';', trim($contentTypeValue));

        switch ($contentType) {
            case 'multipart/form-data':
                $file   = $httpRequest->getFiles('file');
                $filter = new RenameUpload(
                    [
                        'target'    => 'data/uploads/sheet.upd',
                        'randomize' => true,
                    ]
                );

                $file = $filter->filter($file);
                $path = $file['tmp_name'];

                $valid  = false;
                $reader = null;
                $types  = ['Excel2007', 'Excel5', 'CSV'];
                foreach ($types as $type) {
                    $reader = \PHPExcel_IOFactory::createReader($type);
                    if ($reader->canRead($path)) {
                        $valid = true;
                        break;
                    }
                }

                if ($valid) {
                    /** @var \PHPExcel $objPHPExcel */
                    $objPHPExcel = $reader->load($path);
                    $worksheet   = $objPHPExcel->getActiveSheet();

                    $i              = 1;
                    $j              = 1;
                    $schedules = [];

                    foreach ($worksheet->getRowIterator() as $row) {
                        $cellIterator = $row->getCellIterator();
                        $cellIterator->setIterateOnlyExistingCells(false);

                        if ($i == 1 && $worksheet->getCell('A1')->getValue() == 'sport') {
                            $i++;
                            continue;
                        }

                        $sportSlug     = $worksheet->getCell('A' . $i)->getValue();
                        $leagueSlug    = $worksheet->getCell('B' . $i)->getValue();
                        $seasonSlug    = $worksheet->getCell('C' . $i)->getValue();
                        $weekSlug      = $worksheet->getCell('D' . $i)->getValue();
                        $teamHomeSlug  = $worksheet->getCell('E' . $i)->getValue();
                        $teamHomeScore = $worksheet->getCell('F' . $i)->getValue();
                        $teamAwaySlug  = $worksheet->getCell('G' . $i)->getValue();
                        $teamAwayScore = $worksheet->getCell('H' . $i)->getValue();

                        $sport = $this->getSportsTable()->getBySlug($sportSlug);

                        $league   = $this->getLeaguesTable()->getBySlug($sport->id, $leagueSlug);
                        $season   = $this->getSeasonsTable()->getBySlug($league->id, $seasonSlug);
                        $week     = $this->getWeeksTable()->getBySlug($season->id, $weekSlug);
                        $teamHome = $this->getTeamsTable()->getBySlug($league->id, $teamHomeSlug);
                        $teamAway = $this->getTeamsTable()->getBySlug($league->id, $teamAwaySlug);

                        $schedule            = new Schedule();
                        $schedule->sportId   = $sport->id;
                        $schedule->leagueId  = $league->id;
                        $schedule->seasonId  = $season->id;
                        $schedule->weekId    = $week->id;
                        $schedule->teamHome  = $teamHome->id;
                        $schedule->scoreHome = $teamHomeScore;
                        $schedule->teamAway  = $teamAway->id;
                        $schedule->scoreAway = $teamAwayScore;

                        $newObject        = $this->getSchedulesTable()->save($schedule);
                        $newObject->rowNo = $j;
                        $schedules[] = $newObject->toStdClass();

                        $i++;
                        $j++;
                    }

                    unlink($path);

                    return $this->statusOk(
                        [
                            'entries'    => $schedules,
                            'pagination' => [
                                'pageNumber' => 1,
                                'pageSize'   => $i,
                                'totalItems' => $i,
                                'totalPages' => 1,
                            ],
                        ]
                    );

                } else {
                    return $this->statusBadRequest(
                        [
                            'system'         => [
                                'id'          => 4002,
                                'description' => 'Invalid Import File',
                            ],
                            'opticalClinics' => [
                                'description' => 'The file for import is invalid. Only accepts files in CSV, XLS, or XLSX format.',
                            ],
                        ]
                    );
                }


                break;
            case 'application/json':
            case 'text/json':
            default:
                $data['id'] = 0;

                $inputFilter = new ScheduleInputFilter($this->getServiceLocator());
                $inputFilter->setData($data);

                if ($inputFilter->isValid()) {
                    $this->getLogger()->debug(self::LOGGER_INDENT . 'Input Filter is valid. Continue.');

                    $data = $inputFilter->getValues();

                    $schedule            = new Schedule($data);
                    $schedule->status    = Schedule::STATUS_UPCOMING;
                    $schedule->ending    = 0;
                    $schedule->createdBy = $this->getCurrentAdmin()->id;

                    $schedule = $this->getSchedulesTable()->setIndent(self::LOGGER_INDENT)->save($schedule);

                    $schedule->setServiceLocator($this->getServiceLocator());

                    $this->getLogger()->info(self::LOGGER_INDENT . 'Schedule ' . $schedule->name . ' has been created.');
                    $this->getLogger()->debug('SchedulesController::create() end.');

                    return $this->statusOk(
                        [
                            'entry'      => $schedule->toStdClass(),
                            'pagination' => [
                                'pageNumber' => 1,
                                'pageSize'   => 1,
                                'totalItems' => 1,
                                'totalPages' => 1,
                            ],
                        ]
                    );
                } else {
                    $this->getLogger()->debug(self::LOGGER_INDENT . 'Input Filter is invalid. Bugging out.');
                    $this->getLogger()->debug('SchedulesController::create() end.');

                    return $this->statusBadRequest(
                        [
                            'system'    => [
                                'id'          => 4001,
                                'description' => 'Invalid Request',
                            ],
                            'companies' => [
                                'description' => 'Submission is invalid.',
                                'details'     => $inputFilter->getMessages(),
                            ],
                        ]
                    );
                }
        };


    }

    /**
     * @param int|string $id
     * @param mixed      $data
     *
     * @return JsonModel
     */
    public function update($id, $data)
    {
        $this->getLogger()->debug('SchedulesController::update() start.');

        $data['id'] = (int) $id;

        $inputFilter = new ScheduleInputFilter($this->getServiceLocator(), true);
        $inputFilter->setData($data);

        if ($inputFilter->isValid()) {
            $this->getLogger()->debug(self::LOGGER_INDENT . 'Input Filter is valid. Continue.');

            $schedule            = new Schedule($data);
            $schedule->updatedBy = $this->getCurrentAdmin()->id;
            $schedule            = $this->getSchedulesTable()->setIndent(self::LOGGER_INDENT)->save($schedule);

            $schedule->setServiceLocator($this->getServiceLocator());

            $this->getLogger()->info(self::LOGGER_INDENT . 'Schedule ' . $schedule->name . ' has been updated.');
            $this->getLogger()->debug('SchedulesController::update() end.');

            return $this->statusOk(
                [
                    'entry'      => $schedule->toStdClass(),
                    'pagination' => [
                        'pageNumber' => 1,
                        'pageSize'   => 1,
                        'totalItems' => 1,
                        'totalPages' => 1,
                    ],
                ]
            );
        } else {
            $this->getLogger()->debug(self::LOGGER_INDENT . 'Input Filter is invalid. Will not update.');
            $this->getLogger()->debug('SchedulesController::update() end.');

            return $this->statusBadRequest(
                [
                    'system'    => [
                        'id'          => 4001,
                        'description' => 'Invalid Request',
                    ],
                    'companies' => [
                        'description' => 'Submission is invalid.',
                        'details'     => $inputFilter->getMessages(),
                    ],
                ]
            );
        }
    }

    public function replaceList($data)
    {
        $action = isset($data['action']) ? $data['action'] : '';

        switch ($action) {
            case 'update-scores':
                return $this->updateScores($data);
            default:
                return $this->statusBadRequest(
                    [
                        'system'    => [
                            'id'          => 4001,
                            'description' => 'Invalid Request',
                        ],
                        'companies' => [
                            'description' => 'Action ID is missing.',
                            'details'     => '',
                        ],
                    ]
                );
        }
    }

    /**
     * @param int|string $id
     *
     * @return JsonModel
     * @throws \Exception
     */
    public function delete($id)
    {
        $this->getLogger()->debug('SchedulesController::delete() start.');

        $this->getLogger()->debug(self::LOGGER_INDENT . 'Getting info.');

        if ($id > 0) {
            $schedule = $this->getSchedulesTable()->get($id);
            if ($schedule) {

                $this->getLogger()->debug(self::LOGGER_INDENT . 'Schedule ID  : ' . $id);
                $this->getLogger()->debug(self::LOGGER_INDENT . 'Schedule Name: ' . $schedule->name);

                $schedule->deletedBy = $this->getCurrentAdmin()->id;
                $this->getSchedulesTable()->setIndent(self::LOGGER_INDENT)->delete($schedule);

                $this->getLogger()->info(self::LOGGER_INDENT . 'Schedule ' . $schedule->name . ' has been deleted.');
                $this->getLogger()->debug('SchedulesController::delete() end.');

                return $this->statusOk(
                    [
                        'entry'      => null,
                        'pagination' => [
                            'pageNumber' => 1,
                            'pageSize'   => 1,
                            'totalItems' => 1,
                            'totalPages' => 1,
                        ],
                    ]
                );
            } else {
                $this->getLogger()->debug(self::LOGGER_INDENT . 'Schedule ID ' . $id . ' does not exists.');
                $this->getLogger()->debug('SchedulesController::delete() end.');

                return $this->statusNotFound();
            }
        } else {
            $this->getLogger()->debug(self::LOGGER_INDENT . 'Schedule ID is requred for deletion.');
            $this->getLogger()->debug('SchedulesController::delete() end.');

            return $this->statusNotFound();
        }
    }

    protected function updateScores($data) {



        return $this->statusOk(
            [
                'entry'      => null,
                'pagination' => [
                    'pageNumber' => 1,
                    'pageSize'   => 1,
                    'totalItems' => 1,
                    'totalPages' => 1,
                ],
            ]
        );
    }

}
