package com.dcsoft.system.uniubi.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dcsoft.common.core.constant.CacheConstants;
import com.dcsoft.common.core.constant.SecurityConstants;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.common.core.utils.JwtUtils;
import com.dcsoft.common.core.utils.StringUtils;
import com.dcsoft.common.core.utils.uuid.IdUtils;
import com.dcsoft.common.core.web.domain.AjaxResult;
import com.dcsoft.common.redis.service.RedisService;
import com.dcsoft.system.api.RemoteFileService;
import com.dcsoft.system.api.domain.SysFile;
import com.dcsoft.system.api.domain.SysUser;
import com.dcsoft.system.domain.*;
import com.dcsoft.system.service.*;
import com.dcsoft.system.uniubi.domain.EventResult;
import com.dcsoft.system.uniubi.service.ISysApiService;
import com.dcsoft.system.uniubi.service.ISysSdkService;
import com.dcsoft.system.utils.HttpUtil;
import com.dcsoft.system.utils.PictureUtils;
import com.dcsoft.system.utils.WeChatUtil;
import com.dcsoft.system.visitor.domain.Visitor;
import com.dcsoft.system.visitor.service.IVisVisitorExamineService;
import com.dcsoft.system.visitor.service.IVisVisitorRegisterService;
import com.dcsoft.system.visitor.service.IVisitorService;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

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

import static com.dcsoft.common.core.web.domain.AjaxResult.error;
import static com.dcsoft.common.core.web.domain.AjaxResult.success;


/**
 * 用户管理 业务处理
 *
 * @author xueyi
 */
@Slf4j
@RestController
@RequestMapping("/api")
public class SysApiController {

    @Autowired
    protected ISysApiService apiService;

    @Autowired
    protected ISysEquipmentService equipmentService;

    @Autowired
    protected ISysPeopleService peopleService;

    @Autowired
    protected ISysPeopleRecordService peopleRecordService;


    @Autowired
    protected IVisitorService visitorService;


    @Autowired
    private ISysUserService userService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private ISysBranchService sysBranchService;

    @Value("${weixin.appid}")
    public String appid;
    @Value("${weixin.appSecret}")
    public String appSecret;

    @Autowired
    protected ISysSdkService sdkService;

    @Resource
    private IVisVisitorRegisterService registerService;

    private final static long expireTime = CacheConstants.EXPIRATION;



    @Autowired
    private RemoteFileService remoteFileService;

    @Autowired
    private ISysBranchService branchService;

    @Autowired
    private ISysRuleService sysRuleService;

    @Autowired
    private IVisVisitorExamineService visVisitorExamineService;


    /**
     * 获取用户信息A
     *
     * @return 用户信息
     */
    @PostMapping("/backUrl")
    public AjaxResult backUrl(EventResult event) {
        System.out.println("======回调信息============="+event);
        if("100002".equals(event.getEventCode())){//设备上线
            String data=event.getEventMsg();
            JSONObject json= JSONObject.parseObject(data);
            String deviceNo=json.get("deviceNo").toString();
            SysEquipment eqs=equipmentService.selectEquipmentBySequence(deviceNo);
            if(eqs!=null){
                eqs.setFlag("0");
                equipmentService.updateSysEquipment(eqs);
            }
        } else if ("100003".equals(event.getEventCode())) {//设备下线
            String data=event.getEventMsg();
            JSONObject json= JSONObject.parseObject(data);
            String deviceNo=json.get("deviceNo").toString();
            SysEquipment eqs=equipmentService.selectEquipmentBySequence(deviceNo);
            if(eqs!=null){
                SysEquipment equipment=eqs;
                equipment.setFlag("1");
                equipmentService.updateSysEquipment(equipment);
            }
        } else if ("101004".equals(event.getEventCode())) {//识别记录上报
            String data=event.getEventMsg();
            SysPeopleRecord peopleRecord = JSON.parseObject(data,SysPeopleRecord.class);
            SysEquipment eqs=equipmentService.selectEquipmentBySequence(peopleRecord.getDeviceNo());
            peopleRecord.setEquipmentId(eqs.getId());

            SysPeople pq=new SysPeople();
            pq.setGuid(peopleRecord.getAdmitGuid());
            SysPeople pqs=peopleService.selectByGuid(pq);
            if(pqs!=null){
//                peopleRecord.setPeopleId(pqs.getId()+"");
//                peopleRecord.setFlag("0");
//                //判断识别人员是否在考勤组中，是在考勤组中将识别信息塞入到考勤记录中
//                KqGroupUser kqGroupUser=new KqGroupUser();
//                kqGroupUser.setUserId(pqs.getId());
//                List<KqGroupUser> list=groupUserService.selectKqGroupUserList(kqGroupUser);
//                if(list.size()>0){//考勤记录
//                    peopleRecord.setGroupId(list.get(0).getGroupId());
//                    //依据考勤记录将信息放入到考勤结果表中
//                    sdkService.insertKqxx(peopleRecord);
//                }
            }else{
                Visitor vis= visitorService.selectByGuid(peopleRecord.getAdmitGuid());
                if(vis!=null){
                    peopleRecord.setPeopleId(vis.getId());
                }
                peopleRecord.setFlag("1");
            }
            if(peopleRecord.getShowTime()!=null){
                Date date=new Date(peopleRecord.getShowTime());
                peopleRecord.setShowDate(date);
            }
            peopleRecordService.insertSysPeopleRecord(peopleRecord);


        }else{

        }


        return success(event);
    }


    @GetMapping(value = "/peopleEwm")
    public AjaxResult getInfo(@RequestParam("id") Long id,@RequestParam("time") Long timeLong)
    {

        SysPeople people =peopleService.selectSysPeopleById(id);

        return success(people);
    }

    @GetMapping(value = "/visEwm")
    public AjaxResult visEwm(@RequestParam("id") Long id,@RequestParam("time") Long timeLong)
    {

        Visitor visitor =visitorService.selectVisitorById(id);

        return success(visitor);
    }

    //根据code获取openid
    @GetMapping(value = "/getOpenIdUser")
    public AjaxResult getInfo(@RequestParam("code") String code)
    {
       //防止统一code重复提交
        String verifyKey = CacheConstants.WX_KEY + code;
        String openid = redisService.getCacheObject(verifyKey);
        SysUser sysUser=new SysUser();
        System.out.println("获取openid==============================" + openid);
        if(StringUtils.isEmpty(openid)) {//重新获取openid
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?&appid=" + appid + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code";
            String response = HttpUtil.getData(url);
            JSONObject json = JSONObject.parseObject(response);
            System.out.println("微信获取openid==============================" + json);
            sysUser = userService.selectUserByOpenId(json.get("openid").toString());
            redisService.setCacheObject(verifyKey,json.get("openid").toString());
            redisService.expire(verifyKey,60*60);
            if (StringUtils.isNull(sysUser)) {
                sysUser=new SysUser();
                sysUser.setOpenid(json.get("openid").toString());
                return success(sysUser);
            }
        }else{
            sysUser= userService.selectUserByOpenId(openid);
            if (StringUtils.isNull(sysUser)) {
                sysUser=new SysUser();
                sysUser.setOpenid(openid);
                return success(sysUser);
            }
        }
        return success(sysUser);
    }

    @RequestMapping(value = "app",method = RequestMethod.POST)
    @ApiOperation("获取openid")
    public JSONObject app(@RequestBody JSONObject json){
        String phone=json.get("phone")+"";
        String name=json.get("name")+"";
        String openid=json.get("openid")+"";
        log.info("openid:" + openid);
        JSONObject result=new JSONObject();
        SysPeople people = peopleService.selectSysPeopleByOpenId(openid);
        if(people!=null){//已绑定人员
            result.put("code",200);
            result.put("data",people);
        }else{//未绑定人员
            SysPeople peoples =peopleService.selectSysPeopleByGh(phone,name);
            log.info("人员信信息:" + peoples);
            if(peoples!=null){//已绑定人员
                result.put("data",peoples);
                result.put("code",200);
                peoples.setOpenid(openid);
                peopleService.updateSysPeople(peoples);
            }else{
                result.put("code",200);
            }
        }
        return result;
    }

    //根据code获取openid
    @GetMapping(value = "/getWxUser")
    public JSONObject getWxUser(@RequestParam("code") String code)
    {
        JSONObject result=new JSONObject();
        //防止统一code重复提交
        String verifyKey = CacheConstants.WX_KEY + code;
        String openid = redisService.getCacheObject(verifyKey);
        //String openid ="oQvJy6PpmGoEw9TthhcuB1Nnb39E";
        SysPeople people=new SysPeople();
        System.out.println("获取openid==============================" + openid);
        if("null".equals(openid) || StringUtils.isEmpty(openid)) {//重新获取openid
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?&appid=" + appid + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code";
            String response = HttpUtil.getData(url);
            JSONObject json = JSONObject.parseObject(response);
            System.out.println("微信获取openid==============================" + json);
            people = peopleService.selectSysPeopleByOpenId(json.get("openid").toString());
            redisService.setCacheObject(verifyKey,json.get("openid").toString());
            redisService.expire(verifyKey,60*60);
            if (people==null) {
                people=new SysPeople();
                people.setOpenid(json.get("openid").toString());
            }
            result.put("code",200);
            result.put("data",people);
            return result;
        }else{
            people= peopleService.selectSysPeopleByOpenId(openid);
            if (people==null) {
                people=new SysPeople();
                people.setOpenid(openid);
            }
            result.put("code",200);
            result.put("data",people);
            return result;
        }
    }

    /**
     * getSign,初始化config信息
     * @return
     */
    @RequestMapping("/getSign")
    @ResponseBody
    public AjaxResult getSign(HttpServletRequest request, String url) throws Exception {
        String jsapi_ticket  = WeChatUtil.getJsapiTicket(WeChatUtil.getAccessToken());
        Map<String, String> ret = WeChatUtil.sign(jsapi_ticket, url);
        System.out.println("======getSign============="+ret);
        return AjaxResult.success("请求成功",ret);
    }

    /**
     * 获取大华防护数据
     *
     * @return 用户信息
     */
    @PostMapping("/dHInfo")
    public AjaxResult dHInfo(EventResult event) {
        System.out.println("======大华回调信息============="+event);


        return success(event);
    }

    @PostMapping("/getPeople")
    public Map<String, Object> getPeople(@RequestBody SysPeople sysPeople)
    {
        Map<String, Object> rspMap = new HashMap<String, Object>();
        // 更具openid判断是否绑定人员，没有绑定注册人员
        if(StringUtils.isNotEmpty(sysPeople.getOpenid())) {
            SysPeople people = peopleService.queryPeopleByOpenid(sysPeople.getOpenid());
            if(people != null) {
                sysPeople.setName(people.getName());
                sysPeople.setPhone(people.getPhone());
            }
            String i = registerService.queryVisitorRegister(sysPeople);
            if(StringUtils.isEmpty(i)) {
                sysPeople.setVisitorRegisterId(UUID.randomUUID().toString().replace("-", ""));
                registerService.saveVisitorRegister(sysPeople);
                faceStudents(sysPeople, rspMap);
                return rspMap;
            }
            sysPeople.setVisitorRegisterId(i);
            registerService.updateVisitorRegisterByOpenid(sysPeople);
            faceStudents(sysPeople, rspMap);
            return rspMap;
        }
        SysPeople faceStudents = peopleService.selectSysPeopleByPhoneUser(sysPeople);
        faceStudents(faceStudents, rspMap);
        return  rspMap;
    }


    private void faceStudents(SysPeople sysPeople, Map<String, Object> rspMap) {
        if(sysPeople!=null){
            String token = IdUtils.fastUUID();
            // Jwt存储信息
            Map<String, Object> claimsMap = new HashMap<String, Object>();
            claimsMap.put(SecurityConstants.USER_KEY, token);
            claimsMap.put(SecurityConstants.DETAILS_USER_ID, sysPeople.getId() != null ? sysPeople.getId() : sysPeople.getVisitorRegisterId());
            claimsMap.put(SecurityConstants.DETAILS_USERNAME, sysPeople.getName());
            // 接口返回信息
            String access_token= JwtUtils.createToken(claimsMap);
            rspMap.put("access_token", access_token);
            rspMap.put("expires_in", expireTime);
            rspMap.put("sysPeople",sysPeople);
            Claims claims = JwtUtils.parseToken(access_token);
            String userKey = JwtUtils.getUserKey(claims);
            // 根据uuid将loginUser缓存
            redisService.setCacheObject(getTokenKey(userKey), sysPeople, expireTime, TimeUnit.MINUTES);
            log.info("用户登录信息：" + sysPeople);
            peopleService.updatePeopleInfo(sysPeople);
        }
    }

    /**
     * 根据openid获取用户信息
     * @param openid
     * @return
     */
    @PostMapping("/queryPeopleByOpenid")
    public AjaxResult queryPeopleByOpenid(String openid) {
        SysPeople people = peopleService.queryPeopleByOpenid(openid);
        return AjaxResult.success(people);
    }



    private String getTokenKey(String token)
    {
        return CacheConstants.LOGIN_TOKEN_KEY + token;
    }

    @PostMapping("/uploadMinioCar")
    public R<SysFile> uploadMinioCar(@RequestBody JSONObject data) {
        String url=data.get("url")+"";
        if(StringUtils.isEmpty(url)){
            return R.fail("图片地址不能为空");
        }
        MultipartFile files= PictureUtils.base64ToMultipartFiles(url);
        R<SysFile>  file=remoteFileService.uploadMinioCar(files);
        return file;
    }


    /**
     * 获取大华防护数据
     *
     * @return 用户信息
     */
    @PostMapping("/allDeptUrl")
    public AjaxResult allDeptUrl(@RequestBody JSONObject event) {
        System.out.println("======全部部门回调信息============="+event);


        return success(event);
    }

    @PostMapping("/addDeptUrl")
    public AjaxResult addDeptUrl(@RequestBody JSONObject event) {
        if("update".equals(event.get("flag"))){
            String studentJson = JSON.toJSONString(event.get("sysBranch"));
            SysBranch sysBranch = JSON.parseObject(studentJson,SysBranch.class);
            SysBranch SysBranchs= branchService.selectSysBranchById(sysBranch.getId());
            if(SysBranchs!=null){
                sysBranch.setId(SysBranchs.getId());
                branchService.updateSysBranchs(sysBranch);
            }
        }
        if("add".equals(event.get("flag"))){
            String studentJson = JSON.toJSONString(event.get("sysBranch"));
            SysBranch sysBranch = JSON.parseObject(studentJson,SysBranch.class);
            branchService.insertSysBranchs(sysBranch);
        }
        if("delete".equals(event.get("flag"))){
            String studentJson = JSON.toJSONString(event.get("sysBranch"));
            SysBranch sysBranch = JSON.parseObject(studentJson,SysBranch.class);
            branchService.deleteSysBranchByBranchId(sysBranch.getId());
        }

        return success(event);
    }

    @PostMapping("/allPeopleUrl")
    public AjaxResult allPeopleUrl(@RequestBody JSONObject event) {
        System.out.println("======全部人员回调信息============="+event);


        return success(event);
    }

    @PostMapping("/addPeopleUrl")
    public AjaxResult addPeopleUrl(@RequestBody JSONObject event) {
        if("update".equals(event.get("flag"))){
            String studentJson = JSON.toJSONString(event.get("sysPeople"));
            SysPeople sysPeople = JSON.parseObject(studentJson,SysPeople.class);
            SysPeople sysPeoples= peopleService.selectByGuid(sysPeople);
            if(sysPeoples!=null){
                sysPeople.setId(sysPeoples.getId());
                peopleService.updateSysPeoples(sysPeople);
            }else{
                peopleService.insertSysPeoples(sysPeople);
            }
            //下发设备
            if(sysPeople.getBranchId()!=null){
                SysBranch branch=sysBranchService.selectSysBranchById(sysPeople.getBranchId());
                if (branch.getRuleId()!= null) {
                    //添加人员授权信息
                    SysRule rule=sysRuleService.selectSysRuleById(branch.getRuleId());
                    String data=sdkService.authDeviceNew(rule,sysPeople);
                    sysPeople.setDown(1L);
                    if("".equals(data)){
                        return error("该规则未绑定设备!");
                    }
                }
                peopleService.updateSysPeoples(sysPeople);
            }

        }
        if("add".equals(event.get("flag"))){
            String studentJson = JSON.toJSONString(event.get("sysPeople"));
            SysPeople sysPeople = JSON.parseObject(studentJson,SysPeople.class);
            peopleService.insertSysPeoples(sysPeople);
            //下发设备
            if(sysPeople.getBranchId()!=null){
                SysBranch branch=sysBranchService.selectSysBranchById(sysPeople.getBranchId());
                if (branch.getRuleId()!= null) {
                    //添加人员授权信息
                    SysRule rule=sysRuleService.selectSysRuleById(branch.getRuleId());
                    String data=sdkService.authDeviceNew(rule,sysPeople);
                    sysPeople.setDown(1L);
                    if("".equals(data)){
                        return error("该规则未绑定设备!");
                    }
                }
                peopleService.updateSysPeoples(sysPeople);
            }
        }
        if("delete".equals(event.get("flag"))){
            String studentJson = JSON.toJSONString(event.get("sysPeople"));
            SysPeople sysPeople = JSON.parseObject(studentJson,SysPeople.class);
            peopleService.deleteSysPeopleByGuid(sysPeople.getGuid());
        }
        return success(event);
    }

    /*private AjaxResult sendWeixinJspay(String tradeId, int amounts,String openid) throws Exception {
        WeixinPayConfig wxPayConfig = new WeixinPayConfig();// 支付宝配置

        Map<String,String> params = new HashMap<>();
        params.put("appid",wxPayConfig.getAppid());
        params.put("mch_id",wxPayConfig.getMerchantId());
        params.put("description","测试消费");
        params.put("out_trade_no",tradeId);
        params.put("notify_url",wxPayConfig.getNotify_url());
        Map<String,Object> amount = new HashMap<>();
        amount.put("total",amounts); //订单总金额，单位为分。
        amount.put("currency","CNY");
        params.put("amount",amount.toString());
        params.put("nonce_str", generateNonceStr());
        Map<String,Object> payer = new HashMap<>();
        payer.put("openid",openid);
        params.put("payer",payer.toString());
        //创建Httpclient对象
        HttpClient client = new HttpClient(wxPayConfig.getJspayUrl());
        //支持https协议sorry
        client.setHttps(true);
        //设置请求的参数
        String xml= WXPayUtil.mapToXml(params);
        client.setXmlParam(xml);
        //发送post请求
        client.post();
        //获取请求的响应结果
        String content = client.getContent();
        Map<String, String> map = WXPayUtil.xmlToMap(content);
        if (map.get("result_code").equals("SUCCESS")){//扣款成功
            System.out.println("调用成功");
        }else{
            System.out.println("调用失败");
        }
        // 构造支付参数
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000); // 时间戳
        String nonceStr = WXPayUtil.generateNonceStr(); // 随机字符串
        String packageStr = map.get("prepay_id"); // 预支付订单ID
        String signType = "MD5"; // 签名类型
        //构造签名串
        Map<String,String> param = new HashMap<>();
        param.put("appId",wxPayConfig.getAppid());
        param.put("timeStamp",timestamp);
        param.put("nonceStr",nonceStr);
        param.put("packageStr",packageStr);
        String sign =WXPayUtil.generateSignature(param, wxPayConfig.getApiV3Key());

        Map<String, String> payParams = new HashMap<>();
        payParams.put("appId", wxPayConfig.getAppid());
        payParams.put("timeStamp", timestamp);
        payParams.put("nonceStr", nonceStr);
        payParams.put("package", packageStr);
        payParams.put("signType", signType);
        payParams.put("paySign", sign);
        return AjaxResult.success("调用成功",payParams);
    }


    private AjaxResult sendZfb(String tradeId, Double amounts) throws AlipayApiException {
        AlipayConfig alipayConfig = new AlipayConfig();// 支付宝配置
        String appid=alipayConfig.getAppid();
        String private_key=alipayConfig.getRsa_private_key();
        String public_key=alipayConfig.getAlipay_public_key();
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",appid,private_key,"json","GBK",public_key,"RSA2");
        AlipayTradePayRequest request = new AlipayTradePayRequest();
        //异步接收地址，仅支持http/https，公网可访问
        request.setNotifyUrl(alipayConfig.getNotify_url());
        *//******必传参数******//*
        JSONObject bizContent = new JSONObject();
        //商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", tradeId);
        //支付金额，最小值0.01元 单位为元，精确到小数点后两位
        bizContent.put("total_amount",amounts);
        //订单标题，不可使用特殊符号
        bizContent.put("subject", "测试消费");
        //1.条码场景：bar_code；2.刷脸场景：security_code
        bizContent.put("product_code", "QUICK_WAP_WAY");
        request.setBizContent(bizContent.toString());
        AlipayTradePayResponse response = alipayClient.execute(request);
        String pageRedirectionData = response.getBody();
        System.out.println("调用数据"+pageRedirectionData);
        if(response.isSuccess()){
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
       return AjaxResult.success("调用成功",pageRedirectionData);
    }

    @PostMapping("/alipay_callback")
    public AjaxResult alipay_callback(HttpServletRequest request) {
        try{
            Map<String,String> params = new HashMap<String,String>();
            Map requestParams =request.getParameterMap();
            for(Iterator iter = requestParams.keySet().iterator();iter.hasNext();){
                String name =(String)iter.next();
                String[] values =(String[])requestParams.get(name);
                String valuestr ="";
                for(int i =0 ; i<values.length;i++) {
                    valuestr = (i == values.length - 1) ? valuestr + values[i] : valuestr + values[i] + ",";
                }
                    params.put(name,valuestr);
            }
            System.out.println("支付宝回调,sign: {},trade status: },&数:{)"+params.get("sign")+";"+params.get("trade_status")+";"+params.toString());

            try {
                boolean flag = AlipaySignature.rsaCheckV1
                (params, new AlipayConfig().getAlipay_public_key(), "UTF-8", "RSA2");
                if(flag){
                    if("TRADE_SUCCESS".equals(params.get("trade_status"))){
                        String outTradeNo = params.get("out_trade_no");
                        String tradeNo = params.get("trade no");
                        String tradeStatus = params.get("trade_status");

                    }

                }
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            params.remove("sign_type");


        }catch(Exception e){

        }

        return success();
    }*/




    /**
     * 响应返回结果
     *
     * @param rows 影响行数
     * @return 操作结果
     */
    protected AjaxResult toAjax(int rows)
    {
        return rows > 0 ? AjaxResult.success() : error();
    }

}
