package com.artfess.yhxt.open.base.controller;


import cn.hutool.json.JSONUtil;
import com.artfess.base.annotation.ApiGroup;
import com.artfess.base.conf.JwtConfig;
import com.artfess.base.constants.ApiGroupConsts;
import com.artfess.base.context.BaseContext;
import com.artfess.base.enums.ResponseErrorEnums;
import com.artfess.base.model.CommonResult;
import com.artfess.base.util.EncryptUtil;
import com.artfess.base.util.time.DateUtil;
import com.artfess.bpm.engine.task.service.DefaultRestfulService;
import com.artfess.sysConfig.persistence.manager.SysDictionaryManager;
import com.artfess.sysConfig.persistence.model.SysDictionaryDetail;
import com.artfess.uc.util.ContextUtil;
import com.artfess.yhxt.basedata.manager.BridgeInformationManager;
import com.artfess.yhxt.basedata.model.BridgeInformation;
import com.artfess.yhxt.check.regular.vo.BridgeArchivesVo;
import com.artfess.yhxt.disease.manager.DiseaseManager;
import com.artfess.yhxt.disease.model.Disease;
import com.artfess.yhxt.open.base.util.JwtCheckUtils;
import com.artfess.yhxt.open.base.vo.Auth;
import com.artfess.yhxt.thirdparty.manager.BizTpBridgeHealthManager;
import com.artfess.yhxt.thirdparty.manager.BizTpBridgeManager;
import com.artfess.yhxt.thirdparty.manager.BizTpDeviceManager;
import com.artfess.yhxt.thirdparty.manager.BizTpWarningEventsManager;
import com.artfess.yhxt.thirdparty.model.BizTpBridge;
import com.artfess.yhxt.thirdparty.model.BizTpBridgeHealth;
import com.artfess.yhxt.thirdparty.model.BizTpDevice;
import com.artfess.yhxt.thirdparty.model.BizTpWarningEvents;
import com.artfess.yhxt.thirdparty.vo.SynchronizationSignVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Clock;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClock;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import oracle.sql.DATE;
import org.apache.catalina.filters.RemoteIpFilter;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.apache.tools.ant.taskdefs.Sync;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;


@RestController
@RequestMapping("/server/")
@Api(tags = "第三方传输信息对外提供入口")
@ApiGroup(group = {ApiGroupConsts.GROUP_BIZ})
public class TransmissionController {


    @Resource
    BizTpBridgeManager bizTpBridgeManager;
    @Resource
    BridgeInformationManager bridgeInformationManager;
    @Resource
    BizTpDeviceManager bizTpDeviceManager;
    @Resource
    BizTpBridgeHealthManager bizTpBridgeHealthManager;
    @Resource
    BizTpWarningEventsManager bizTpWarningEventsManager;
    @Resource
    JwtCheckUtils jwtCheckUtils;
    @Resource
    JwtConfig jwtConfig;

    /**
     * 铁建一联
     */
    private final List<String> accessTransKeyList = Arrays.asList("TJYL001001");

    // 加密盐值
    private final static String SALT = "PASSWORD001001";

    private Clock clock = DefaultClock.INSTANCE;


    @PostMapping("/transmission/save/bridge")
    @ApiOperation("新增或者修改桥梁")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Map> saveBridge(@ApiParam(name="bizTpBridge", value="桥梁基础信息") @RequestBody List<BizTpBridge> bizTpBridges,HttpServletRequest request) {
       String token = request.getHeader("Authorization");

      if( !checkToken(token)){
          return new CommonResult<Map>(false, "请重新获取token", null);
      }
        token = token.replaceAll("Bearer ", "");
       String tokenAccessKey = jwtCheckUtils.getTokenAccessKey(token);


        for (BizTpBridge bizTpBridge : bizTpBridges) {
            String bridgeCode = bizTpBridge.getBridgeCode();
            if(null == bridgeCode || bridgeCode.isEmpty()){
                return new CommonResult<>(false, "桥梁编码不能为空", null);
            }


            String id = bizTpBridge.getId();
            if(null == id || id.isEmpty()){
                return new CommonResult<Map>(false, "桥梁ID不能为空", null);
            }
            //防止不同系统
            bizTpBridge.setId(tokenAccessKey+id);

            //方向
            Integer direction = bizTpBridge.getDirection();


            //判断该桥梁是否在养护系统是否存在  编码加方向
            BridgeInformation bridgeInformation = bridgeInformationManager.getBridgeByCode(bridgeCode,direction );

            if(null == bridgeInformation){
                return new CommonResult<Map>(false, "该桥梁在系统中不存在", null);
            }else {
                bizTpBridge.setBridgeId(bridgeInformation.getId());
                bizTpBridge.setCompanyIds(bridgeInformation.getCompanyIds());
                bizTpBridge.setCompanyId(bridgeInformation.getCompanyId());
                bizTpBridge.setCompanyName(bridgeInformation.getCompanyName());
                bizTpBridge.setRoadSegmentId(bridgeInformation.getRoadSegmentId());
                bizTpBridge.setRoadSegmentName(bridgeInformation.getRoadSegmentName());
            }


            if(null == bizTpBridge.getIsDele()){
                bizTpBridge.setIsDele("0");
            }
            BizTpBridge  bridge= bizTpBridgeManager.selectById(bizTpBridge.getId());
            //保存修改
            if(null == bridge){
                 bizTpBridgeManager.save(bizTpBridge);
            }else {
                bizTpBridge.setTenantId("-1");
                 bizTpBridgeManager.update(bizTpBridge);
            }

        }


        return new CommonResult<>(true, "操作成功");
    }


    @PostMapping("/transmission/save/device")
    @ApiOperation("新增或者修改设备")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Map> saveDevice(@ApiParam(name="bizTpDevice", value="设备基础信息") @RequestBody List<BizTpDevice> bizTpDevices,HttpServletRequest request){

        String token = request.getHeader("Authorization");

        if( !checkToken(token)){
            return new CommonResult<Map>(false, "请重新获取token", null);
        }
        token = token.replaceAll("Bearer ", "");
        String tokenAccessKey = jwtCheckUtils.getTokenAccessKey(token);
        for (BizTpDevice bizTpDevice : bizTpDevices) {
            if(null == bizTpDevice.getId() || bizTpDevice.getId().isEmpty()){
                return new CommonResult<Map>(false, "设备ID不能为空", null);
            }

            //防止重复设置符合id
            bizTpDevice.setId(tokenAccessKey+bizTpDevice.getId());
            if(null == bizTpDevice.getIsDele()){
                bizTpDevice.setIsDele("0");
            }
            BizTpDevice device = bizTpDeviceManager.getById(bizTpDevice.getId());


            //修改
            if(null != device &&  "0" !=  device.getIsDele()){
                device.setState(bizTpDevice.getState());

                if(null !=  bizTpDevice.getTrBridgeId()){
                    device.setTrBridgeId(tokenAccessKey+bizTpDevice.getTrBridgeId());

                    BizTpBridge  bridge= bizTpBridgeManager.getById(bizTpDevice.getTrBridgeId());
                    if(null == bridge){
                        return new CommonResult<Map>(false, "未找到相关桥梁传输信息", null);
                    }
                    device.setTpBridgeId(bridge.getBridgeId());
                    device.setTpBridgeName(bridge.getBridgeName());
                    device.setTpBridgeType(bridge.getType());

                    device.setCompanyIds(bridge.getCompanyIds());
                    device.setCompanyId(bridge.getCompanyId());
                    device.setCompanyName(bridge.getCompanyName());
                    device.setRoadSegmentId(bridge.getRoadSegmentId());
                    device.setRoadSegmentName(bridge.getRoadSegmentName());
                }


                device.setIsDele(bizTpDevice.getIsDele());
                bizTpDeviceManager.update(device);
            }else {

                //保存
                if(null == bizTpDevice.getDeviceCode() || bizTpDevice.getDeviceCode().isEmpty()){
                    return new CommonResult<Map>(false, "设备编码不能为空", null);
                }

                if(null == bizTpDevice.getTrBridgeId() ||  bizTpDevice.getTrBridgeId().isEmpty()){
                    return new CommonResult<Map>(false, "关联桥梁ID不能为空", null);
                }
                //防止重复设置符合id
                bizTpDevice.setTrBridgeId(tokenAccessKey+bizTpDevice.getTrBridgeId());

                BizTpBridge  bridge= bizTpBridgeManager.getById(bizTpDevice.getTrBridgeId());
                if(null == bridge){
                    return new CommonResult<Map>(false, "未找到相关桥梁传输信息", null);
                }
                bizTpDevice.setTpBridgeId(bridge.getBridgeId());
                bizTpDevice.setTpBridgeName(bridge.getBridgeName());
                bizTpDevice.setTpBridgeType(bridge.getType());

                bizTpDevice.setCompanyIds(bridge.getCompanyIds());
                bizTpDevice.setCompanyId(bridge.getCompanyId());
                bizTpDevice.setCompanyName(bridge.getCompanyName());
                bizTpDevice.setRoadSegmentId(bridge.getRoadSegmentId());
                bizTpDevice.setRoadSegmentName(bridge.getRoadSegmentName());
                boolean result = bizTpDeviceManager.saveOrUpdate(bizTpDevice);
            }
        }

        return new CommonResult<>(true, "操作成功");
    }



    @PostMapping("/transmission/save/monitor")
    @ApiOperation("桥梁健康监测数据传输")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Map> saveMonitor(@ApiParam(name="bridgeHealth", value="桥梁健康相关信息") @RequestBody List<BizTpBridgeHealth> bridgeHealths,HttpServletRequest request){
        String token = request.getHeader("Authorization");

        if( !checkToken(token)){
            return new CommonResult<Map>(false, "请重新获取token", null);
        }
        token = token.replaceAll("Bearer ", "");

        String tokenAccessKey = jwtCheckUtils.getTokenAccessKey(token);

        for (BizTpBridgeHealth bridgeHealth : bridgeHealths) {
            String trBridgeId = bridgeHealth.getTrBridgeId();
            if(null == trBridgeId || trBridgeId.isEmpty()){
                return new CommonResult<Map>(false, "桥梁ID不能为空", null);
            }
            bridgeHealth.setTrBridgeId(tokenAccessKey+bridgeHealth.getTrBridgeId());


            //查询桥梁是否已存在
            BizTpBridge  bridge= bizTpBridgeManager.getById(bridgeHealth.getTrBridgeId());
            if(null == bridge){
                return new CommonResult<Map>(false, "未找到相关桥梁传输信息", null);
            }
            //修改桥梁健康状态
//            bridge.setState(bridgeHealth.getHealthAssessmentLevel());
//            bizTpBridgeManager.update(bridge);

            bridgeHealth.setTpBridgeId(bridge.getBridgeId());
            bridgeHealth.setTpBridgeCode(bridge.getBridgeCode());

            bridgeHealth.setCompanyIds(bridge.getCompanyIds());
            bridgeHealth.setCompanyId(bridge.getCompanyId());
            bridgeHealth.setCompanyName(bridge.getCompanyName());
            bridgeHealth.setRoadSegmentId(bridge.getRoadSegmentId());
            bridgeHealth.setRoadSegmentName(bridge.getRoadSegmentName());

            if(null == bridgeHealth.getIsDele()){
                bridgeHealth.setIsDele("0");
            }
        }

        boolean result = bizTpBridgeHealthManager.saveBatch(bridgeHealths);

        if(!result) {
            return new CommonResult<Map>(false, "保存失败", null);
        }
        return new CommonResult<>(true, "操作成功");
    }


    @PostMapping("/transmission/save/events")
    @ApiOperation("桥梁相关预警事件传输")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Map> saveWarnEvents(@ApiParam(name="bizTpWarningEvents", value="桥梁相关预警事件") @RequestBody List<BizTpWarningEvents> bizTpWarningEventss,HttpServletRequest request) {
        String token = request.getHeader("Authorization");

        if( !checkToken(token)){
            return new CommonResult<Map>(false, "请重新获取token", null);
        }
        token = token.replaceAll("Bearer ", "");

        String tokenAccessKey = jwtCheckUtils.getTokenAccessKey(token);


        for (BizTpWarningEvents bizTpWarningEvents : bizTpWarningEventss) {
            String id = bizTpWarningEvents.getId();


            if(null == id || id.isEmpty()){
                return new CommonResult<Map>(false, "预警事件ID不能为空", null);
            }

            bizTpWarningEvents.setId(tokenAccessKey+bizTpWarningEvents.getId());



            Integer eventsState = bizTpWarningEvents.getEventsState();
            if(null == eventsState){
                return new CommonResult<Map>(false, "事件处置状态不能为空", null);
            }

            if(null == bizTpWarningEvents.getIsDele()){
                bizTpWarningEvents.setIsDele("0");
            }

            BizTpWarningEvents tpWarningEvents = bizTpWarningEventsManager.getById(bizTpWarningEvents.getId());

            //修改状态
            if(null != tpWarningEvents){

                if( eventsState == 1 &&  null == bizTpWarningEvents.getDealDate()){
                    return new CommonResult<Map>(false, "事件处置时间不能为空", null);
                }

                tpWarningEvents.setEventsState(eventsState);
                tpWarningEvents.setDealDate(bizTpWarningEvents.getDealDate());
                bizTpWarningEventsManager.update(tpWarningEvents);
            }else {
                String deviceId = bizTpWarningEvents.getDeviceId();

                if(null == deviceId || deviceId.isEmpty()){
                    return new CommonResult<Map>(false, "设备ID不能为空", null);
                }
                bizTpWarningEvents.setDeviceId(tokenAccessKey+deviceId);
                bizTpWarningEvents.setTrBridgeId(tokenAccessKey+bizTpWarningEvents.getTrBridgeId());

                BizTpDevice device = bizTpDeviceManager.getById(bizTpWarningEvents.getDeviceId());

                if(null == device){
                    return new CommonResult<Map>(false, "未找到相关关联设备", null);
                }

                bizTpWarningEvents.setTpBridgeName(device.getTpBridgeName());
                bizTpWarningEvents.setTpBridgeId(device.getTpBridgeId());
                bizTpWarningEvents.setTrBridgeId(device.getTrBridgeId());

                bizTpWarningEvents.setCompanyIds(device.getCompanyIds());
                bizTpWarningEvents.setCompanyId(device.getCompanyId());
                bizTpWarningEvents.setCompanyName(device.getCompanyName());
                bizTpWarningEvents.setRoadSegmentId(device.getRoadSegmentId());
                bizTpWarningEvents.setRoadSegmentName(device.getRoadSegmentName());
                boolean result = bizTpWarningEventsManager.saveOrUpdate(bizTpWarningEvents);
            }
        }


        return new CommonResult<>(true, "操作成功");
    }




    /**
     * 传输系统获取token
     * @param auth []系统编码
     * @param auth 秘钥，系统编码+盐 MD5加密
     * @return
     */
    @RequestMapping(value = "/transmission/getTransToken", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "传输系统获取token", httpMethod = "POST")
    public CommonResult<String> getTransToken(@RequestBody Auth auth) {
        if(auth == null ){
            return new CommonResult<>(false, "参数不能为空！");
        }
        String accessKey = auth.getAccessKey();
        String secret = auth.getSecret();
        if(StringUtils.isBlank(accessKey)){
            return new CommonResult<>(false, "系统编码不能为空！");
        }
        if(StringUtils.isBlank(secret)){
            return new CommonResult<>(false, "秘钥不能为空！");
        }
        // 判断秘钥是否正确,系统编码+盐 MD5
        String str = accessKey + SALT;
        try {
            String curKey = EncryptUtil.md5Hex(str);
            if(!curKey.equalsIgnoreCase(secret)){
                return new CommonResult<>(false, "认证失败，非法的秘钥！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new CommonResult<>(false, "系统加解密错误！");
        }
        boolean result = accessTransKeyList.stream().anyMatch(s -> s.equals(accessKey));
        if (result) {
            final Date createdDate = clock.now();
            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
            stringObjectHashMap.put("accessKey", accessKey);

            Date date = DateUtils.addHours(createdDate,2);


            String token = Jwts.builder()
                    .setClaims(stringObjectHashMap)
                    .setSubject(accessKey)
                    .setIssuedAt(createdDate)
                    .setExpiration(date)
                    .signWith(SignatureAlgorithm.HS512, jwtConfig.getSecret())
                    .compact();

            //是否需要全量同步
            SynchronizationSignVo signVo = new SynchronizationSignVo();

            QueryWrapper<BizTpBridge> wrapperBridge = new QueryWrapper<>();
            wrapperBridge.like("ID_",accessKey);
            int count1 = bizTpBridgeManager.count(wrapperBridge);
            if(count1 == 0){
                signVo.setNeedBridge(1);
            }


            QueryWrapper<BizTpDevice> wrapperDevice = new QueryWrapper<>();
            wrapperDevice.like("ID_",accessKey);
            int count2 = bizTpDeviceManager.count(wrapperDevice);
            if(count2 == 0){
                signVo.setNeedDevice(1);
            }


            QueryWrapper<BizTpBridgeHealth> wrapperHealth = new QueryWrapper<>();
            wrapperHealth.like("TR_BRIDGE_ID_",accessKey);
            int count3 = bizTpBridgeHealthManager.count(wrapperHealth);
            if(count3 == 0){
                signVo.setNeedAssessment(1);
            }

            QueryWrapper<BizTpWarningEvents> wrapperWarn = new QueryWrapper<>();
            wrapperWarn.like("ID_",accessKey);
            int count4 = bizTpWarningEventsManager.count(wrapperWarn);
            if(count4 == 0){
                signVo.setNeedWarningEvents(1);
            }


            signVo.setToken(token);

            return new CommonResult(true, "获取token成功", signVo);


        } else {
            return new CommonResult<>(false, "未授权的第三方，请联系管理员");
        }
    }


    //验证token是否正确
    private boolean checkToken(String token) {
        if(null == token || token.isEmpty()){
            return false;
        }
        token = token.replaceAll("Bearer ", "");

        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(jwtConfig.getSecret())
                    .parseClaimsJws(token)
                    .getBody();
            Object accessKey = claims.get("accessKey");
            Date expiration = claims.getExpiration();
            Date date = new Date();
            if(date.after(expiration)){
                return false;
            }


            return accessTransKeyList.stream().anyMatch(s -> s.equals(accessKey));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

}
