package com.ruoyi.predict.controller;

import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.predict.domain.EnumMenuItem;
import com.ruoyi.predict.domain.WfFileConfig;
import com.ruoyi.predict.service.IEnumMenuItemService;
import com.ruoyi.predict.service.IWfFileConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * @author hlf
 * @date 2022/10/25 10:44
 * 文件说明：数值天气预报管理
 */
@Api(value = "数值天气预报管理Controller", tags = {"数值天气预报管理操作接口"})
@Controller
@RequestMapping("/predict/api/nwmc")
public class NumericalWeatherManagementController extends BaseController {

    @Autowired
    private IWfFileConfigService wfFileConfigService;

    @Autowired
    private IEnumMenuItemService enumMenuItemService;

    @ApiOperation("获取数值天气预报信息列表")
    @PostMapping("/getWfFileConfigList")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "windplantName或pvPowerStationName(筛选传值windplantNo)", value = "所属场站"),
            @ApiImplicitParam(name = "nwpFlagName", value = "短期模型"),
            @ApiImplicitParam(name = "uspNwpNoName", value = "超短期模型"),
    })
    public TableDataInfo getWfFileConfigList(WfFileConfig wfFileConfig) {
        startPage();
        List<WfFileConfig> list = wfFileConfigService.selectWfFileConfigList(wfFileConfig);
        for (WfFileConfig obj : list) {
            long nwpFlagLong = convertDecimalToBinary(Convert.toInt(obj.getNwpFlag()));
            String nwpFlagStr = new StringBuilder(Convert.toStr(nwpFlagLong)).reverse().toString();
            StringBuilder nwpFlag = new StringBuilder();
            StringBuilder nwpFlagInt = new StringBuilder();
            for (int i = 0; i < nwpFlagStr.length(); i++) {
                if (nwpFlagStr.charAt(i) == '1'){
                    EnumMenuItem enumMenuItem = enumMenuItemService.selectEnumMenuItemByMenuNo((long) 119, (long) i);
                    if (ObjectUtil.isNotNull(enumMenuItem)) {
                        nwpFlag.append(enumMenuItem.getItemName()).append(",");
                        nwpFlagInt.append(i).append(",");
                    }
                }
            }
            if (nwpFlag.length() > 0){
                obj.setNwpFlagName(nwpFlag.substring(0, nwpFlag.length() - 1));
            }
            if (nwpFlagInt.length() > 0){
                obj.setNwpFlagInt(nwpFlagInt.substring(0, nwpFlagInt.length() - 1));
            }
        }
        return getDataTable(list);
    }

    @ApiOperation("添加数值天气预报信息")
    @PostMapping("/addWfFileConfig")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "windplantNo", value = "场站编号", required = true),
            @ApiImplicitParam(name = "nwpFlagName", value = "短期模型", required = true),
            @ApiImplicitParam(name = "uspNwpNo", value = "超短期模型", required = true),
    })
    public AjaxResult addWfFileConfig(WfFileConfig wfFileConfig) {
        if (UserConstants.USER_NAME_NOT_UNIQUE.equals(wfFileConfigService.checkWindplantNoUnique(wfFileConfig.getWindplantNo()))) {
            return error("添加数值天气预报信息失败，数值天气预报信息已存在");
        }
        String[] nwpFlagStr = wfFileConfig.getNwpFlagName().split(",");
        StringBuilder stringBuilder = new StringBuilder("00000000000000000000000000000000");
        for (String str : nwpFlagStr){
            stringBuilder.replace(Convert.toInt(str), Convert.toInt(str) + 1, "1");
        }
        wfFileConfig.setNwpFlag((long) convertBinaryToDecimal(Convert.toLong(stringBuilder.reverse())));
        wfFileConfigService.insertWfFileConfig(wfFileConfig);
        return AjaxResult.success();
    }

    @ApiOperation("修改数值天气预报信息")
    @PostMapping("/updateWfFileConfig")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "windplantNo", value = "场站编号", required = true),
            @ApiImplicitParam(name = "nwpFlagName", value = "短期模型"),
            @ApiImplicitParam(name = "uspNwpNo", value = "超短期模型"),
    })
    public AjaxResult updateWfFileConfig(WfFileConfig wfFileConfig) {
        if (UserConstants.USER_NAME_UNIQUE.equals(wfFileConfigService.checkWindplantNoUnique(wfFileConfig.getWindplantNo()))) {
            return error("修改数值天气预报信息失败，数据不存在");
        }
        String[] nwpFlagStr = wfFileConfig.getNwpFlagName().split(",");
        StringBuilder stringBuilder = new StringBuilder("00000000000000000000000000000000");
        for (String str : nwpFlagStr){
            stringBuilder.replace(Convert.toInt(str), Convert.toInt(str) + 1, "1");
        }
        wfFileConfig.setNwpFlag((long) convertBinaryToDecimal(Convert.toLong(stringBuilder.reverse())));
        wfFileConfigService.updateWfFileConfig(wfFileConfig);
        return AjaxResult.success();
    }

    @ApiOperation("删除数值天气预报信息")
    @PostMapping("/deleteWfFileConfig")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "terminalNumber", value = "场站编号", required = true),
    })
    public AjaxResult deleteWfFileConfig(@RequestParam(value = "terminalNumber") String terminalNumber) {
        wfFileConfigService.deleteWfFileConfigById(Convert.toLong(terminalNumber));
        return AjaxResult.success();
    }

    //二进制数转十进制数
    public static int convertBinaryToDecimal(long num)
    {
        int decimalNumber = 0, i = 0;
        long remainder;
        while (num != 0)
        {
            remainder = num % 10;
            num /= 10;
            decimalNumber += remainder * Math.pow(2, i);
            ++i;
        }
        return decimalNumber;
    }

    //十进制数转二进制数
    public static long convertDecimalToBinary(int n)
    {
        long binaryNumber = 0;
        int remainder, i = 1, step = 1;

        while (n!=0)
        {
            remainder = n % 2;
            //System.out.printf("Step %d: %d/2, 余数 = %d, 商 = %d\n", step++, n, remainder, n/2);
            n /= 2;
            binaryNumber += remainder * i;
            i *= 10;
        }
        return binaryNumber;
    }
}
