<?php


namespace frontend\modules\api\controllers;


use common\components\AjaxException;
use common\models\Rules;
use common\models\RulesPoints;
use common\services\EmergencyResponseRelateToRulesPointsService;
use common\services\EmergencyResponseService;
use common\services\OperationalAdjustmentsRelateToRulesPointsService;
use common\services\OperationalAdjustmentsService;
use common\services\RulesPointsService;
use common\services\RulesService;
use common\util\RulesPointObj;
use frontend\modules\api\components\BaseAdminController;
use Throwable;
use Yii;
use yii\base\InvalidConfigException;
use yii\db\Exception;
use yii\web\Response;

class BasicController extends BaseAdminController
{
    /**
     * 规则需要展示的列表
     * @return Response
     */
    public function actionRulesShowList($rule_name, $start_time, $end_time)
    {
        $rulesPointsList = RulesPointsService::getRulesPointsQuery()->where(["or", ["like", "name", $rule_name], ["like", "content", $rule_name]])->asArray()->all();
        $ids = array_column($rulesPointsList, "rule_id");
        $query = RulesService::getQuery()
            ->andWhere(["rule_status" => 1])
            ->andWhere([
                "or",
                ["like", "rule_name", $rule_name],
                ["id" => $ids],
            ]);
        if ($end_time == "") {
            $query->andWhere([
                "or",
                ["and", [">=", "end_time", $start_time], ["<=", "create_time", $start_time]],
                ["and", ["end_time" => null], ["<=", "create_time", $start_time]]
            ]);
        } else {
            $query->andWhere([
                "or",
                ["<=", "create_time", $end_time],
                [">=", "end_time", $start_time],
            ]);
        }
        $query->orderBy("create_time desc,end_time desc,id desc");
        //组合数据
        $ruleList = RulesService::getAllList($query);
        $data['data'] = $this->getRealRuleList($ruleList);
        return $this->asJson($data);
    }

    protected function getRealRuleList($ruleList)
    {
        $ruleIdList = [];
        foreach ($ruleList as $rule) {
            $ruleIdList[] = $rule->getId();
        }
        $rulesPointsIdList = array_column(RulesPointsService::getRulesPointsQuery()->where(["rule_id" => $ruleIdList])->select("distinct(rule_id)")->asArray()->all(), "rule_id");
        $realRuleList = [];
        foreach ($ruleList as $rule) {
            if (in_array($rule->getId(), $rulesPointsIdList)) {
                $realRuleList[] = $rule;
            }
        }
        return $realRuleList;
    }

    /**
     * 废止规则需要展示的列表  新增协议
     * @return Response
     */
    public function actionRulesShowListWhenRulesAdd($rule_id, $rule_name, $start_time)
    {
        $rulesPointsList = RulesPointsService::getRulesPointsQuery()->where(["or", ["like", "name", $rule_name], ["like", "content", $rule_name]])->asArray()->all();
        $ids = array_column($rulesPointsList, "rule_id");
        $query = RulesService::getQuery()
            ->andWhere(["end_time" => null])
            ->andWhere(["<>", "id", $rule_id])
            ->andWhere(["<", "create_time", $start_time])
            ->andWhere([
                "or",
                ["like", "rule_name", $rule_name],
                ["id" => $ids],
            ]);
        $query->orderBy("create_time desc,end_time desc,id desc");
        //组合数据
        $ruleList = RulesService::getAllList($query);
        $data['data'] = $this->getRealRuleList($ruleList);
        return $this->asJson($data);
    }

    /**
     * 规则需要展示的列表
     * @param $id
     * @return Response
     * @throws AjaxException
     */
    public function actionRulesGetById($id)
    {
        $Rules = RulesService::getRulesById($id);
        //获取知识点
        $query = RulesPointsService::getRulesPointsQuery()->andWhere(["rule_id" => $id]);
        $point_content = RulesPointsService::getAllList($query);
        //规章添加知识点
        $rulesData = RulesService::getRuleWithContent($Rules, $point_content);
        //组合数据
        $data['data'] = $rulesData;
        return $this->asJson($data);
    }

    /**
     * 根据案例ID展示规章
     * @return Response
     */
    public function actionRulesGetByCaseId($id)
    {
        $EmergencyResponseId = array_column(EmergencyResponseService::getEmergencyResponseQuery()->andWhere(["accident_id" => $id])->all(), "id");
        $OperationalAdjustmentsId = array_column(OperationalAdjustmentsService::getQuery()->andWhere(["accident_id" => $id])->all(), "id");
        $pointIds = [];
        $pointIds = array_merge($pointIds, array_column(EmergencyResponseRelateToRulesPointsService::getListByEmergencyResponseId($EmergencyResponseId), "rules_point_id"));
        $pointIds = array_merge($pointIds, array_column(OperationalAdjustmentsRelateToRulesPointsService::getListByOperationalAdjustmentsId($OperationalAdjustmentsId), "rules_point_id"));
        $pointIds = array_values(array_unique($pointIds));
        $ids = array_column(RulesPointsService::getRulesPointsQuery()->where(["id" => $pointIds])->select("distinct(rule_id)")->all(), "rule_id");
        $query = RulesService::getQuery();
        $query->where(["id" => $ids]);
        //组合数据
        $data['data'] = RulesService::getAllList($query);
        return $this->asJson($data);
    }

    /**
     * 通过应急处置ID或者运营调整ID查找规章
     * @param $id
     * @param $type
     * @return Response
     */
    public function actionRulesAndPointsByEventId($id, $type)
    {
        if ($type == 1) {
            $pointIds = array_column(EmergencyResponseRelateToRulesPointsService::getListByEmergencyResponseId($id), "rules_point_id");
        } else {
            $pointIds = array_column(OperationalAdjustmentsRelateToRulesPointsService::getListByOperationalAdjustmentsId($id), "rules_point_id");
        }
        /** @var RulesPoints[] $pointList */
        $pointList = RulesPointsService::getRulesPointsQuery()->where(["id" => $pointIds])->all();
        $newPointList = [];
        foreach ($pointList as $point) {
            $newPointList[$point->rule_id][] = new RulesPointObj($point);
        }
        $ruleId = array_column($pointList, "rule_id");
        /** @var Rules[] $ruleList */
        $ruleList = RulesService::getQuery()->where(["id" => $ruleId])->all();
        $newRuleList = [];
        foreach ($ruleList as $rule) {
            $newRuleList[] = RulesService::getRuleWithContent($rule, $newPointList[$rule->id]);
        }
        //组合数据
        $data['data'] = $newRuleList;
        return $this->asJson($data);
    }

    /**
     * 规则列表
     * @return Response
     */
    public function actionRulesList(int $current = 1, int $page = 10)
    {
        //重新整合数据
        $post = Yii::$app->request->post();
        $rule_content = $post["content"] ?? ""; //规章概要
        $point_content = $post["rule_content"] ?? "";//规章知识点
        $post["rule_content"] = $rule_content;
        Yii::$app->request->setBodyParams($post);


        $query = RulesService::getQuery()
            ->limit($page)
            ->offset(($current - 1) * $page);
        //排序
        $this->initSequence($query, "create_time desc,end_time desc,id desc");
        //主要筛选条件
        //规章知识点筛选条件
        $ruleIdList = [];
        if ($point_content !== "") {
            $ruleIdList = array_column(RulesPointsService::getRulesPointsQuery()->andWhere(["like", "content", $point_content])->select("distinct(rule_id)")->asArray()->all(), "rule_id");
        }
        if ($ruleIdList != []) {
            $query->andWhere(["id" => $ruleIdList]);
        }
        //规章筛选条件
        $this->addConditionToQuery("rule_name", $query, true);
        $this->addConditionToQuery("rule_content", $query, true);
        $this->addConditionToQuery("rule_category", $query);
        $this->addConditionToQuery("rule_status", $query);
        $this->addStartEndConditionToQuery("create_time", $query);
        $this->addStartEndConditionToQuery("end_time", $query);
        $this->addConditionToQuery("version", $query, true);
        //组合数据
        $data['data'] = RulesService::getAllList($query);
        $data['total'] = $query->count();
        return $this->asJson($data);
    }

    /**
     * 规章添加
     * @return Response
     * @throws Exception
     */
    public function actionRulesAdd()
    {
        $post = Yii::$app->request->post();
        if (!isset($post["rule_name"]) || strlen(trim($post["rule_name"])) == 0 || !isset($post["version"]) || strlen(trim($post["version"])) == 0) {
            return $this->asJson([], 1, "名称不可以为空！");
        }
        $rules = RulesService::getQuery()->andWhere(["rule_name" => $post["rule_name"], "version" => $post["version"]])->one();
        if ($rules) {
            return $this->asJson([], 1, "名称+版本号 {$post["rule_name"]}+{$post["version"]} 已存在！");
        }
        $model = new Rules($post);
        $model->update_time = date("Y-m-d H:i:s");
        if ($post['end_time'] && $post['end_time'] != "") {
            $model->end_time = $post['end_time'];
        }
        if (!$model->save()) {
            throw new Exception($model->getErrorSummary(true)[0]);
        }
//        $repealedIds = [];
//        if ($repealedIds != []) {
//            $endTime = date("Y-m-d H:i:s", strtotime($model->create_time) - 1);
//            Rules::updateAll(["end_time" => $endTime], ["id" => $repealedIds]);
//        }
        $data = [];
        return $this->asJson($data);
    }


    protected function getRuleNameVersionString($data)
    {
        return trim($data["title"]) . '+' . trim($data["version"]);
    }

    /**
     * 从excel批量导入规章
     * @return Response
     * @throws Exception
     */
    public function actionRulesAddBatch()
    {
        // 获取传值
        $post = Yii::$app->request->post();
        $json = $post;
        $time = time();
        $ruleNameVersionList = [];
        $ruleNameVersionIdList = [];
        $rulesParamData = [];
        $rulesParam = [
            'rule_name', //规章名字
            'version',  //规章版本
            'rule_content',  //规章概要
            'rule_status',
            'create_time',
            'end_time',
            'update_time',
            'rule_category',
        ];
        foreach ($json as $key => $value) {
            //统计好规章个数
            $ruleNameVersionString = $this->getRuleNameVersionString($value);
            if (!in_array($ruleNameVersionString, $ruleNameVersionList)) {
                $ruleNameVersionList[] = $ruleNameVersionString;
                $end_time = trim($value["end_time"]) === "" ? null : date("Y-m-d H:i:s", strtotime(trim($value["end_time"])));
                $create_time = date("Y-m-d H:i:s", strtotime(trim($value["create_time"])));
                $rulesParamData[] = [
                    'rule_name' => trim($value["title"]), //规章名字
                    'version' => trim($value["version"]),  //规章版本
                    'rule_content' => trim($value["content"]),  //规章概要
                    'rule_status' => 1,  //规章版本
                    'create_time' => $create_time,//实施日期
                    'end_time' => $end_time,  //废止日期
                    'update_time' => date("Y-m-d H:i:s", $time),
                    'rule_category' => "",
                ];
            }
        }
        /** @var Rules[] $rulesList */
        $rulesList = RulesService::getQuery()->andWhere(["CONCAT_WS('+',`rule_name`,`version`)" => $ruleNameVersionList])->select("`id`,CONCAT_WS('+',`rule_name`,`version`) AS `rule_name_version`")->all();
        foreach ($rulesList as $rule) {
            $exitsKey = array_search($rule->rule_name_version, $ruleNameVersionList);
            if ($exitsKey !== false) {
                //已经有的规章就不保存了
                unset($rulesParamData[$exitsKey]);
            }
        }
        //储存规章
        Yii::$app->db->createCommand()->batchInsert(Rules::tableName(), $rulesParam, $rulesParamData)->execute();
        //查询存入的规章信息，得到规章的ID
        /** @var Rules[] $rulesList */
        $rulesList = RulesService::getQuery()->andWhere(["CONCAT_WS('+',`rule_name`,`version`)" => $ruleNameVersionList])->select("`id`,CONCAT_WS('+',`rule_name`,`version`) AS `rule_name_version`")->all();
        foreach ($rulesList as $rule) {
            $ruleNameVersionIdList[$rule->rule_name_version] = $rule->id;
        }
        //上传的规章点列表
        $needUpdateName = [];
        $needUpdateContent = [];
        $needUpdateDic = [];
        $rulesPointParamData = [];
        $ruleIdPointList = [];
        foreach ($json as $key => $value) {
            $ruleNameVersionString = $this->getRuleNameVersionString($value);
            $rule_id = $ruleNameVersionIdList[$ruleNameVersionString];
            $point = trim($value["point"]);
            //插入
            $rulesPointParamData[] = [
                'rule_id' => $rule_id,
                'name' => isset($value["name"]) ? trim($value["name"]) : '',
                'point' => $point,
                'content' => isset($value["rule_content"]) ? trim($value["rule_content"]) : "",
                'dic' => isset($value["dic"]) ? trim($value["dic"]) : '',
            ];
            $ruleIdPointList[] = $rule_id . "+" . $point;
        }
        //数据库规章对应的已有规章点列表
        /** @var RulesPoints[] $rulesPoints */
        $rulesPoints = RulesPointsService::getRulesPointsQuery()->andWhere(["CONCAT_WS('+',`rule_id`,`point`)" => $ruleIdPointList])->select("`id`,CONCAT_WS('+',`rule_id`,`point`) AS `rule_id_point`")->all();
        foreach ($rulesPoints as $key => $rulesPoint) {
            $exitsKey = array_search($rulesPoint->rule_id_point, $ruleIdPointList);
            if ($exitsKey !== false) {
                //已经有的规章点需要修改
                if ($rulesPoint->content !== $rulesPointParamData[$exitsKey]["content"]) {
                    $needUpdateContent[] = [
                        "id" => $rulesPoint->id,
                        "content" => $rulesPointParamData[$exitsKey]["content"],
                    ];
                }
                if ($rulesPoint->name !== $rulesPointParamData[$exitsKey]["name"]) {
                    $needUpdateName[] = [
                        "id" => $rulesPoint->id,
                        "name" => $rulesPointParamData[$exitsKey]["name"],
                    ];
                }
                if ($rulesPoint->dic !== $rulesPointParamData[$exitsKey]["dic"]) {
                    $needUpdateDic[] = [
                        "id" => $rulesPoint->id,
                        "dic" => $rulesPointParamData[$exitsKey]["dic"],
                    ];
                }
                unset($rulesPointParamData[$exitsKey]);
            }
        }
        $rulesPointParam = [
            'rule_id',
            'name',
            'point',
            'content',
            'dic',
        ];
        //添加规章知识点
        Yii::$app->db->createCommand()->batchInsert(RulesPoints::tableName(), $rulesPointParam, $rulesPointParamData)->execute();
        //修改规章知识点
        if ($needUpdateContent != []) {
            $sql = $this->batchUpdate(RulesPoints::tableName(), "id", "content", $needUpdateContent, true);
            Yii::$app->db->createCommand($sql)->execute();
        }
        if ($needUpdateName != []) {
            $sql = $this->batchUpdate(RulesPoints::tableName(), "id", "name", $needUpdateName, true);
            Yii::$app->db->createCommand($sql)->execute();
        }
        if ($needUpdateDic != []) {
            $sql = $this->batchUpdate(RulesPoints::tableName(), "id", "dic", $needUpdateDic, true);
            Yii::$app->db->createCommand($sql)->execute();
        }
        return $this->asJson();
    }


    /**
     * 规章修改
     * @param $id
     * @return Response
     * @throws AjaxException
     * @throws InvalidConfigException
     */
    public function actionRulesUpdate($id)
    {
        //校验
        $model = RulesService::getRulesById($id);
        $this->setAttributeFromGetAndPost($model);
        //校验是否重名
        $otherInfo = RulesService::getQuery()
            ->andWhere(['<>', 'id', $id])
            ->andWhere(["rule_name" => $model->rule_name, "version" => $model->version])
            ->one();
        if ($otherInfo) {
            return $this->asJson([], 1, "名称+版本号 {$model->rule_name}+{$model->version} 已存在！"); //通知前端
        }
        if ($model->save()) {
            return $this->asJson();
        } else {
            return $this->returnError($model->getErrorSummary(true)[0]);
        }
    }

    /**
     * 规章删除
     * @param $id
     * @return Response
     * @throws Exception
     * @throws Throwable
     */
    public function actionRulesDelete($id)
    {
        //校验
        $model = RulesService::getRulesById($id);
        //开启事务
        Yii::$app->db->transaction(function () use ($model, $id) {
            $model->delete_time = time();
            if (!$model->save()) {
                throw new Exception($model->getErrorSummary(true)[0]);
            }
            //删除对应的知识点
            RulesPointsService::deleteByRulesId($id);
        });
        return $this->asJson();
    }


    /**
     * 规章列表
     * @param $category
     * @return Response
     */
    public function actionRulesListCategory($category)
    {
        $query = RulesService::getQuery()
            ->andWhere(['rule_category' => $category, 'rule_status' => 1])
            ->orderBy("id desc");
        $data['data'] = RulesService::getAllList($query);
        return $this->asJson($data);
    }


    /**
     * 规章知识点列表
     * @param null $rule_id
     * @return Response
     */
    public function actionRulesPointsListById($rule_id = null)
    {
        $query = RulesPointsService::getRulesPointsQuery()
            ->andWhere(['rule_id' => $rule_id])
            ->orderBy("point desc");
        $data['data'] = RulesPointsService::getAllList($query);
        return $this->asJson($data);
    }

    /**
     * 规章知识点添加
     * @return Response
     * @throws Exception
     */
    public function actionRulesPointsAdd()
    {
        $post = Yii::$app->request->post();
        if (!isset($post["rule_id"])) {
            return $this->asJson([], 1, "数据非法！");
        }
        $rules = RulesPointsService::getRulesPointsQuery()->andWhere(["rule_id" => $post["rule_id"], "point" => $post["point"]])->one();
        if ($rules) {
            return $this->asJson([], 1, "知识点编号 {$post["point"]} 已存在！");
        }
        $model = new RulesPoints($post);
        if (!$model->save()) {
            throw new Exception($model->getErrorSummary(true)[0]);
        }
        $data = [];
        return $this->asJson($data);
    }

    /**
     * 规章知识点更新
     * @param $id
     * @return Response
     * @throws InvalidConfigException
     * @throws AjaxException
     */
    public function actionRulesPointsUpdate($id)
    {
        $model = RulesPointsService::getRulesPointsById($id);
        $this->setAttributeFromGetAndPost($model);
        //判断某个编号是否重复
        $RulesPoints = RulesPointsService::getRulesPointsQuery()->andWhere(["and", ["rule_id" => $model->rule_id, "point" => $model->point], ["<>", "id", $id]])->one();
        if ($RulesPoints) {
            throw new AjaxException("同一个规章,编号不能重复!");
        }
        if ($model->save()) {
            return $this->asJson();
        } else {
            return $this->returnError($model->getErrorSummary(true)[0]);
        }
    }

    /**
     * 规章知识点删除
     * @param $id
     * @return Response
     * @throws Exception
     */
    public function actionRulesPointsDeleteById($id)
    {
        $model = RulesPointsService::getRulesPointsById($id);
        $model->delete_time = time();
        if (!$model->save()) {
            throw new Exception($model->getErrorSummary(true)[0]);
        }
        return $this->asJson();
    }
}