<?php

namespace app\index\controller;

define('BASE_ROOT_PATH',str_replace('/application/index/controller','',dirname(__FILE__)));
require_once(BASE_ROOT_PATH . '/extend/queue.php');
require_once(BASE_ROOT_PATH . '/extend/queue.logic.php');

use app\index\model\ActionLogModel;
use app\index\model\BoxActionModel;
use app\index\model\CabinetModel;
use app\index\model\BoxModel;
use app\index\model\MsgModel;
use app\index\model\OrderModel;
use app\index\model\UserModel;
use think\App;
use think\facade\Log;
use think\Session;
use QueueClient;
use QueueServer;
use Exception;

class Cabinet extends Base
{
    public function __construct(App $app = null)
    {
        parent::__construct($app);
        session('start','1');
    }

    /**
     * 自提柜批量生产
    */
    public function AddCabinet(){
        $param = input('param.');

        $url = urldecode($param['url']);
        $alias = $param['alias'];
        $count = intval($param['count']);
        $number = $param['number'];
        $login_key = $param['login_key'];
        if($count < 0 || empty($url)) {
            return json(json_error_exception(1007,'参数不正确'));
        }

        $CabinetModel = new CabinetModel();
        $flag = $CabinetModel->insertCabinet($url,$alias,$count,$number,$login_key);
        if($flag['code'] != 1){
            return json(json_error_exception(1006,$flag['msg']));
        }
        $this->action_log();
        json_success([]);
    }

    public function AddBox(){
        $cabinet_number = input('param.cabinet_number');
        $BoxModel = new BoxModel();
        $last_box = $BoxModel->where('cabinet_number' , $cabinet_number)->order('box_number desc')->find();
        if(empty($last_box)){
            $data['box_number'] = 1;
        }else{
            $data['box_number'] = intval($last_box['box_number'] + 1);
        }
        $data['cabinet_number'] = $cabinet_number;
        $ret = $BoxModel->save($data);
        if($ret == false){
            return json(json_error_exception(1006));
        }else{
            json_success([]);
        }
    }

    public function OpenBox()
    {
        $params['id']                 = $this->getid();
        $cabinet_code                 = input('param.cabinet_number');
        $box_number                   = input('param.box_number');
        $box_position_list[]          = $box_number;
        $params['box_position_list']  = $box_position_list;
        $params['delay_time']         = 0;

        $cabinet = $this->get_cabinet($cabinet_code);
        if($cabinet == false){
            return json(json_error_exception('1008'));
        }
        $params['ret_queue']          = 'RET' . session_id();
        $params['req_url']            = $cabinet['req_url'];
        $params['key']                = $cabinet['login_key'];
        $params['cabinet_code']       = $cabinet['cabinet_code'];
        $params['method']             = 'OpenBoxR';

        $result = $this->proc_request(self::queue_name,'OpenBox',$params);

        if($result == false) {
            json_error(2000);
        } else {
            $this->action_log();
            $model = new BoxModel();
            $model->editData(['cabinet_number' => $cabinet_code , 'box_number' => $box_number] , ['box_status' => 0]);
            json_success($result['data']);
        }
    }

    public function LockCabinet()
    {
        $params['id']                 = $this->getid();
        $cabinet_code                 = input('param.cabinet_number');

        $cabinet = $this->get_cabinet($cabinet_code);
        $params['delay_time']         = 0;
        if($cabinet == false){
            return json(json_error_exception('1008'));
        }

        $params['ret_queue']          = 'RET' . session_id();
        $params['req_url']            = $cabinet['req_url'];
        $params['key']                = $cabinet['login_key'];
        $params['cabinet_code']       = $cabinet['cabinet_code'];
        $params['method']             = 'LockCabinetR';

        $result = $this->proc_request(self::queue_name,'LockCabinet',$params);
        if($result == false) {
            json_error(2000);
        } else {
            $this->action_log();
            $this->CabinetStatusChange($cabinet_code , 2);
            json_success($result['data']);
        }
    }

    public function UnLockCabinet()
    {
        $params['id']                 = $this->getid();
        $cabinet_code                 = input('param.cabinet_number');

        $cabinet = $this->get_cabinet($cabinet_code);
        $params['delay_time']         = 0;
        if($cabinet == false){
            return json(json_error_exception('1008'));
        }

        $params['ret_queue']          = 'RET' . session_id();
        $params['req_url']            = $cabinet['req_url'];
        $params['key']                = $cabinet['login_key'];
        $params['cabinet_code']       = $cabinet['cabinet_code'];
        $params['method']             = 'UnLockCabinetR';

        $result = $this->proc_request(self::queue_name,'UnLockCabinet',$params);
        if($result == false) {
            json_error(2000);
        } else {
            $this->action_log();
            $this->CabinetStatusChange($cabinet_code , 1);
            json_success($result['data']);
        }
    }

    public function ReleaseAlarm()
    {
        $params['id']               = $this->getid();
        $cabinet_code                 = input('param.cabinet_number');
        $params['delay_time']         = 0;

        $cabinet = $this->get_cabinet($cabinet_code);
        if($cabinet == false){
            return json(json_error_exception('1008'));
        }

        $params['ret_queue']          = 'RET' . session_id();
        $params['req_url']            = $cabinet['req_url'];
        $params['key']                = $cabinet['login_key'];
        $params['cabinet_code']       = $cabinet['cabinet_code'];
        $params['method']             = 'ReleaseAlarmR';

        $result = $this->proc_request(self::queue_name,'ReleaseAlarm',$params);
        if($result == false) {
            json_error(2000);
        } else {
            $this->action_log();
            json_success($result['data']);
        }
    }

    public function Reboot()
    {
        $params['id']                 = $this->getid();
        $cabinet_code                 = input('param.cabinet_number');
        $params['delay_time']         = 0;

        $cabinet = $this->get_cabinet($cabinet_code);
        if($cabinet == false){
            return json(json_error_exception('1008'));
        }

        $params['ret_queue']          = 'RET' . session_id();
        $params['req_url']            = $cabinet['req_url'];
        $params['key']                = $cabinet['login_key'];
        $params['cabinet_code']       = $cabinet['cabinet_code'];
        $params['method']             = 'RebootR';

        $result = $this->proc_request(self::queue_name,'Reboot',$params);
        if($result == false) {
            json_error(2000);
        } else {
            $this->action_log();
            json_success($result['data']);
        }
    }

    public function QueryState()
    {
        $params['id']               = $this->getid();
        $cabinet_code                 = input('param.cabinet_number');
        $params['delay_time']         = 0;

        $cabinet = $this->get_cabinet($cabinet_code);
        if($cabinet == false){
            return json(json_error_exception('1008'));
        }

        $params['ret_queue']          = 'RET' . session_id();
        $params['req_url']            = $cabinet['req_url'];
        $params['key']                = $cabinet['login_key'];
        $params['cabinet_code']       = $cabinet['cabinet_code'];
        $params['method']             = 'RebootR';

        $result = $this->proc_request(self::queue_name,'QueryState',$params);
        if($result == false) {
            json_error(2000);
        } else {
            $this->action_log();
            json_success($result['data']);
        }
    }

    public function CabinetList(){
        $param = input('param.');
        $CabinetModel = new CabinetModel();
        $selectResult = $CabinetModel->getCabinetsByWhere();
        $cabinet_status = ['1' => '运行中' , '2' => '已锁定'];
        // 拼装参数
        foreach($selectResult as $key=>$vo){
            $selectResult[$key]['status_text'] = $cabinet_status[$vo['cabinet_status']];
        }
        $return['total'] = $CabinetModel->getAllCabinets();  //总数量
        $return['rows'] = $selectResult;
        $this->action_log();
        json_success($return);
    }

    public function BoxList(){
        $param = input('param.');
        $cabinet_number = input('param.cabinet_number');
        if(empty($cabinet_number)){
            json_error(1007 , '柜子号码不能为空');
        }
        $BoxModel = new BoxModel();
        $where['sc_box.cabinet_number'] = $cabinet_number;
        $limit = isset($param['pageSize']) ? $param['pageSize'] : 10;
        $param['pageNumber'] = isset($param['pageNumber']) ? $param['pageNumber'] : 1;
        $offset = ($param['pageNumber'] - 1) * $limit;
        $selectResult = $BoxModel->getBoxsByWhere($where, $offset, $limit);
        $box_status = ['打开','关闭'];
        // 拼装参数
        foreach($selectResult as $key=>$vo){
            $selectResult[$key]['status_text'] = $box_status[$vo['box_status']];
            if($vo['enter_time'] == null){
                $selectResult[$key]['enter_time'] = $selectResult[$key]['use_time'] = '';
            }else{
                $selectResult[$key]['use_time'] = $this->elapse_time((time() - strtotime($vo['enter_time'])));
                $selectResult[$key]['enter_time'] = date("m-d H:i",strtotime($vo['enter_time']));
            }
        }
        $return['total'] = $BoxModel->getAllCounts();  //总数量
        $return['rows'] = $selectResult;
        $this->action_log();
        json_success($return);
    }
    public function BoxActionList(){
        $param = input('param.');
        if(!empty($param['cabinet_number']) && !empty($param['box_number'])){
            $where['cabinet_number'] = $param['cabinet_number'];
            $where['box_number'] = $param['box_number'];
        }
        if(!empty($param['cabinet_number']) && empty($param['box_number'])){
            $where['cabinet_number'] = $param['cabinet_number'];
        }
        if(empty($param['cabinet_number']) && empty($param['box_number'])){
            $where = [];
        }
        if(empty($param['cabinet_number']) && !empty($param['box_number'])){
            json_error(1007 , '柜子号码不能为空');
        }
        $limit = isset($param['pageSize']) ? $param['pageSize'] : 10;
        $param['pageNumber'] = isset($param['pageNumber']) ? $param['pageNumber'] : 1;
        $offset = ($param['pageNumber'] - 1) * $limit;

        $BoxActionModel = new BoxActionModel();
        $selectResult = $BoxActionModel->getBoxActionsByWhere($where , $offset, $limit);
        $status = ['1' => '开箱' , '2' => '关箱'];
        // 拼装参数
        foreach($selectResult as $key=>$vo){
            $selectResult[$key]['status_text'] = $status[$vo['type']];
        }
        $return['total'] = $BoxActionModel->getAllCounts($where);  //总数量
        $return['rows'] = $selectResult;
        $this->action_log();
        json_success($return);
    }
    public function MsgList(){
        $param = input('param.');
        if(!empty($param['cabinet_number']) && !empty($param['box_number'])){
            $where['cabinet_number'] = $param['cabinet_number'];
            $where['box_number'] = $param['box_number'];
        }
        if(!empty($param['cabinet_number']) && empty($param['box_number'])){
            $where['cabinet_number'] = $param['cabinet_number'];
        }
        if(empty($param['cabinet_number']) && empty($param['box_number'])){
            $where = [];
        }
        if(empty($param['cabinet_number']) && !empty($param['box_number'])){
            json_error(1007 , '柜子号码不能为空');
        }

        $limit = isset($param['pageSize']) ? $param['pageSize'] : 10;
        $param['pageNumber'] = isset($param['pageNumber']) ? $param['pageNumber'] : 1;
        $offset = ($param['pageNumber'] - 1) * $limit;

        $MsgModel = new MsgModel();
        $selectResult = $MsgModel->getMsgsByWhere($where , $offset, $limit);
        $status = ['1' => '存入上报' , '2' => '取走上报' , '3' => '通知用户'];
        // 拼装参数
        foreach($selectResult as $key=>$vo){
            $selectResult[$key]['status_text'] = $status[$vo['type']];
        }
        $return['total'] = $MsgModel->getAllCounts($where);  //总数量
        $return['rows'] = $selectResult;
        $this->action_log();
        json_success($return);
    }
    public function ActionLogList(){
        $param = input('param.');
        $limit = isset($param['pageSize']) ? $param['pageSize'] : 10;
        $param['pageNumber'] = isset($param['pageNumber']) ? $param['pageNumber'] : 1;
        $offset = ($param['pageNumber'] - 1) * $limit;

        $ActionLogModel = new ActionLogModel();
        $selectResult = $ActionLogModel->getActionLogsByWhere($offset, $limit);
        // 拼装参数
        foreach($selectResult as $key=>$vo){

        }
        $return['total'] = $ActionLogModel->getAllCounts();  //总数量
        $return['rows'] = $selectResult;
        $this->action_log();
        json_success($return);
    }

    public function GetCabinetsBoxs(){
        $CabinetModel = new CabinetModel();
        $cabinets = $CabinetModel->getCabinetsByWhere();
        $BoxModel = new BoxModel();
        foreach ($cabinets as $key => $value){
            $cabinets[$key]['box_data'] = $BoxModel->getBoxNumbers(['cabinet_number' => $value['id']]);
        }
        json_success($cabinets);
    }

    public function BoxChangeStatus(){
        $cabinet_code = input('param.cabinet_code');
        $box_number = input('param.box_number');
        $box_status = input('param.box_status');
        $cabinet = CabinetModel::where('cabinet_code',$cabinet_code)->find();
        $ret = $this->ChangeStatus($cabinet['cabinet_number'] , $box_number , $box_status);

        if($ret['code'] == -1){
            json_error(1008 , $ret['msg']);
        }
        if($ret == false){
            json_error(1006);
        }
        json_success([]);
    }


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private function proc_request($queue_name, $key, $params){
        QueueClient::push($queue_name,self::redis_host , self::redis_port ,$key,$params);
        [$method,$args] = $this->wait_result($params['ret_queue']);
        Log::record($args);
        return $args;
    }

    private function elapse_time($seconds)
    {
        $minutes = intval($seconds / 60);

        if($minutes >= 60) {
            $minute = $minutes % 60;
            $hours = intval($minutes / 60);
            $result = "{$minute}分钟";
        }
        else {
            $result = "{$minutes}分钟";
        }

        if(isset($hours))
        {
            if($hours >= 24) {
                $hour = $hours % 24;
                $day = intval($hours / 24);
                $result = "{$hour}小时" . $result;
            }
            else {
                $result = "{$hours}小时" . $result;
            }
        }

        if(isset($day) && $day > 0) {
            $result = "{$day}天" . $result;
        }

        return $result;
    }

    private function getid(){
        return md5(rand(1000000,9999999));
    }

    private function wait_result($queue_name)
    {
        $times = 10;
        while ($times--)
        {
            try
            {
                $worker = new QueueServer($queue_name,self::redis_host , self::redis_port);
                $queues = $worker->scan();

                $content = $worker->pop($queues, 1);
                if(is_array($content)) {
                    $method = key($content);
                    $arg = current($content);

                    return [$method,$arg];
                }
            }
            catch (Exception $e)
            {
                $err = $e->getMessage();
                $code = $e->getCode();
            }
        }

        return [false,false];
    }

    /**
     * 自提柜箱子修改状态
     */
    private function ChangeStatus($cabinet_number , $box_number , $status){
        $BoxModel = new BoxModel();
        $box = $BoxModel->getOneCabinetBox($cabinet_number,$box_number);
        if(empty($box)){
            return msg(-1, '', '箱子不存在');
        }
        if($status == $box['box_status']){
            return true;
        }
        $where['cabinet_number']    = $cabinet_number;
        $where['box_number']        = $box_number;
        $update['box_status']       = $status;
        return $BoxModel->editData($where,$update);
    }

    private function CabinetStatusChange($cabinet_number , $status){
        $cabinet = $this->get_cabinet($cabinet_number);
        if($cabinet['cabinet_status'] == $status){
            return true;
        }
        $CabinetModel = new CabinetModel();
        $CabinetModel->save(['cabinet_status' => $status] , ['id' => $cabinet_number]);
    }

    public function test(){
        pre(1);
    }


    /**
     * 获取柜子信息
    */
    private function get_cabinet($cabinet_number){
        $cabinet = CabinetModel::find($cabinet_number);
        if(empty($cabinet)){
            return false;
        }
        $cabinet = $cabinet->toArray();
        return $cabinet;
    }
}