package com.xy.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xy.annotation.LogOperate;
import com.xy.device.EnumAlgorithmPayConfig;
import com.xy.device.EnumAlgorithmTypes;
import com.xy.dto.AlgorithmDto;
import com.xy.dto.DeviceAlgorithmChargingDto;
import com.xy.dto.DeviceTypeAlgorithmBeforConfigDto;
import com.xy.dto.be.MercDto;
import com.xy.entity.DeviceTypeAlgorithmBeforConfig;
import com.xy.entity.SysDictRedis;
import com.xy.error.CommRuntimeException;
import com.xy.mapper.DeviceTypeAlgorithmBeforConfigMapper;
import com.xy.service.be.MercService;
import com.xy.utils.Emptys;
import com.xy.utils.MybatisPlusQuery;
import com.xy.utils.R;
import com.xy.utils.SysDictUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.xy.utils.Beans.copy;


/**
 * <p>
 * 设备类型算法预充配置 服务实现类
 * </p>
 *
 * @author lijin
 * @since 2023-07-10
 */
@Service
@AllArgsConstructor
@Api(tags = "设备类型算法预充配置")
public class DeviceTypeAlgorithmBeforConfigServiceImpl extends ServiceImpl<DeviceTypeAlgorithmBeforConfigMapper, DeviceTypeAlgorithmBeforConfig> implements DeviceTypeAlgorithmBeforConfigService {

    private AlgorithmService algorithmService;
    private MercService mercService;
    private DeviceAlgorithmChargingServiceImpl deviceAlgorithmChargingService;

    @Override
    @ApiOperation("对象查询")
    public R<DeviceTypeAlgorithmBeforConfigDto.Vo> obj(@RequestBody DeviceTypeAlgorithmBeforConfigDto.Vo vo) {
        MercDto.Vo merc = R.feignCheckData(mercService.obj(new MercDto.Vo().setId(vo.getMercId())));
        List<String> mercCodes = new ArrayList<>();
        deviceAlgorithmChargingService.getMercCodes(merc.getMercCode(), mercCodes);
        DeviceTypeAlgorithmBeforConfigDto.SelectList selectList = copy(DeviceTypeAlgorithmBeforConfigDto.SelectList.class, vo);
        selectList.setMercCodes(mercCodes);
        List<DeviceTypeAlgorithmBeforConfigDto.Vo> list = list(selectList).getData();
        if (Emptys.check(list)) {
            return R.ok(list.get(0));
        }
        return R.ok();
    }

    @PostMapping("list")
    @ApiOperation("集合查询")
    public R<List<DeviceTypeAlgorithmBeforConfigDto.Vo>> list(@RequestBody DeviceTypeAlgorithmBeforConfigDto.SelectList selectList) {
        List<String> mercCodes = selectList.getMercCodes();
        if (CollUtil.isNotEmpty(mercCodes)) {
            // 优先编码查询
            selectList.setMercId(null);
        }
        LambdaQueryWrapper<DeviceTypeAlgorithmBeforConfig> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(selectList, DeviceTypeAlgorithmBeforConfig.class).build()
                .in(CollUtil.isNotEmpty(mercCodes), DeviceTypeAlgorithmBeforConfig::getMercCode, mercCodes);
        List<DeviceTypeAlgorithmBeforConfig> list = list(lambdaQueryWrapper);
        return R.ok(copy(DeviceTypeAlgorithmBeforConfigDto.Vo.class, list));
    }

    @PostMapping("deviceActiveFeeList")
    @ApiOperation("费用管理-设备激活费用查询")
    public R<DeviceTypeAlgorithmBeforConfigDto.DeviceActiveFeeVO> deviceActiveFeeList(@RequestBody DeviceTypeAlgorithmBeforConfigDto.DeviceActiveFeeDTO dto) {
        DeviceTypeAlgorithmBeforConfigDto.DeviceActiveFeeVO vo = new DeviceTypeAlgorithmBeforConfigDto.DeviceActiveFeeVO();
        Long mercId = dto.getMercId();
        LambdaQueryWrapper<DeviceTypeAlgorithmBeforConfig> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(dto, DeviceTypeAlgorithmBeforConfig.class).build();
        List<DeviceTypeAlgorithmBeforConfig> list = list(lambdaQueryWrapper);
        // 查询默认算法信息
        List<AlgorithmDto.ListNameId> listNameIds = R.feignCheckData(algorithmService.ListNameId());
        List<Long> algorithmIds = listNameIds.stream().map(AlgorithmDto.ListNameId::getId).collect(Collectors.toList());
        Map<Long, String> agMap = listNameIds.stream().collect(Collectors.toMap(AlgorithmDto.ListNameId::getId, AlgorithmDto.ListNameId::getName));
//        Map<Long, String> moonAlgorithmTypesMap = new HashMap<>();
        Map<Long, String> algorithmPayConfigMap = new HashMap<>();
        for (Long algorithmId : algorithmIds) {
            SysDictRedis moonAlgorithmTypes = SysDictUtils.get(EnumAlgorithmTypes.Code.CODE.getCode(), String.valueOf(algorithmId));
            // 算法类型对应的字典配置的默认激活费（无设备类型）
            SysDictRedis algorithmPayConfig = SysDictUtils.get(EnumAlgorithmPayConfig.Code.CODE.getCode(), String.valueOf(algorithmId));
//            if (Emptys.check(moonAlgorithmTypes)) {
//                moonAlgorithmTypesMap.put(algorithmId, moonAlgorithmTypes.getMsg());
//            }
            if (Emptys.check(algorithmPayConfig)) {
                algorithmPayConfigMap.put(algorithmId, algorithmPayConfig.getValue());
            }
        }


        // 字典默认配置
        List<DeviceTypeAlgorithmBeforConfigDto.DeviceActiveDictVO> deviceActiveDicts = new ArrayList<>();

        for (Long algorithmId : algorithmIds) {
            String algorithmName = agMap.get(algorithmId);
            String algorithmPayConfig = algorithmPayConfigMap.get(algorithmId);
            DeviceAlgorithmChargingDto.AlgorithmMoonConfig algorithmMoonConfig = JSONUtil.parseObj(algorithmPayConfig).toBean(DeviceAlgorithmChargingDto.AlgorithmMoonConfig.class);
            DeviceAlgorithmChargingDto.AlgorithmMoonConfig.Inf inf = algorithmMoonConfig.getInf();
            Integer money = inf.getMoney();
            DeviceTypeAlgorithmBeforConfigDto.DeviceActiveDictVO dictVO = new DeviceTypeAlgorithmBeforConfigDto.DeviceActiveDictVO();
            dictVO.setAlgorithmId(algorithmId);
            dictVO.setAlgorithmName(algorithmName);
            dictVO.setMoney(money);
            dictVO.setSize(inf.getSize());
            deviceActiveDicts.add(dictVO);
        }
        // 平台给商家定义的配置
        List<DeviceTypeAlgorithmBeforConfigDto.DeviceActiveMercFeeVO> deviceActiveMercFees = new ArrayList<>();
        if (CollUtil.isNotEmpty(list)) {
            // 平台给商家自定义的设备激活费用，多了个设备类型
            BeanUtil.copyToList(list, DeviceTypeAlgorithmBeforConfigDto.DeviceActiveMercFeeVO.class);
            for (DeviceTypeAlgorithmBeforConfig db : list) {
                DeviceTypeAlgorithmBeforConfigDto.DeviceActiveMercFeeVO dbData = new DeviceTypeAlgorithmBeforConfigDto.DeviceActiveMercFeeVO();
                BeanUtil.copyProperties(db, dbData);
                String algorithmName = agMap.get(db.getAlgorithmId());
                dbData.setAlgorithmName(algorithmName);
                deviceActiveMercFees.add(dbData);
            }
        }
        vo.setDeviceActiveDicts(deviceActiveDicts);
        vo.setDeviceActiveMercFees(deviceActiveMercFees);
        return R.ok(vo);
    }

    @LogOperate
    @PostMapping("save")
    @ApiOperation("添加")
    public R save(@RequestBody @Validated DeviceTypeAlgorithmBeforConfigDto.Save save) {
        Integer deviceType = save.getDeviceType();
        Long algorithmId = save.getAlgorithmId();
        Long mercId = save.getMercId();
        MercDto.Vo merc = R.feignCheckData(mercService.obj(new MercDto.Vo().setId(mercId)));
        String mercCode = merc.getMercCode();
        DeviceTypeAlgorithmBeforConfig dc = this.getOne(Wrappers.<DeviceTypeAlgorithmBeforConfig>lambdaQuery()
                .eq(DeviceTypeAlgorithmBeforConfig::getMercId, mercId)
                .eq(DeviceTypeAlgorithmBeforConfig::getAlgorithmId, algorithmId)
                .eq(DeviceTypeAlgorithmBeforConfig::getDeviceType, deviceType)
        );
        if (dc != null) {
            throw new CommRuntimeException("该类型配置已存在，请勿重复添加！");
        }
        LocalDateTime now = LocalDateTime.now();
        DeviceTypeAlgorithmBeforConfig saveInfo = copy(DeviceTypeAlgorithmBeforConfig.class, save)
                .setCreateTime(now)
                .setUpdateTime(now).setMercCode(mercCode);
        save(saveInfo);
        return R.ok().setLogMsg(String.format("商户id：%s,算法id：%s,预充金额：%s", save.getMercId(), save.getAlgorithmId(), save.getMoney()));
    }

    @LogOperate
    @PostMapping("update")
    @ApiOperation("修改")
    public R update(@RequestBody @Validated DeviceTypeAlgorithmBeforConfigDto.Update update) {
        DeviceTypeAlgorithmBeforConfig deviceTypeAlgorithmBeforConfig = getById(update.getId());
        DeviceTypeAlgorithmBeforConfig updateInfo = copy(DeviceTypeAlgorithmBeforConfig.class, update)
                .setUpdateTime(LocalDateTime.now());
        updateById(updateInfo);
        return R.ok().setLogMsg(String.format("商户id：%s,算法id：%s,原预充金额：%s,新预充金额：%s", deviceTypeAlgorithmBeforConfig.getMercId(), deviceTypeAlgorithmBeforConfig.getAlgorithmId(), deviceTypeAlgorithmBeforConfig.getMoney(), update.getMoney()));
    }

    @LogOperate
    @PostMapping("delete")
    @ApiOperation("删除")
    public R delete(@RequestBody @Validated DeviceTypeAlgorithmBeforConfigDto.Delete delete) {
        removeById(delete.getId());
        return R.ok();
    }
}
