package com.imdroid.sideslope.web;

import com.imdroid.secapi.client.HttpResp;
import com.imdroid.sideslope.calc.MultiLineGNSSCalcService;
import com.imdroid.sideslope.calc.SingleLineGNSSCalcService;
import com.imdroid.sideslope.sal.LocalDeviceServiceImpl;
import com.imdroid.sideslope.server.DeviceChannel;
import com.imdroid.sideslope.server.OnlineChannels;
import com.imdroid.common.util.DataTypeUtil;
import com.imdroid.sideslope.service.WarningService;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @author LiGang
 * @date 2023/9/24 10:01
 */
@RestController
public class ApiController {

    private final Logger logger = LoggerFactory.getLogger(ApiController.class);

    @Autowired
    LocalDeviceServiceImpl localDeviceService;

    @Autowired
    WarningService warningService;
    @Autowired
    SingleLineGNSSCalcService calcService;
    @Autowired
    MultiLineGNSSCalcService multiCalcService;

    @PostMapping(value = "/config")
    public HttpResp config(String deviceId, String configuration) {
        Map<String, Object> status = new HashMap<>();
        HttpResp resp = new HttpResp();
        DeviceChannel deviceChannel = OnlineChannels.INSTANCE.getConfigChannel(deviceId);
        if(deviceChannel == null || !deviceChannel.isOnline()) {
            deviceChannel = OnlineChannels.INSTANCE.getDataChannel(deviceId);
        }
        //if(deviceChannel!=null && deviceChannel.isOnline()){
        if(deviceChannel!=null && deviceChannel.isOnline()){
            status.put("status", "Online");
            // send command
            ByteBuf buf = Unpooled.buffer();
            byte[] data = getBinaryData(ConfigDataTypeEnum.HEX, configuration);
            logger.info("send command:{}", configuration);
            buf.writeBytes(data);
            deviceChannel.writeAndFlush(buf);
        }

        if (status.isEmpty()) {
            status.put("status", "Offline");
            resp.setCode(HttpResp.HTTP_RSP_FAILED);
            resp.setResponseMessage("Offline.");
        } else {
            resp.setResponseMessage("Command sent.");
        }
        resp.setResponseObject(status);
        return resp;
    }

    @PostMapping("/device_param_changed")
    public HttpResp deviceParamChanged(String deviceId) {
        // 更新设备缓存
        localDeviceService.refresh(deviceId);

        HttpResp resp = new HttpResp();
        resp.setResponseMessage("succeed");
        return resp;
    }

    @PostMapping("/group_param_changed")
    public HttpResp groupParamChanged(){
        calcService.refreshGroupCalc();
        multiCalcService.refreshGroupCalc();
        HttpResp resp = new HttpResp();
        resp.setResponseMessage("succeed");
        return resp;
    }


    @PostMapping("/warning_param_changed")
    public HttpResp warningParamChanged(){
        warningService.refreshCfg();
        HttpResp resp = new HttpResp();
        resp.setResponseMessage("succeed");
        return resp;
    }

    private static byte[] getBinaryData(ConfigDataTypeEnum dataTypeEnum, String text) {
        if (dataTypeEnum == ConfigDataTypeEnum.HEX) {
            return DataTypeUtil.hexStringToBytes(text);
        } else if (dataTypeEnum == ConfigDataTypeEnum.JSON) {
            String content = URLDecoder.decode(text);
            return content.getBytes(StandardCharsets.UTF_8);
        } else {
            return text.getBytes(StandardCharsets.UTF_8);
        }
    }
}
