<?php

/**
 * Class Lottery
 * @author Candison November <www.kandisheng.com>
 * @time   2017-06-16
 */
class Lottery extends MY_Controller
{
//    const MAX_AWARD_PER_DAY  = 75; // 每天的中奖名额
    const MAX_AWARD_PER_USER = 30; // 一个用户最高中奖次数
    const WINNER_MULTIPLE    = 5; // 每天的中奖概率
    const ALLOW_CITY         = 'hf'; // 合肥
    const TIME_START         = '10:00:00'; // TODO 10:00:00
    const TIME_END           = '10:59:59'; // TODO 10:59:59
    const DATE_START         = '2017-06-22'; // TODO 2017-06-22
    const DATE_END           = '2017-08-31'; // TODO 2017-08-31

    const WORD_CITY_NOT_ALLOW     = '您所在的城市无法参加此活动';
    const WORD_ACTIVITY_NOT_START = '抽奖时间为2017-06-22至2017-08-31每天的10:00-11:00，请小主耐心等待';
    const WORD_ACTIVITY_END       = '活动已结束';

    const DEBUG                     = false;
    const ACTIVITY_STATUS_NOT_START = 0; // 活动尚未开始
    const ACTIVITY_STATUS_RUNNING   = 1; // 活动进行中
    const ACTIVITY_STATUS_END       = 2; // 活动已结束
    const DATABASE_AWARD            = 'event_lottery_award';
    const DATABASE_PRIZE            = 'event_lottery_prize';
    const DATABASE_POOL             = 'event_lottery_pool';
    const STATIC_PATH               = '//esf.fz.house365.com/event/lottery';

    private $dateToday   = '';
    private $userID      = '0';
    private $timeStatus  = 0;
    private $isAllowCity = false;
    private $data        = array();

    /**
     * Database Master
     * @return Object
     */
    private function databaseMaster()
    {
        $model = new Broker_model();
        return $model->getDatabaseMaster();
    }

    /**
     * Database Slave
     * @return Object
     */
    private function databaseSlave()
    {
        $model = new Broker_model();
        return $model->getDatabaseSlave();
    }

    /**
     * Encode
     *
     * @param $string
     * @param string $newEncoding
     *
     * @return string
     */
    private function encode($string, $newEncoding = 'GBK')
    {
        $oldEncoding = mb_detect_encoding($string);
        return mb_convert_encoding($string, $newEncoding, $oldEncoding);
    }

    /**
     * Encode String
     *
     * @param array $array
     *
     * @return array
     */
    private static function encodeString($array = array())
    {
        foreach ($array as &$value) {
            if (is_array($value)) {
                $value = self::encodeString($value);
            }
            if (is_string($value)) {
                global $conf_cityflag;
                if ($_SERVER['SERVER_ADDR'] != '192.168.105.243' && $conf_cityflag != 'nj') {
                    $value = iconv('gbk', 'utf-8', $value);
                }
                $value = urlencode($value);
            }
        }
        return $array;
    }

    /**
     * Show AJAX
     *
     * @param int $status
     * @param string $message
     * @param null $data
     */
    private static function showAJAX($status = 0, $message = '', $data = null)
    {
        $return = array();
        $return['status'] = $status;
        $return['message'] = $message;
        $return['data'] = $data;
        $return = self::encodeString($return);
        echo urldecode(json_encode($return));
        exit();
    }

    /**
     * Check AJAX
     */
    private function checkAJAX()
    {
        if (!$this->isAllowCity) {
            $this->showAJAX(0, self::WORD_CITY_NOT_ALLOW, null);
        }
        if ($this->timeStatus == self::ACTIVITY_STATUS_NOT_START) {
            $this->showAJAX(0, self::WORD_ACTIVITY_NOT_START, null);
        }
        if ($this->timeStatus == self::ACTIVITY_STATUS_END) {
            $this->showAJAX(0, self::WORD_ACTIVITY_END, null);
        }
    }

    /**
     * Check Page
     */
    private function checkPage()
    {
        if (!$this->isAllowCity) {
            $this->jump(GB_WO_URL, self::WORD_CITY_NOT_ALLOW);
        }
    }

    /**
     * Get Mine
     * @return mixed
     */
    private function getMine($mobile)
    {
        $mine = $this->databaseSlave()
            ->where('mobile =', $mobile)
            ->where('award_id >', 0)
            ->order_by('time', 'desc')
            ->select('award_name, time')
            ->get(self::DATABASE_AWARD)
            ->result_array();
        foreach ($mine as $key => &$value) {
            $value['award_name'] = sprintf('%s.%s', $key + 1, $value['award_name']);
            $value['time'] = date('Y-m-d H:i:s', $value['time']);
        }
        return $mine;
    }

    /**
     * Get Winner
     * @return mixed
     */
    private function getWinner()
    {
        $winner = $this->databaseSlave()
            ->where('award_id >', 0)
            ->where('mobile !=', '')
            ->order_by('id', 'desc')
            ->limit(12)
            ->select('mobile, award_name')
            ->get(self::DATABASE_AWARD)
            ->result_array();
        foreach ($winner as &$value) {
            $str1 = mb_substr($value['mobile'], 0, 3, 'gbk');
            $str2 = mb_substr($value['mobile'], 7, 4, 'gbk');
            $value['mobile'] = sprintf('%s****%s', $str1, $str2);
//            $value['mobile'] = substr_replace($value['mobile'], '****', 3, 4);
        }
        return $winner;
    }

    /**
     * Get Award Show ID
     *
     * @param $id
     * @param bool $isSave
     *
     * @return mixed
     */
    private function getAwardShowID($id, $isSave = false)
    {
        $config = array();
        $config[0] = array(2, 4); // 不中奖
        $config[1] = array(1, 5); // 租售宝优惠券50元
        $config[2] = array(6); // 租售宝优惠券100元
        $config[3] = array(3); // 租售宝优惠券200元
        unset($_SESSION['award']);
        $id = intval($id);
        $return = isset($config[$id]) ? $config[$id] : $config[0];
        $key = array_rand($return);
        if ($isSave) {
            $awardName = '谢谢参与';
            if ($id > 0) {
                $result = $this->databaseSlave()
                    ->where('id =', $id)
                    ->select('name')
                    ->get(self::DATABASE_PRIZE)
                    ->row_array();
                $awardName = isset($result['name']) ? $result['name'] : $awardName;
                // Pool
                $resultPool = $this->databaseMaster()
                    ->where('award_id =', $id)
                    ->where('day = ', $this->dateToday)
                    ->select('id, number')
                    ->get(self::DATABASE_POOL)
                    ->row_array();
                if (!$resultPool) {
                    return $config[0][0];
                }
                $sql = sprintf('UPDATE %s SET `number`=`number`-1 WHERE id=%s AND `number`>0', self::DATABASE_POOL, $resultPool['id']);
                $databaseMaster = $this->databaseMaster();
                $databaseMaster->query($sql);
                $resultCount = $databaseMaster->affected_rows();
                if ($resultCount <= 0) {
                    return $config[0][0];
                }
                // Pool
            }
            $data = array();
            $data['account'] = $this->userID;
            $data['award_id'] = $id;
            $data['award_name'] = $awardName;
            $data['month'] = date('Ym');
            $data['day'] = $this->dateToday;
            $data['time'] = time();
            $data['share'] = 0;
            $data['status'] = 1;
            $data['name'] = '';
            $data['mobile'] = '';
            $data['company'] = '';
            $dataBaseMaster = $this->databaseMaster();
            $dataBaseMaster->insert(self::DATABASE_AWARD, $data);
            if ($id > 0) {
                $data['returnID'] = $dataBaseMaster->insert_id();
                $_SESSION['award'] = $data;
            }
        }
        return $return[$key];
    }

    /**
     * Get Pool Today
     * @return array
     */
    private function getPoolToday()
    {
//        $prize = $this->databaseSlave()
//            ->select('id, max')
//            ->get(self::DATABASE_PRIZE)
//            ->result_array();
//        $winnerToday = $this->databaseMaster()
//            ->where('day =', $this->dateToday)
//            ->where('award_id >', 0)
//            ->select('award_id')
//            ->get(self::DATABASE_AWARD)
//            ->result_array();
//        $prizePool = array();
//        foreach ($prize as $value) {
//            $prizePool[$value['id']] = intval($value['max']);
//        }
//        foreach ($winnerToday as $value) {
//            if (isset($prizePool[intval($value['award_id'])])) {
//                $prizePool[intval($value['award_id'])] -= 1;
//            }
//        }
//        $pool = array();
//        foreach ($prizePool as $key => $value) {
//            for ($index = 0; $index < $value; $index++) {
//                array_push($pool, $key);
//            }
////            if ($value > 0) {
////                foreach (range(1, $value) as $count) {
////                    array_push($pool, $key);
////                }
////            }
//        }
//        return $pool;
        $pool = array();
        $prizePool = $this->databaseMaster()
            ->where('day =', $this->dateToday)
            ->select('award_id, number')
            ->get(self::DATABASE_POOL)
            ->result_array();
        foreach ($prizePool as $value) {
            for ($index = 0; $index < intval($value['number']); $index++) {
                array_push($pool, $value['award_id']);
            }
        }
        return $pool;
    }

    /**
     * Lottery constructor.
     */
    public function __construct()
    {
        parent::__construct();
        // Debug
        error_reporting(0);
        ini_set('display_errors', 'Off');
        if (self::DEBUG) {
            error_reporting(E_ERROR);
            ini_set('display_errors', 'On');
        }
        // Initialize
        $allowCity = explode(',', self::ALLOW_CITY);
        $this->isAllowCity = in_array(GB_CITY, $allowCity);
        $this->userID = session_id();
        $this->dateToday = date('Ymd');
        // Check Time
        $timeStart = strtotime(sprintf('%s %s', self::DATE_START, self::TIME_START));
        $timeEnd = strtotime(sprintf('%s %s', self::DATE_END, self::TIME_END));
        $timeNow = time();
        if ($timeNow < $timeStart) {
            $this->timeStatus = self::ACTIVITY_STATUS_NOT_START;
        } else if ($timeNow <= $timeEnd) {
            $this->timeStatus = self::ACTIVITY_STATUS_RUNNING;
            $timeTodayStart = strtotime(sprintf('%s %s', date('Y-m-d'), self::TIME_START));
            $timeTodayEnd = strtotime(sprintf('%s %s', date('Y-m-d'), self::TIME_END));
            if ($timeNow < $timeTodayStart || $timeNow > $timeTodayEnd) {
                $this->timeStatus = self::ACTIVITY_STATUS_NOT_START;
            }
        } else {
            $this->timeStatus = self::ACTIVITY_STATUS_END;
        }
        // Render
        $this->data = array();
        $this->data['static'] = self::STATIC_PATH;
    }

    /**
     * Page Index
     */
    public function index()
    {
        $this->checkPage();
        // Pool
        $result = $this->databaseSlave()
            ->select('name, id, max')
            ->get(self::DATABASE_PRIZE)
            ->result_array();
        foreach ($result as $value) {
            $result1 = $this->databaseMaster()
                ->where('day =', $this->dateToday)
                ->where('award_id =', $value['id'])
                ->get(self::DATABASE_POOL)
                ->result_array();
            if (!$result1) {

                $saveData = array();
                $saveData['day'] = $this->dateToday;
                $saveData['award_id'] = $value['id'];
                $saveData['number'] = $value['max'];
                $this->databaseMaster()
                    ->insert(self::DATABASE_POOL, $saveData);
            }
        }
        // Pool
        $this->data['winner'] = $this->getWinner();
//        $this->data['mine'] = $this->getMine();
        $this->data['status'] = $this->timeStatus;
        $this->load->view(sprintf('%s/%s', __CLASS__, __FUNCTION__), $this->data);
    }

    /**
     * Page Pool
     */
    public function pool()
    {
        $pool = $this->getPoolToday();
        $data = array();
        echo '<pre>';
        foreach ($pool as $value) {
            if (!isset($data[$value])) {
                $data[$value] = 0;
            }
            $data[$value]++;
        }
        print_r($data);
        print_r($pool);
        echo '</pre>';
    }

    /**
     * AJAX Mine
     */
    public function ajaxMine()
    {
        $mobile = isset($_POST['mobile']) ? $_POST['mobile'] : '';
        $mine = $this->getMine($mobile);
        $this->showAJAX(1, '', $mine);
    }

    /**
     * AJAX Run
     */
    public function ajaxRun()
    {
        $this->checkAJAX();
        // 当天已抽奖，不可抽奖
        $result = $this->databaseMaster()
            ->where('account =', $this->userID)
            ->where('day =', $this->dateToday)
            ->from(self::DATABASE_AWARD)
            ->count_all_results();
        if ($result > 0) {
            $this->showAJAX(0, '小主今天的机会已用完，明天再来呦', null);
        }
        // 个人中奖次数不能超过30
        $result = $this->databaseMaster()
            ->where('account =', $this->userID)
            ->where('award_id >', 0)
            ->from(self::DATABASE_AWARD)
            ->count_all_results();
        if ($result >= self::MAX_AWARD_PER_USER) {
            $this->showAJAX(1, '', $this->getAwardShowID(0, true));
        }
//        // 每天有75个中奖名额
//        $result = $this->databaseMaster()
//            ->where('day =', $this->dateToday)
//            ->where('award_id >', 0)
//            ->from(self::DATABASE_AWARD)
//            ->count_all_results();
//        if ($result >= self::MAX_AWARD_PER_DAY) {
//            $this->showAJAX(1, '', $this->getAwardShowID(0, true));
//        }
        // 当天奖池里是否还有奖品
        $pool = $this->getPoolToday();
        if (count($pool) <= 0) {
            $this->showAJAX(1, '', $this->getAwardShowID(0, true));
        }
        // 10的倍数的人可以中奖
        $number = $this->databaseMaster()
            ->where('day =', $this->dateToday)
            ->from(self::DATABASE_AWARD)
            ->count_all_results();
        $remainder = $number % self::WINNER_MULTIPLE;
        if ($remainder != (self::WINNER_MULTIPLE - 1)) {
            $this->showAJAX(1, '', $this->getAwardShowID(0, true));
        }
        // 中奖
        $arrayKey = array_rand($pool);
        $awardID = $pool[$arrayKey];
        $this->showAJAX(1, '', $this->getAwardShowID($awardID, true));
    }

    /**
     * AJAX Book
     */
    public function ajaxBook()
    {
        // $this->checkAJAX();
        if (!isset($_SESSION['award']['returnID'])) {
            $this->showAJAX(0, '系统错误，请重试', null);
        }
        $data = array();
        $data['name'] = isset($_POST['name']) ? $_POST['name'] : '';
        $data['mobile'] = isset($_POST['mobile']) ? $_POST['mobile'] : '';
        $data['company'] = isset($_POST['company']) ? $_POST['company'] : '';
        foreach ($data as &$value) {
            $value = $this->encode($value);
        }
        $this->databaseMaster()
            ->where('id =', $_SESSION['award']['returnID'])
            ->update(self::DATABASE_AWARD, $data);
        unset($_SESSION['award']);
        $this->showAJAX(1, '', null);
    }
}