package vip.xiaonuo.biz.api.mini.service;

import cn.hutool.core.util.ArrayUtil;
import org.springframework.stereotype.Service;
import vip.xiaonuo.auth.core.enums.SaClientTypeEnum;
import vip.xiaonuo.auth.modular.login.enums.AuthDeviceTypeEnum;
import vip.xiaonuo.auth.modular.login.param.AuthAccountPasswordLoginParam;
import vip.xiaonuo.auth.modular.login.service.AuthService;
import vip.xiaonuo.biz.api.mini.entity.MiNiLoginParam;
import vip.xiaonuo.biz.api.wxapp.entity.WeiXinRes;
import vip.xiaonuo.biz.api.wxapp.service.WxMiniSendService;
import vip.xiaonuo.biz.core.Const.BizStr;
import vip.xiaonuo.biz.modular.depotDevice.entity.DepotDevice;
import vip.xiaonuo.biz.modular.depotDevice.param.DepotDeviceListParam;
import vip.xiaonuo.biz.modular.depotDevice.service.DepotDeviceService;
import vip.xiaonuo.biz.modular.depotTruckWeighDouble.Statistics.StatisticsVo;
import vip.xiaonuo.biz.modular.depotTruckWeighDouble.Statistics.StatisticsCarNumData;
import vip.xiaonuo.biz.modular.depotTruckWeighDouble.Statistics.StatisticsDeviceData;
import vip.xiaonuo.biz.modular.depotTruckWeighDouble.Statistics.StatisticsTotalWeightData;
import vip.xiaonuo.biz.modular.depotTruckWeighDouble.entity.DepotTruckWeighDouble;
import vip.xiaonuo.biz.modular.depotTruckWeighDouble.param.StatisticsParam;
import vip.xiaonuo.biz.modular.depotTruckWeighDouble.service.DepotTruckWeighDoubleService;
import vip.xiaonuo.biz.modular.depotWork.service.DepotWorkService;
import vip.xiaonuo.biz.modular.user.service.UserWxOpenService;
import vip.xiaonuo.common.annotation.CommonLog;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.util.BigDecimalUtil;
import vip.xiaonuo.common.util.CommonCryptogramUtil;
import vip.xiaonuo.common.util.DatesUtil;
import vip.xiaonuo.sys.modular.user.param.SysUserUpdatePwdParam;
import vip.xiaonuo.sys.modular.user.service.SysUserService;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 微信小程序实现类
 *
 * @author xiang
 * @date 2023/09/19 16:23
 **/
@Service
public class MiNiService {

    @Resource
    AuthService authService;
    @Resource
    SysUserService sysUserService;
    @Resource
    DepotTruckWeighDoubleService doubleService;
    @Resource
    DepotWorkService depotWorkService;
    @Resource
    DepotDeviceService deviceService;
    @Resource
    WxMiniSendService wxMiniSendService;
    @Resource
    UserWxOpenService userWxOpenService;

    /**
     * 登陆
     *
     * @author xiang
     * @date 2023/04/19 14:48
     **/
    public Object doLogin(MiNiLoginParam param, String saClientType) {
        String token = null;
        String device = AuthDeviceTypeEnum.MINI.getValue();
        //账号密码
        if (SaClientTypeEnum.B.getValue().equals(saClientType)) {
            if (ArrayUtil.hasEmpty(param.getAccount(), param.getPassword()))
                throw new CommonException("账号和密码不能为空!");
            AuthAccountPasswordLoginParam loginParam = new AuthAccountPasswordLoginParam(param.getAccount(), CommonCryptogramUtil.doSm2Encrypt(param.getPassword()), device);
            token = authService.doLogin(loginParam, SaClientTypeEnum.B.getValue());
        }
        return token;
    }

    /**
     * 修改用户密码
     *
     * @author xiang
     * @date 2023/04/19 14:48
     **/
    public void updatePassword(SysUserUpdatePwdParam param, String saClientType) {
        //账号密码
        if (SaClientTypeEnum.B.getValue().equals(saClientType)) {
            sysUserService.updatePassword(param);
        }
    }

    /**
     * 绑定
     *
     * @author xiang
     * @date 2023/04/19 14:48
     **/
    @CommonLog("小程序绑定系统账号")
    public void binding(WeiXinRes param) {
        Map<String, Object> map = new HashMap<>();
        map.put("js_code", param.getJsCode());
        String res = wxMiniSendService.weiXinSend(map);

        WeiXinRes weiXinRes = new WeiXinRes().weixinResgistRes(res);
        if (!weiXinRes.getErrcode().equals(0)) {
            throw new CommonException("code：{}，msg：{}。", weiXinRes.getErrcode(), weiXinRes.getErrmsg());
        }
        userWxOpenService.save(authService.getLoginUser().getId(), weiXinRes.getUnionid(), weiXinRes.getOpenid());
    }

    /**
     * 过磅和设备统计
     *
     * @author xiang
     * @date 2023/10/08 17:05
     **/
    public Object statistics(StatisticsParam param) {
        //车次、车重、设备
        List<StatisticsCarNumData> carNumData = new ArrayList<>();
        StatisticsTotalWeightData totalWeightData;
        List<StatisticsDeviceData> deviceData = new ArrayList<>();
        //车重_统计
        BigDecimal totalGrossWeight = BigDecimal.ZERO;
        BigDecimal totalTareWeight = BigDecimal.ZERO;
        BigDecimal totalNetWeight = BigDecimal.ZERO;
        //时间范围
        String startDate = DatesUtil.forDateTime(DatesUtil.getStartTime(new Date(), param.getType()));
        String endDate = DatesUtil.forDateTime(DatesUtil.getEndTime(new Date(), param.getType()));
        List<String> dateLst = DatesUtil.dateBetween(startDate, endDate, param.getType() > 3 ? 7 : 10);

        //双磅记录
        List<DepotTruckWeighDouble> recordDoubles = doubleService.lst(new StatisticsParam(param.getDepotId(), startDate, endDate));
        for (String dateOne : dateLst) {
            List<DepotTruckWeighDouble> recordDoubleLstStream = recordDoubles.stream().filter(
                    s -> DatesUtil.forDate(s.getCreateTime()).contains(dateOne)).collect(Collectors.toList());
            carNumData.add(new StatisticsCarNumData(dateOne, recordDoubleLstStream.size()));
        }
        //车重
        for (DepotTruckWeighDouble dbOne : recordDoubles) {
            totalGrossWeight = BigDecimalUtil.addVal(totalGrossWeight, dbOne.getGrossWeight());
            totalTareWeight = BigDecimalUtil.addVal(totalTareWeight, dbOne.getTareWeight());
            totalNetWeight = BigDecimalUtil.addVal(totalNetWeight, dbOne.getNetWeight());
        }
        totalWeightData = new StatisticsTotalWeightData(totalGrossWeight, totalTareWeight, recordDoubles.size(), totalNetWeight);
        //设备状态
        List<DepotDevice> itemDeviceLst = deviceService.lst(new DepotDeviceListParam(param.getDepotId()));
        deviceData.add(new StatisticsDeviceData(BizStr.DEVICE_ON_LINE, itemDeviceLst.stream().filter(i -> BizStr.DEVICE_ON_LINE.equals(i.getOnlineState())).count()));
        deviceData.add(new StatisticsDeviceData(BizStr.DEVICE_OFF_LINE, itemDeviceLst.stream().filter(i -> BizStr.DEVICE_OFF_LINE.equals(i.getOnlineState())).count()));

        return new StatisticsVo(carNumData, totalWeightData, deviceData);
    }

    /**
     * 出入库统计
     *
     * @author xiang
     * @date 2023/10/08 17:05
     **/
    public Object statsDate(StatisticsParam param) {
        return depotWorkService.statsDate(param);
    }

}
