package com.cmvr.edge.client.service.impl;

import cmvr.api.DexHandServiceGrpc;
import cmvr.api.DexhandCommand;
import com.alibaba.fastjson2.JSON;
import com.cmvr.common.exception.GlobalException;
import com.cmvr.edge.client.manage.GrpcServiceManager;
import com.cmvr.edge.client.service.EdgeDexHandService;
import com.cmvr.edge.client.service.EdgeStreamService;
import com.cmvr.edge.client.utils.EdgeCommonUtil;
import com.cmvr.framework.websocket.service.MessagePushService;
import io.grpc.stub.StreamObserver;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class EdgeDexHandServiceImpl implements EdgeDexHandService, EdgeStreamService {

    private final GrpcServiceManager grpcServiceManager;

    private final MessagePushService messagePushService;

    @Override
    public DexhandCommand.DexHandState getStatus(String terminalId, String deviceId) {
        DexHandServiceGrpc.DexHandServiceBlockingStub stub = grpcServiceManager.getGrpcClient(terminalId, DexHandServiceGrpc.DexHandServiceBlockingStub.class);
        DexhandCommand.GetDexHandStateCommand.Request request = DexhandCommand.GetDexHandStateCommand.Request.newBuilder()
                .setHeader(EdgeCommonUtil.buildRequest(deviceId))
                .build();
        return executeGrpcCall(() -> stub.getStatus(request)).getState();
    }

    @Override
    public void setDexHandPos(String terminalId, String deviceId) {

    }

    @Override
    public void setDexHandAngle(String terminalId, String deviceId, int id, float value) {
        DexHandServiceGrpc.DexHandServiceBlockingStub stub = grpcServiceManager.getGrpcClient(terminalId, DexHandServiceGrpc.DexHandServiceBlockingStub.class);
        DexhandCommand.FreedomValue.Builder builder = DexhandCommand.FreedomValue.newBuilder();
        builder.setId(id);
        builder.setValue(value);
        DexhandCommand.SetDexHandAnglesCommand.Request request = DexhandCommand.SetDexHandAnglesCommand.Request.newBuilder()
                .setHeader(EdgeCommonUtil.buildRequest(deviceId))
                .addValues(builder.build())
                .build();
        executeGrpcCall(() -> stub.setDexHandAngle(request));
    }

    @Override
    public void setDexHandForce(String terminalId, String deviceId) {

    }

    @Override
    public void setDexHandSpeed(String terminalId, String deviceId) {

    }

    @Override
    public void setDexHandPresetAct(String terminalId, String deviceId) {

    }

    @Override
    public String getSensorData(String terminalId, String deviceId) {
        DexHandServiceGrpc.DexHandServiceBlockingStub stub = grpcServiceManager.getGrpcClient(terminalId, DexHandServiceGrpc.DexHandServiceBlockingStub.class);
        DexhandCommand.GetSensorDataCommand.Request request = DexhandCommand.GetSensorDataCommand.Request.newBuilder()
                .setHeader(EdgeCommonUtil.buildRequest(deviceId))
                .build();
        DexhandCommand.GetSensorDataCommand.Feedback feedback = executeGrpcCall(() -> stub.getSensorData(request));
        return JSON.toJSONString(feedback);
    }

    @Override
    public StreamObserver<DexhandCommand.GetSensorDataStreamCommand.Request> getSensorDataStream(String terminalId, String deviceId) {
        DexHandServiceGrpc.DexHandServiceStub stub = grpcServiceManager.getGrpcClient(terminalId, DexHandServiceGrpc.DexHandServiceStub.class);
        StreamObserver<DexhandCommand.GetSensorDataStreamCommand.Feedback> responseObserver = new StreamObserver<DexhandCommand.GetSensorDataStreamCommand.Feedback>() {
            @Override
            public void onNext(DexhandCommand.GetSensorDataStreamCommand.Feedback value) {
                // 例如，将传感器数据转换为JSON字符串
                String playLoad = JSON.toJSONString(value.getSensorList());
                messagePushService.pushToChannel("edgeDexHandServiceImpl/getSensorDataStream/" + terminalId + "/" + deviceId, playLoad);
            }

            @Override
            public void onError(Throwable t) {
                // 处理错误
                System.err.println("Error: " + t.getMessage());
            }

            @Override
            public void onCompleted() {
                // 流结束
                System.out.println("Stream completed.");
            }
        };
        // 创建StreamObserver来发送请求
       StreamObserver<DexhandCommand.GetSensorDataStreamCommand.Request> requestObserver = stub.getSensorDataStream(responseObserver);
        // 构建请求并发送
       DexhandCommand.GetSensorDataStreamCommand.Request request = DexhandCommand.GetSensorDataStreamCommand.Request.newBuilder()
                .setHeader(EdgeCommonUtil.buildRequest(deviceId))
                .build();
       requestObserver.onNext(request);
       return requestObserver;

    }

    @FunctionalInterface
    private interface GrpcCall<T> {
        T call() throws Exception;
    }

    private <T> T executeGrpcCall(EdgeDexHandServiceImpl.GrpcCall<T> call) {
        try {
            return call.call();
        } catch (Exception e) {
            throw new GlobalException("gRPC 调用失败: " + e.getMessage());
        }
    }

}
