<?php

namespace TdyGames\Model;

use TdyCommons\Filter\Word\LowercaseFirst;
use TdyCommons\Model\Model;
use TdySports\Model\Team;
use TdySports\Table\Teams;
use Zend\Filter\FilterChain;
use Zend\Filter\Word\DashToCamelCase;
use Zend\Filter\Word\UnderscoreToCamelCase;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceManager;

/**
 * Class Mixture
 *
 * @package TdySports\Model
 *
 * @author  James Lloyd Atwil <james@nadows.com>
 */
class Mixture extends Model
{


    /**
     * The unique ID for Sport.
     *
     * @var int
     */
    public $id = 0;

    /**
     * @var int
     */
    public $slotId = 0;

    /**
     * @var int
     */
    public $teamHome = 0;

    /**
     * @var null
     */
    public $teamHomeSide = null;

    /**
     * @var int
     */
    public $teamAway = 0;

    /**
     * @var int
     */
    public $teamAwaySide = 0;

    /**
     * @var int
     */
    public $bet = 0;

    /**
     * @var int
     */
    public $scoreHome = 0;

    /**
     * @var int
     */
    public $scoreAway = 0;

    /**
     * @var int
     */
    public $points = 0;

    /**
     * @var null|ServiceManager|ServiceLocatorInterface
     */
    protected $sm;

    /**
     * @param null $data
     * @param null $sm
     */
    public function __construct($data = null, $sm = null)
    {
        if (!empty($data) && is_array($data)) {
            $this->exchangeArray($data);
        }

        $this->sm = $sm;
    }

    /**
     * @param null|ServiceManager|ServiceLocatorInterface $sm
     */
    public function setServiceLocator($sm)
    {
        $this->sm = $sm;
    }

    /**
     * @see Model::exchangeArray()
     *
     * @param array $data
     */
    public function exchangeArray($data)
    {
        parent::exchangeArray($data);

        foreach ($data as $key => $value) {
            $filter = new FilterChain();
            if (strpos($key, '-') !== false) {
                $filter->attach(new DashToCamelCase());
            } else {
                $filter->attach(new UnderscoreToCamelCase());
            }

            $filter->attach(new LowercaseFirst());
            $nKey = $filter->filter($key);

            if (!property_exists(__CLASS__, $nKey)) {
                continue;
            } else {
                $inArray = in_array($nKey, ['id', 'slotId', 'sportId', 'leagueId', 'weekId', 'scoreHome', 'scoreAway', 'teamHomeSide', 'teamAwaySide', 'points']);
                if ($inArray) {
                    $this->$nKey = (int) $value;
                } else {
                    $this->$nKey = $value;
                }
            }
        }
    }

    /**
     * @param int $id
     *
     * @return null|Team
     */
    public function getTeam($id)
    {
        if (is_null($this->sm)) {
            return null;
        }

        if ($id > 0) {
            /**
             * @var Teams $table
             * @var Team  $sport
             */
            $table = $this->sm->get('TdySports\Table\Teams');
            $team  = $table->get($id);

            return $team;
        } else {
            return new Team(null);
        }
    }

    /**
     * @return null|Team
     */
    public function getHomeTeam()
    {
        return $this->getTeam($this->teamHome);
    }

    /**
     * @return null|Team
     */
    public function getAwayTeam()
    {
        return $this->getTeam($this->teamAway);
    }

    /**
     * @return \StdClass
     */
    public function toStdClass()
    {
        $object = parent::toStdClass();

        if (!is_null($this->sm)) {

            unset($object->teamHome);

            $homeTeam         = $this->getTeam($this->teamHome);
            $object->homeTeam = $homeTeam->toStdClass();

            unset($object->teamAway);

            $awayTeam         = $this->getTeam($this->teamAway);
            $object->awayTeam = $awayTeam->toStdClass();

            unset($object->bet);

            $bet         = $this->getTeam($this->bet);
            $object->bet = $bet->toStdClass();

            unset($object->teamHomeSide);
            $object->homeTeamSide = $this->teamHomeSide == 0 ? 'home' : 'away';

            unset($object->teamAwaySide);
            $object->awayTeamSide = $this->teamAwaySide == 0 ? 'home' : 'away';

            $object->diff = $this->bet == $this->teamHome ? $this->scoreHome - $this->scoreAway : $this->scoreAway - $this->scoreHome;

            $object->basePoints = 0;

            if ($this->bet == $this->teamHome) {
                $object->basePoints = ($object->diff > 0 ? 1 : -1) * $this->scoreHome;
            } else {
                if ($this->bet == $this->teamAway) {
                    $object->basePoints = ($object->diff > 0 ? 1 : -1) * $this->scoreAway;
                } else {
                    if ($this->bet != $this->teamHome) {
                        $object->basePoints = ($object->diff > 0 ? 1 : -1) * $this->scoreAway;
                    } else {
                        if ($this->bet != $this->teamAway) {
                            $object->basePoints = ($object->diff > 0 ? 1 : -1) * $this->scoreHome;
                        }
                    }
                }
            }



            $object->earned = 0;

            // Court Location Rules
            $object->courtPoints = 0;

            if ($object->diff > 0) {
                if ($this->teamHomeSide == 0 && $this->teamAwaySide == 1) {
                    $object->courtPoints += 1;
                }
                if ($this->teamHomeSide == 1 && $this->teamAwaySide == 0) {
                    $object->courtPoints += 1;
                }
                if ($this->teamHomeSide == 1 && $this->teamAwaySide == 1) {
                    $object->courtPoints += 1;
                }
                if ($this->teamHomeSide == 0 && $this->teamAwaySide == 0) {
                    $object->courtPoints += 1;
                }
            }

            // Same Division Rules
            $object->sameDivision   = $homeTeam->groupId == $awayTeam->groupId ? 'Yes' : 'No';

            $object->divisionPoints = 0;
            if ($homeTeam->groupId == $awayTeam->groupId) {
                $object->divisionPoints = ($object->diff > 0) ? 2 : -4;
            }

            $object->earned = $object->courtPoints + $object->divisionPoints;
        }

        return $object;
    }

}
