<?php
namespace Gm\Controller;
use Framework\Log\LogMark;
use Game\Protobuf\MGLampCancel;
use Game\Protobuf\PacketId;
use Gm\Config\ErrorCode;
use Gm\Core\RedisLib;
use Gm\Lib\Jwt;
use Gm\Model\Gms;
use Gm\Model\Logs;
use Gm\Model\Lamps;
use Gm\Comm\CommFunc;
use Gm\Model\Servers;
use Gm\Controller\Gm;

/**
 * Class Lamp
 * 跑马灯
 */

class Lamp {

    use CommFunc;

    public const LAMP_TIMER_KEY = "lampTimer";

    public function Save() {
        $params = json_decode(file_get_contents("php://input"));
        $id = $params->id;
        $name = $params->name;
        $servers = $params->servers;
        $time_start = $params->time_start;
        $time_end = $params->time_end;
        $num = $params->num;
        $content = $params->content;

        $user = Jwt::verifyToken();
        $user_name = $user['info']['username'];

        if(empty($id)) {

            // 存储跑马灯数据
            if(Lamps::AddLamp($name, json_encode($servers), $time_start, $time_end, $num, $content, $user_name)) {

                $log_info = $user['info']['username']. ' 增加了跑马灯：'. $name;
                $log_data = [
                    'name' => $name,
                    'servers' => $servers,
                    'time_start' => $time_start,
                    'time_end' => $time_end,
                    'num' => $num,
                    'content' => $content,
                ];
                $db_id = Lamps::findInsID();
                // 放入执行队列中
                RedisLib::GetInstance()->zAdd(self::LAMP_TIMER_KEY, $time_start, $db_id);

                Logs::InsData(Gm::LAMP_LOG_TYPE, $user_name, $log_info, json_encode($log_data));
                $this->ReturnSucc(ErrorCode::SUCCESS);
            } else {
                $this->ReturnErr(ErrorCode::ERROR_GM_INTERNAL, "跑马灯创建失败");
            }
        } else {
            $beforeLamp = Lamps::GetLampById($id);
            $user = Jwt::verifyToken()['info'];

            if($beforeLamp['time_start'] >= time()) {
                $this->ReturnErr(ErrorCode::ERROR_GM_INTERNAL, "不可修改已经发送的跑马灯！");
                return ;
            }
            // 修改跑马灯数据|start deal packet
            if(Lamps::UpdateLamp($id, $name, json_encode($servers), $time_start, $time_end, $num, $content)) {
                $update_info = '';

                if ($beforeLamp['servers'] != json_encode($servers)) {
                    $update_info .= ' 发送区 '. $beforeLamp['servers'] . ' 修改为 ' . json_encode($servers) . ';';
                }

                if ($beforeLamp['name'] != $name) {
                    $update_info .= ' 名称 '. $beforeLamp['name'] . ' 修改为 ' . $name . ';';
                }

                if ($beforeLamp['time_start'] != $time_start) {
                    $update_info .= ' 开始时间 '. date('Y-m-d H:i:s', $beforeLamp['time_start'])
                        . ' 修改为 ' . date('Y-m-d H:i:s', $time_start) .
                    ';';
                    // 更新时间
                    RedisLib::GetInstance()->zAdd(self::LAMP_TIMER_KEY, $time_start, $id);
                }

                if ($beforeLamp['time_end'] != $time_end) {
                    $update_info .= ' 结束时间 '. date('Y-m-d H:i:s', $beforeLamp['time_end'])
                        . ' 修改为 ' . date('Y-m-d H:i:s', $time_end) . ';';
                }

                if ($beforeLamp['num'] != $num) {
                    $update_info .= ' 循环数量 '. $beforeLamp['num'] . ' 修改为 ' . $num . ';';
                }

                if ($beforeLamp['content'] != $content) {
                    $update_info .= ' 内容 '. $beforeLamp['content'] . ' 修改为 ' . $content . ';';
                }

                if (empty($update_info)) {
                    $this->ReturnSucc(ErrorCode::SUCCESS, '未改变数据，修改无效');
                } else {
                    $log_info = $user['username']. ' 修改了跑马灯： ' . $beforeLamp['name'] . $update_info;
                    $log_data = [
                        'before' => $beforeLamp,
                        'after'   => [
                            'servers' => $servers,
                            'name' => $name,
                            'ts' => $time_start,
                            'te' => $time_end,
                            'content' => $content,
                        ]
                    ];

                    Logs::InsData(Gm::LAMP_LOG_TYPE, $user['username'], $log_info, json_encode($log_data));
                    $this->ReturnSucc(ErrorCode::SUCCESS, '修改成功');
                }
            } else {
                $this->ReturnErr(ErrorCode::ERROR_GM_INTERNAL, "跑马灯更新失败");
            }
        }
    }

    public function List() {
        $search = $_GET['search'];
        $page = $_GET['page'];
        $limit = $_GET['limit'];
        $time_start = $_GET['time_start'];
        $time_end = $_GET['time_end'];
        $data = Lamps::GetLampList($search, $page, $limit, $time_start, $time_end);
//        var_dump($data);
        $dataRes = [];
        foreach ($data as $item) {
            if(time() > $item['time_end']) {
                $status = "4";
            } else {
                $status = $item['status'];
            }
            $dataRes[] = [
                'id' => $item['id'],
                'name' => $item['name'],
                'servers' => array_values(json_decode($item['servers'], true)),
                'time_start' => date("Y-m-d H:i:s", $item['time_start']),
                'time_end' => date("Y-m-d H:i:s", $item['time_end']),
                'time_create' => date("Y-m-d H:i:s", $item['time_create']),
                'time_s' => $item['time_start'],
                'time_e' => $item['time_end'],
                'num' => $item['num'],
                'content' => $item['content'],
                'status' => $status,
                'user_name' => $item['user_name'],
            ];
        }

        $count = Lamps::GetLampCount($search);
        $r = [
            "data" => $dataRes,
            "count" => (int)$count
        ];
        // 处理参数
        $this->ReturnSucc(ErrorCode::SUCCESS, '查询成功',$r);
    }

    public function Delete() {
        $params = json_decode(file_get_contents("php://input"));
        $id = $params->id;
        $user = Jwt::verifyToken()['info'];
        $lamp = Lamps::GetLampById($id);
        $log_info = $user['username'] . ' 删除了跑马灯：'. $lamp['name'];

        if(Lamps::DeleteLampById($id)) {
            // 删除发送任务
            RedisLib::GetInstance()->zRem(self::LAMP_TIMER_KEY, $id);
            Logs::InsData(Gm::LAMP_LOG_TYPE, $user['username'], $log_info, $log_info);
            $this->ReturnSucc(ErrorCode::SUCCESS, '删除成功');
        } else {
            $this->ReturnErr(ErrorCode::ERROR_GM_INTERNAL, "删除失败");
        }
    }

    public function Cancel() {
        $params = json_decode(file_get_contents("php://input"));
        $id = $params->id;
        $user = Jwt::verifyToken()['info'];
        $lamp = Lamps::GetLampById($id);
        $log_info = $user['username'] . ' 撤回了跑马灯： '. $lamp['name'];
        $servers = $lamp['servers'];

        $token = getallheaders()['Token'];
        $sendMsg = new MGLampCancel();
        $sendMsg->setID($id);

        if(Lamps::UpdateLampStatus($id, 3)) {
            $servers = json_decode($servers, true);
            // TODO:先不做处理 后续做撤回逻辑
            foreach ($servers as $sid) {
                // 给相应服务器发送消息
                $server_info = Servers::GetServerById($sid);
                if (!Gms::SaveMsgDB($sid, PacketId::MG_LampCancel, $token, $sendMsg)) {
                    LogMark::getInstance()->markError(
                        ErrorCode::ERROR_LAMP_CANCEL_SAVE_DB_FAILED,
                        'send lamp cancel save msg db error!',
                        ['serverID' => $sid, 'packetID' => PacketId::MG_LampCancel]
                    );

                    $info = $user['info']['username'] . ' 执行 ' . $server_info['name'] .
                        ' 撤销跑马灯：' . $lamp['name'] . ' 发送失败！';
                    // 返回失败
                    Logs::InsData(GM::LAMP_LOG_TYPE, 'System', $info, '');
                    continue;
                }
                $info = ' 执行 ' . $server_info['name'] . ' 撤销跑马灯：' . $lamp['name'] .
                    ' 成功！';
                // 返回失败
                Logs::InsData(GM::LAMP_LOG_TYPE, 'System', $info, '');
            }

            Logs::InsData(Gm::LAMP_LOG_TYPE, $user['username'], $log_info, $log_info);
            $this->ReturnSucc(ErrorCode::SUCCESS, '发送撤回成功');
        } else {
            Logs::InsData(Gm::LAMP_LOG_TYPE, $user['username'], $log_info, $log_info);
            $this->ReturnErr(ErrorCode::ERROR_GM_INTERNAL, "发送撤回失败");
        }
    }
}