package com.platform.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.platform.annotation.CanUserUpdateRecord;
import com.platform.entity.BrandEntity;
import com.platform.entity.SceneEntity;
import com.platform.entity.SysUserEntity;
import com.platform.enums.ResultCodeEnum;
import com.platform.exception.CommonBaseException;
import com.platform.service.BrandService;
import com.platform.service.SceneService;
import com.platform.service.SysDeptService;
import com.platform.service.SysUserService;
import com.platform.utils.*;
import com.platform.vo.BrandBindUserVo;
import com.platform.vos.RequestScene;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Controller
 *
 * @author lipengjun
 * @email 939961241@qq.com
 * @date 2017-08-19 17:59:15
 */
@Api(tags = "管理后台店铺操作相关接口")
@RestController
@RequestMapping("scene")
@Slf4j
public class SceneController extends AbstractController{
    @Autowired
    private SceneService sceneService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysDeptService sysDeptService;

    @Autowired
    private DepartmentUtils departmentUtils;

    @Value("${scenePath}")
    private String scenePath;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 更新显示状态
     */
    @CanUserUpdateRecord
    @RequestMapping("/update")
    @RequiresPermissions("brand:list")
    @Transactional(rollbackFor = Exception.class)
    public R updateShowStatus(@RequestBody SceneEntity sceneParam) {
        if(ObjectUtils.isEmpty(sceneParam.getId()) && ObjectUtils.isEmpty(sceneParam.getSceneNum())){
            log.error("参数有误");
            return R.error("参数有误");
        }
        if(!ObjectUtils.isEmpty(sceneParam.getId())){
            sceneService.update(sceneParam);
        }else{
            // 获取情景信息
            RequestScene requestScene = new RequestScene();
            requestScene.setToken(sceneParam.getToken());
            requestScene.setNums("'"+sceneParam.getSceneNum()+"'");
            requestScene.setUserId(-1L);
            String url = scenePath + "scene/list";
            JSONObject mySceneJsonData = getSceneFromKanKan(url , requestScene);
            if(ObjectUtils.isEmpty(mySceneJsonData) || !mySceneJsonData.containsKey("list")){
                log.error("场景码错误！");
                return R.error("场景码错误！");
            }

            List<Object> mySceneList = mySceneJsonData.getJSONArray("list");
            if (ObjectUtils.isEmpty(mySceneList)) {
                log.error("场景码错误！");
                return R.error("场景码错误！");
            }
            JSONObject sceneRes = JSONObject.parseObject(JSONObject.toJSONString(mySceneList.get(0)));
            SceneEntity sceneEntity = new SceneEntity();
            sceneEntity.setIsShow(sceneParam.getIsShow());
            if(ObjectUtils.isEmpty(sceneEntity.getIsShow())){
                sceneEntity.setIsShow(0);
            }
            String webSite = sceneRes.getString("webSite");
            sceneEntity.setSceneUrl(webSite);
            sceneEntity.setAppListPicUrl(sceneParam.getAppListPicUrl());
            String phone = sceneRes.getString("phone");
            SysUserEntity userEntity = sysUserService.queryByUserMobile(phone);
            if (ObjectUtils.isEmpty(userEntity)) {
                log.error("找不到用户：{}",phone);
                return R.error("找不到用户：" + phone);
            }
            sceneEntity.setCreateUserId(userEntity.getUserId());
            sceneEntity.setName(sceneRes.getString("sceneName"));
            if(!ObjectUtils.isEmpty(sceneParam.getName())){
                sceneEntity.setName(sceneParam.getName());
            }
            sceneEntity.setSceneNum(sceneParam.getSceneNum());
            int result = sceneService.save(sceneEntity);
            if(result==0){
                log.error("场景已经被绑定!");
                return R.error("场景已经被绑定!");
            }
        }
        return R.ok();
    }

    public List<Long> getAllSubDeptIds(Long deptId) {
        if (null == deptId) {
            log.info("部门ID为空");
            return new ArrayList<>();
        }
        List<Long> allDeptIdList = new ArrayList<>();
        int leve = 0;
        leve = findDeptIdByParent(deptId, 0, allDeptIdList);
        log.info("获取到当前部门以及所有子部门(10层嵌套以内)的id为:{}，部门层级为:{}",
                JSON.toJSONString(allDeptIdList) , leve);
        return allDeptIdList;
    }

    private int findDeptIdByParent(long deptId, int level, List<Long> deptIdList) {

        if (level > 10) {
            log.info("嵌套层数超过了10层");
            return level;
        }
        deptIdList.add(deptId);
        //获取所有子部门的id
        List<Long> subDeptIdList = sysDeptService.queryDetpIdList(deptId);
        if (CollectionUtils.isEmpty(subDeptIdList)) {
            //自己算一层，没有子部门，要先加上自己这一层
            return level + 1;
        }
        int maxLevel = 0;
        for(Long id : subDeptIdList){
            //遍历所有子部门的子部门，并记下子部门中嵌套最深的层数
            int tmpLevel = findDeptIdByParent(id, level, deptIdList);
            if(tmpLevel > maxLevel){
                maxLevel = tmpLevel;
            }
        }
        //添加子部门的id
        deptIdList.addAll(subDeptIdList);
        //叠加子部门的最大层级
        level += maxLevel;
        //加上自己这一层
        level += 1;
        return level;
    }

    /**
     * 查看列表
     */
    @PostMapping("/list")
    @RequiresPermissions("brand:list")
    public R list(@RequestBody RequestScene requestScene) {
        //查询列表数据
        if (null == requestScene || org.apache.commons.lang3.StringUtils.isBlank(requestScene.getToken())) {
            return  R.error("缺少必要参数");
        }
        if(!ObjectUtils.isEmpty(requestScene.getPage())){
            requestScene.setPageNum(requestScene.getPage());
        }
        //看看的页码从1开始算起
        if(requestScene.getPageNum()==0){
            requestScene.setPageNum(1L);
        }
        if (!ObjectUtils.isEmpty(requestScene.getLimit())) {
            requestScene.setPageSize(requestScene.getLimit());
        }
        if(!ObjectUtils.isEmpty(requestScene.getName())){
            requestScene.setSceneName(requestScene.getName());
        }
        Long userId = getUserId();
        boolean geratedable = false;
        if(Constant.SUPER_ADMIN == userId){
            requestScene.setUserId(-1L);
        }else{
            // 获取当前用户手机号
            SysUserEntity user = sysUserService.queryObject(userId);
            if(getUser().getRoleId() == 6){
                geratedable = true;
                // 获取该公司下所有员工手机号
                List<Long> subDeptIds = getAllSubDeptIds(getDeptId());
                List<SysUserEntity> users = sysUserService.getSysUserListByDeptIds(subDeptIds);
                requestScene.setPhone(users.stream().map(SysUserEntity::getMobile).collect(Collectors.joining(";")));
            }else if(getUser().getRoleId() == 8){
                requestScene.setPhone(user.getMobile());
            }
        }
        String url = scenePath + "scene/list";
        JSONObject mySceneJsonData = getSceneFromKanKan(url , requestScene);
        if(ObjectUtils.isEmpty(mySceneJsonData) || !mySceneJsonData.containsKey("list")){
            return R.ok().put("page", null);
        }

        List<Object> mySceneList = mySceneJsonData.getJSONArray("list");
        if (ObjectUtils.isEmpty(mySceneList)) {
            return R.ok().put("page", mySceneJsonData);
        }
        boolean finalGeratedable = geratedable;
        mySceneList = mySceneList.parallelStream().map(Object -> JSONObject.parseObject(JSONObject.toJSONString(Object)))
                .peek(object -> {
                    object.put("sceneUrl", object.getString("webSite"));
                    object.put("name",object.getString("sceneName"));
                    // 查找本地记录
                    String sceneNum = object.getString("num");
                    SceneEntity sceneEntity = sceneService.queryByScene(sceneNum);
                    object.put("id",null);
                    if(!ObjectUtils.isEmpty(sceneEntity)){
                        object.put("id",sceneEntity.getId());
                        object.put("appListPicUrl",sceneEntity.getAppListPicUrl());
                        object.put("isShow",sceneEntity.getIsShow());
                        object.put("sceneUrl",sceneEntity.getSceneUrl());
                        object.put("name",sceneEntity.getName());
                        // 判断名称是否修改，如果修改，则同步到本地
                        if (!object.get("sceneName").toString().equals(sceneEntity.getName())) {
                            sceneEntity.setName(object.get("sceneName").toString());
                            sceneService.update(sceneEntity);
                        }
                    }
                    object.put("lived", true);
                    if(finalGeratedable){
                        // 查找是否生成直播间记录
                        BrandEntity brandEntity = brandService.queryByScene(sceneNum);
                        if (ObjectUtils.isEmpty(brandEntity)) {
                            object.put("lived", false);
                        }
                    }
                }).collect(Collectors.toList());
        mySceneJsonData.put("list", mySceneList);
        return R.ok().put("page", mySceneJsonData);
    }

    public JSONObject getSceneFromKanKan(String url , RequestScene requestScene){
        if(org.apache.commons.lang3.StringUtils.isBlank(url )){
            throw new CommonBaseException(ResultCodeEnum.D101 , "入参不全，无法获取四维场景列表");
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("token", requestScene.getToken());
        HttpEntity<Object> formEntity = new HttpEntity<>(requestScene, headers);
        ResponseEntity<String> kankanResult = restTemplate.postForEntity(url,formEntity,String.class);
        //把信息封装为json
        JSONObject res = JSONObject.parseObject(kankanResult.getBody());
        return parseKanKanRsp(res);
    }

    public JSONObject parseKanKanRsp(JSONObject result){
        if(null == result){
            throw new CommonBaseException(ResultCodeEnum.D101 , "四维看看返回数据异常");
        }
        log.info("看看获取场景列表返回:{}", result.toJSONString());
        int code = -10;
        if (result.containsKey("code")) {
            code = (int) result.get("code");
            if (code != 200) {
                throw new CommonBaseException(ResultCodeEnum.D101 , "调用四维看看失败");
            }
            JSONObject data =  result.getJSONObject("message");
            if(null == data){
                throw new CommonBaseException(ResultCodeEnum.D101 , "四维看看返回数据异常-缺data");
            }

            return data;
        } else {
            throw new CommonBaseException(ResultCodeEnum.D101 , "调用四维看看失败");
        }
    }

    /**
     * 查看信息
     */
    @PostMapping("/info")
    @RequiresPermissions("brand:info")
    public R info(@RequestBody SceneEntity SceneEntity) {
        if(!ObjectUtils.isEmpty(SceneEntity.getId())){
            SceneEntity scene = sceneService.queryObject(SceneEntity.getId().intValue());
            return R.ok().put("brand", scene);
        }
        String token = SceneEntity.getToken();
        if(ObjectUtils.isEmpty(token)){
            return R.error("请传递token信息");
        }
        // 获取情景信息
        RequestScene requestScene = new RequestScene();
        requestScene.setToken(token);
        requestScene.setNums("'"+SceneEntity.getSceneNum()+"'");
        requestScene.setUserId(-1L);
        String url = scenePath + "scene/list";
        JSONObject mySceneJsonData = getSceneFromKanKan(url , requestScene);
        if(ObjectUtils.isEmpty(mySceneJsonData) || !mySceneJsonData.containsKey("list")){
            return R.error("场景码错误！");
        }

        List<Object> mySceneList = mySceneJsonData.getJSONArray("list");
        if (ObjectUtils.isEmpty(mySceneList)) {
            return R.error("场景码错误！");
        }
        JSONObject scene = JSONObject.parseObject(JSONObject.toJSONString(mySceneList.get(0)));
        SceneEntity.setSceneUrl(scene.getString("webSite"));
        SceneEntity.setName(scene.getString("sceneName"));
        return R.ok().put("brand", SceneEntity);
    }


    /**
     * 删除
     */
    @CanUserUpdateRecord
    @RequestMapping("/delete")
    @RequiresPermissions("brand:delete")
    @Transactional(rollbackFor = Exception.class)
    public R delete(@RequestBody Integer[] ids) {
        List<SceneEntity> brandEntityList = new ArrayList<>();
        if(ObjectUtils.isEmpty(ids)){
            return R.ok();
        }
        sceneService.deleteBatch(ids);
        return R.ok();
    }

    /**
     * 删除
     */
    @CanUserUpdateRecord
    @PostMapping("/generateDefaultLiveRoom")
    @RequiresPermissions("brand:delete")
    public R generateDefaultLiveRoom(@RequestBody SceneEntity requestScene) {
        String sceneNum = requestScene.getSceneNum();
        if(ObjectUtils.isEmpty(sceneNum)){
            return R.error("参数有误！");
        }

        BrandEntity brand = brandService.queryByScene(sceneNum);
        if(!ObjectUtils.isEmpty(brand)){
            return R.error("直播间已存在！");
        }

        SceneEntity entity = sceneService.queryByScene(sceneNum);
        if(ObjectUtils.isEmpty(entity)){
            updateShowStatus(requestScene);
        }
        BrandEntity brandEntity = brandService.generateDefaultLiveRoom(sceneNum);
        if(ObjectUtils.isEmpty(brandEntity)){
            return R.error("场景获取失败！");
        }
        BrandBindUserVo brandBindUserVo = new BrandBindUserVo();
        brandBindUserVo.setUserId(getUserId());
        brandBindUserVo.setBrandId(brandEntity.getId().intValue());
        brandBindUserVo.setCanShow(0);
        brandBindUserVo.setType(1);
        brandService.bindUsers(Arrays.asList(brandBindUserVo));
        return R.ok("生成直播间功能，请前往直播间查看。");
    }

    @ApiOperation(value = "获取客户所有的非直播间场景数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "用户登录的token", paramType = "body", required = true, dataType = "String"),
            @ApiImplicitParam(name = "pageNum", value = "当前页码", paramType = "body", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", paramType = "body", required = true, dataType = "Long")}
    )
    @PostMapping("/getAllScene")
    @ResponseBody
    public R getAllScene(@RequestBody @ApiParam(name = "四维看看场景请求体", value = "传入json格式", required = true) RequestScene requestScene) {

        // 排除已绑定直播间的数据
        List<String> sceneNums = brandService.queryAllLiveSceneNum();
        List<Long> deptIds = null;

        Long userId = getUserId();
        if(Constant.SUPER_ADMIN != userId){
            //通过部门ID过滤数据
            if(null == getDeptId()){
                return R.ok().put("myScene", new ArrayList<>());
            }
            deptIds = departmentUtils.getAllSubDeptIds(getDeptId());
        }
        List<SceneEntity> brandList = sceneService.selectByDeptIdsAndExceptSceneNums(deptIds,sceneNums);
        Map<String ,Object> result = new HashMap<>();
        result.put("myScene" , brandList);
        return R.ok( result);
    }
}
