package com.yeejoin.amos.boot.module.app.biz.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.utils.Menu;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.biz.common.utils.TreeParser;
import com.yeejoin.amos.boot.module.app.api.common.MobileLoginParam;
import com.yeejoin.amos.boot.module.app.api.dto.CertInfoRequestParam;
import com.yeejoin.amos.boot.module.app.api.dto.TzBaseEnterpriseInfoDto;
import com.yeejoin.amos.boot.module.app.api.entity.EquipmentCategory;
import com.yeejoin.amos.boot.module.app.api.entity.PageParam;
import com.yeejoin.amos.boot.module.app.api.entity.TzBaseEnterpriseInfo;
import com.yeejoin.amos.boot.module.app.api.mapper.ViewJgClaimMapper;
import com.yeejoin.amos.boot.module.app.api.service.ITzBaseEnterpriseInfoService;
import com.yeejoin.amos.boot.module.app.biz.service.impl.CertDetailServiceImpl;
import com.yeejoin.amos.boot.module.app.biz.service.impl.EquipmentCategoryServiceImpl;
import com.yeejoin.amos.boot.module.app.biz.service.impl.TzsAppService;
import com.yeejoin.amos.boot.module.app.flc.api.entity.RegUnitInfo;
import com.yeejoin.amos.boot.module.app.flc.api.mapper.RegUnitInfoMapper;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.component.robot.AmosRequestContext;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.privilege.model.PermissionModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@Slf4j
@Api(tags = "tzs小程序接口")
@RequestMapping(value = "/tzs-app")
public class TzsAppController {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    TzsAppService appService;
    @Autowired
    private RegUnitInfoMapper regUnitInfoMapper;
    @Autowired
    private ViewJgClaimMapper viewJgClaimMapper;
    @Autowired
    ITzBaseEnterpriseInfoService iTzBaseEnterpriseInfoService;
    @Autowired
    private EquipmentCategoryServiceImpl equipmentCategoryService;
    private static final String LEVEL = "company";
    private static final String COMPANYPATH = "/company";
    private static final String JIANGUAN = "/";


    @Autowired
    AmosRequestContext amosRequestContext;

    @Autowired
    EquipmentCategoryServiceImpl equipmentCategoryServiceImpl;

    @Autowired
    CertDetailServiceImpl certDetailService;

    /**
     * 小程序获取设备详情
     *
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @GetMapping(value = "/equipmentInfo")
    @ApiOperation(httpMethod = "GET", value = "小程序获取设备详情", notes = "小程序获取设备详情")
    public ResponseModel<Object> getEquipmentInfo(String record) {
        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        CompanyModel companys = reginParams.getUserModel().getCompanys().get(0);
        Map<String, String> detial = viewJgClaimMapper.getDetialByCode(record);
        Map<String, Object> equipmentInfo;
        //判断是否有权限查看全部信息
        if (LEVEL.equals(companys.getLevel())) {
            //企业
            if (!ValidationUtil.isEmpty(detial.get("USE_UNIT_CREDIT_CODE")) && detial.get("USE_UNIT_CREDIT_CODE").equals(companys.getCompanyCode())) {
                equipmentInfo = appService.getEquipmentInfo(record);
            } else {
                equipmentInfo = appService.getEquipmentInfoWX(record);
            }
        } else {
            //监管
            if (!ValidationUtil.isEmpty(detial.get("ORG_BRANCH_CODE")) && detial.get("ORG_BRANCH_CODE").contains(companys.getOrgCode())) {
                equipmentInfo = appService.getEquipmentInfo(record);
            } else {
                equipmentInfo = appService.getEquipmentInfoWX(record);
            }
        }
        return ResponseHelper.buildResponse(equipmentInfo);
    }

    /**
     * 小程序获取设备详情-微信扫一扫
     *
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @GetMapping(value = "/equipmentInfoWX")
    @ApiOperation(httpMethod = "GET", value = "小程序获取设备详情", notes = "小程序获取设备详情")
    public ResponseModel<Object> getEquipmentInfoWX(String record) {
        return ResponseHelper.buildResponse(appService.getEquipmentInfoWX(record));
    }


    /**
     * 小程序获取证详情-微信扫一扫
     *
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
    @PostMapping(value = "/certInfo")
    @ApiOperation(httpMethod = "GET", value = "小程序获取登记证或者使用标志详情", notes = "小程序获取登记证或者使用标志详情")
    public ResponseModel<Map> getCertInfoForWX(@Validated @RequestBody CertInfoRequestParam requestParam, BindingResult result) {
        List<FieldError> fieldErrors = result.getFieldErrors();
        if (!fieldErrors.isEmpty()) {
            throw new BadRequest(fieldErrors.get(0).getDefaultMessage());
        }
        return ResponseHelper.buildResponse(certDetailService.getCertInfoForWX(requestParam));
    }


    /**
     * 根据监管码查询设备详情
     *
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @GetMapping(value = "/getEquipInfoBySuperviseCode")
    @ApiOperation(httpMethod = "GET", value = "根据监管码查询设备详情", notes = "根据监管码查询设备详情")
    public ResponseModel<Object> getEquipInfoBySuperviseCode(String supervisoryCode) {
        return ResponseHelper.buildResponse(appService.getEquipInfoBySuperviseCode(supervisoryCode));
    }

    /**
     * 登录
     *
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
    @PostMapping(value = "/mobile/login")
    @ApiOperation(httpMethod = "POST", value = "小程序登录", notes = "小程序登录")
    public ResponseModel<Map<String, Object>> login(@RequestBody MobileLoginParam param) {
        return ResponseHelper.buildResponse(appService.login(param));
    }

    /**
     * 小程序企业详情
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @RequestMapping(value = "/details", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "小程序企业详情", notes = "小程序企业详情")
    public ResponseModel<IPage<TzBaseEnterpriseInfoDto>> pageInfo(String unitCode) {
        PageParam pageParam = new PageParam();
        LambdaQueryWrapper<TzBaseEnterpriseInfo> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        objectLambdaQueryWrapper.eq(!ValidationUtil.isEmpty(unitCode), TzBaseEnterpriseInfo::getUseCode, unitCode);
        TzBaseEnterpriseInfo neInfo = iTzBaseEnterpriseInfoService.getOne(objectLambdaQueryWrapper, true);
        return ResponseHelper.buildResponse(iTzBaseEnterpriseInfoService.page(pageParam, neInfo.getUseUnit()));
    }

    /**
     * 小程序菜单权限
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @RequestMapping(value = "/permission/tree", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "小程序菜单权限", notes = "小程序菜单权限")
    public FeignClientResult<Collection<PermissionModel>> tree(HttpServletRequest http, @RequestParam(value = "most", required = false) String most) {
        FeignClientResult<Collection<PermissionModel>> app = new FeignClientResult<Collection<PermissionModel>>();
        if (ValidationUtil.isEmpty(most)) {
            //根据当前登录人的公司是企业还是监管来过滤
            List<JSONObject> objectList = equipmentCategoryService.getCompanyType();
            List<JSONObject> total = objectList.stream().filter(item -> !LEVEL.equals(item.getString("level"))).collect(Collectors.toList());
            if (total.size() == 0) {
                //企业
                app = Privilege.permissionClient.queryPermissionTree("APP", null, null, COMPANYPATH, null);
            } else {
                //监管
                app = Privilege.permissionClient.queryPermissionTree("APP", null, null, JIANGUAN, null);
            }
        } else {
            //更多应用
            app = Privilege.permissionClient.queryPermissionTree("APP", null, null, most, null);

        }

        return app;
    }

    //修改密码
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @RequestMapping(value = "/{userId}/password", method = RequestMethod.PUT)
    @ApiOperation(httpMethod = "PUT", value = "修改密码", notes = "修改密码")
    public ResponseModel<Boolean> updatePassword(@PathVariable("userId") String userId, @RequestBody AgencyUserModel AgencyUserModel) {
        Boolean result = false;
        if (ValidationUtil.isEmpty(userId) ||
                ValidationUtil.isEmpty(AgencyUserModel.getOriginalPassword()) ||
                ValidationUtil.isEmpty(AgencyUserModel.getRePassword()) ||
                ValidationUtil.isEmpty(AgencyUserModel.getPassword())) {
            log.error("用户信息不能为空");
            return ResponseHelper.buildResponse(result);
        }
        if (!AgencyUserModel.getRePassword().equals(AgencyUserModel.getPassword())) {
            log.error("两次密码不一致");
            return ResponseHelper.buildResponse(result);
        }
        //平台修改
        AgencyUserModel.setUserId(userId);
        FeignClientResult<AgencyUserModel> agencyUserModelFeignClientResult = Privilege.agencyUserClient.modifyPassword(userId, AgencyUserModel);
        if (agencyUserModelFeignClientResult.getStatus() != 200) {
            log.error("Privilege远程调用失败");
            return ResponseHelper.buildResponse(result);
        }
        if (ValidationUtil.isEmpty(agencyUserModelFeignClientResult.getResult()) || ValidationUtil.isEmpty(agencyUserModelFeignClientResult.getResult().getUserId())) {
            log.error("平台修改失败");
            return ResponseHelper.buildResponse(result);

        }
        //走业务修改
        LambdaQueryWrapper<RegUnitInfo> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        objectLambdaQueryWrapper.eq(RegUnitInfo::getAdminUserId, agencyUserModelFeignClientResult.getResult().getUserId());
        RegUnitInfo regUnitInfo = new RegUnitInfo();
        regUnitInfo.setAdminLoginPwd(AgencyUserModel.getRePassword());
        int update = regUnitInfoMapper.update(regUnitInfo, objectLambdaQueryWrapper);
        if (update == 0) {
            log.error("业务更新失败");
            return ResponseHelper.buildResponse(result);
        }
        result = true;

        return ResponseHelper.buildResponse(result);
    }


    //扫一扫功能通过监管查询SEQUENCE_NBR
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @RequestMapping(value = "/supervisoryCode", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "扫一扫功能通过监管查询SEQUENCE_NBR", notes = "扫一扫功能通过监管查询SEQUENCE_NBR")
    public ResponseModel<String> supervisoryCode(String code) {
        String sequenceNbr = viewJgClaimMapper.supervisoryCode(code);
        return ResponseHelper.buildResponse(sequenceNbr);
    }


    @TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
    @RequestMapping(value = "/wxUserLogin", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "微信授权登陆", notes = "微信授权登陆")
    public ResponseModel<JSONObject> wxUserLogin(@RequestBody JSONObject wx) {
        return ResponseHelper.buildResponse(appService.wxUserLogin(wx));
    }

    //企业的设备总数统计
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "企业的认领设备总数", notes = "企业的认领设备总数")
    @GetMapping(value = "/equipmentCount")
    public ResponseModel<Object> equipClaimOverview(String unitCode) {
        return ResponseHelper.buildResponse(appService.equipmentCount(unitCode));
    }

    //设备列表
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "设备列表", notes = "设备列表")
    @GetMapping(value = "/getTable")
    public ResponseModel<Page<JSONObject>> getTable(@RequestParam Map<String, Object> map) {
        JSONObject jsonObject = new JSONObject(map);
        return ResponseHelper.buildResponse(equipmentCategoryServiceImpl.queryByKeys(jsonObject));
        //return ResponseHelper.buildResponse(appService.getTable(map));

    }

    //行政区划树

    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "行政区划code", notes = "行政区划code")
    @GetMapping(value = "/getRegionName")
    public ResponseModel<JSONArray> getRegionName() {
        return ResponseHelper.buildResponse(appService.getRegionName());
    }


    @TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
    @ApiOperation(value = "获取机器人登录token", notes = "获取机器人登录token")
    @GetMapping(value = "/acquireToken")
    synchronized public ResponseModel<String> getRobotLoginToken() {
        return ResponseHelper.buildResponse(amosRequestContext.getToken());
    }

    /**
     * 树
     *
     * @return
     * @throws Exception
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "装备分类列表全部数据查询", notes = "装备分类列表全部数据查询")
    @GetMapping(value = "/tree")
    public ResponseModel<Object> tree(@RequestParam(value = "code", required = false) String code) throws Exception {
        if (ObjectUtils.isEmpty(code)) {
            return ResponseHelper.buildResponse(new ArrayList<>());
        }
        EquipmentCategory root = equipmentCategoryServiceImpl.getOne(new LambdaQueryWrapper<EquipmentCategory>().eq(EquipmentCategory::getCode, code));
        QueryWrapper<EquipmentCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.likeRight("code", code.replaceAll("0+$", ""));
        Collection<EquipmentCategory> list = equipmentCategoryServiceImpl.list(queryWrapper);
        Menu menu = new Menu(root.getId(), root.getName(), 0L, 0);
        List<Menu> menus = TreeParser.getTree(root.getId(), list, EquipmentCategory.class.getName(), "getId", 0, "getName",
                "getParentId", null, "getCode");
        menu.setChildren(menus);
        List<Menu> tree = new ArrayList<>();
        tree.add(menu);
        return ResponseHelper.buildResponse(tree);
    }

    @TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
    @RequestMapping(value = "/page", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "企业列表", notes = "企业列表")
    public ResponseModel<IPage<TzBaseEnterpriseInfoDto>> page(PageParam pageParam,
                                                              TzBaseEnterpriseInfoDto tzBaseEnterpriseInfoDto) {
        return ResponseHelper.buildResponse(iTzBaseEnterpriseInfoService.page(pageParam, tzBaseEnterpriseInfoDto));
    }

    /**
     * 小程序获取证详情-根据登记证编号查询
     *
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
    @PostMapping(value = "/certInfo/certNo")
    @ApiOperation(httpMethod = "POST", value = "小程序获取登记证或者使用标志详情", notes = "小程序获取登记证或者使用标志详情")
    public ResponseModel<Map<String, Object>> getCertInfoByCertNoForWX(@Validated @RequestBody CertInfoRequestParam requestParam, BindingResult result) {
        List<FieldError> fieldErrors = result.getFieldErrors();
        if (!fieldErrors.isEmpty()) {
            throw new BadRequest(fieldErrors.get(0).getDefaultMessage());
        }
        return ResponseHelper.buildResponse(certDetailService.getCertInfoByCertNoForWX(requestParam));
    }
}
