package com.usky.eg.controller.web;

import com.usky.common.core.bean.ApiResult;
import com.usky.common.core.exception.BusinessException;
import com.usky.eg.service.EgDeviceAdbService;
import com.usky.eg.service.EgDeviceRemoteUpgradeMqttService;
import com.usky.eg.service.vo.EgDeviceAdbEndpointVO;
import com.usky.eg.service.vo.EgDeviceAdbRemoteUpgradeBatchResultVO;
import com.usky.eg.service.vo.EgDeviceAdbRemoteUpgradeVO;
import com.usky.eg.service.vo.EgDeviceAdbResultVO;
import com.usky.eg.service.vo.EgDeviceAdbTcpipVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 服务端官方 adb：部署机需安装 Android Platform Tools（adb 在 PATH），且网络可达设备。
 * <p>
 * 网关前缀一般为 /service-eg，完整路径示例：POST /service-eg/egDevice/adb/connect
 */
@RestController
@RequestMapping("/egDevice/adb")
public class EgDeviceAdbController {

    @Autowired
    private EgDeviceAdbService egDeviceAdbService;

    @Autowired
    private EgDeviceRemoteUpgradeMqttService egDeviceRemoteUpgradeMqttService;

    @PostMapping("/connect")
    public ApiResult<EgDeviceAdbResultVO> connect(@RequestBody EgDeviceAdbEndpointVO vo) {
        EgDeviceAdbResultVO r = egDeviceAdbService.connect(vo.getDeviceIp(), vo.getDevicePort());
        return ApiResult.success(r);
    }

    @PostMapping("/disconnect")
    public ApiResult<EgDeviceAdbResultVO> disconnect(@RequestBody EgDeviceAdbEndpointVO vo) {
        EgDeviceAdbResultVO r = egDeviceAdbService.disconnect(vo.getDeviceIp(), vo.getDevicePort());
        return ApiResult.success(r);
    }

    @PostMapping("/tcpip")
    public ApiResult<EgDeviceAdbResultVO> tcpip(@RequestBody EgDeviceAdbTcpipVO vo) {
        EgDeviceAdbResultVO r = egDeviceAdbService.tcpip(vo.getDeviceIp(), vo.getDevicePort(), vo.getPort());
        return ApiResult.success(r);
    }

    /**
     * 远程升级：仅通过 MQTT 向 Broker 发布下行指令，由终端 {@code connectWithDevice} 订阅后在设备侧自行下载安装
     * 单台：{@code fileUrl} 必填；{@code deviceId} 或 {@code deviceCode} 至少其一。
     * 批量：非空 {@code items}，每项含 {@code deviceId} 或 {@code deviceCode}，并与同级 {@code fileUrl}、可选 {@code launchPackage} 共用。
     * 完整路径示例：POST /service-eg/egDevice/adb/remoteUpgrade
     */
    @PostMapping("/remoteUpgrade")
    public ApiResult<?> remoteUpgrade(@RequestBody EgDeviceAdbRemoteUpgradeVO vo) {
        if (vo.getItems() != null && !vo.getItems().isEmpty()) {
            EgDeviceAdbRemoteUpgradeBatchResultVO batch = egDeviceRemoteUpgradeMqttService.publishRemoteUpgradeBatch(
                    vo.getItems(), vo.getFileUrl(), vo.getLaunchPackage());
            return ApiResult.success(batch);
        }
        EgDeviceAdbResultVO r = egDeviceRemoteUpgradeMqttService.publishRemoteUpgrade(vo);
        return ApiResult.success(r);
    }

    /**
     * 原始 PNG 二进制，无 JSON 封装（前端 responseType: blob）。
     * 使用 {@link HttpServletResponse} 写出流，避免全局 ApiResult 包装器把返回值当成 JSON 再强转为 byte[] 导致 ClassCastException。
     */
    @GetMapping(value = "/screenshot", produces = MediaType.IMAGE_PNG_VALUE)
    public void screenshot(@RequestParam("deviceIp") String deviceIp,
                           @RequestParam("devicePort") Integer devicePort,
                           HttpServletResponse response) throws IOException {
        try {
            byte[] png = egDeviceAdbService.screenshot(deviceIp, devicePort);
            response.setStatus(HttpServletResponse.SC_OK);
            response.setContentType(MediaType.IMAGE_PNG_VALUE);
            response.setHeader(HttpHeaders.CACHE_CONTROL, "no-store, no-cache");
            response.setContentLength(png.length);
            response.getOutputStream().write(png);
            response.getOutputStream().flush();
        } catch (BusinessException e) {
            String msg = e.getMessage() != null ? e.getMessage() : "Bad Request";
            byte[] err = msg.getBytes(StandardCharsets.UTF_8);
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.setContentType(MediaType.TEXT_PLAIN_VALUE);
            response.setContentLength(err.length);
            response.getOutputStream().write(err);
            response.getOutputStream().flush();
        }
    }
}
