//
//  RTCXLinkAppProtocol.h
//  RTCXAppExpress
//
//  Created by Apple on 2025/11/12.
//

#import <Foundation/Foundation.h>
#import <RTCXAppExpress/RTCXLinkAppModel.h>
NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, RTCXLinkAppStatus) {
    RTCXLinkAppStatusConnected,
    RTCXLinkAppStatusRefused,
    RTCXLinkAppStatusClosed,
    RTCXLinkAppStatusError,
    RTCXLinkAppStatusProtocolError,
    RTCXLinkAppStatusClosedByBroker
};

/**
 连接通道连接状态侦听者
 */
@protocol LRTCXLinkAppConnectListener<NSObject>
/** 通道连接状况改变
 @param connectState 参见枚举 `RTCXLinkAppStatus`
 */
-(void)onLinkAppConnectState:(RTCXLinkAppStatus)connectState;
@end

@protocol RTCXLinkAppDownListener <NSObject>
/**
 下推数据监听
 
 @param data 消息内容。
 @param iotId 设备唯一标识
 @param topic 下推 Topic 的业务部分，由具体业务确定
 */
-(void)onLinkDownData:(NSData *_Nullable)data topic:(NSString * _Nullable)topic iotId:(NSString *)iotId;

@optional
/**
 数据使用 `onLinkDownData:topic:iotId:` 上抛时，可以先过滤一遍，返回 NO，则不上抛；返回 YES，则会使用 `onLinkDownData:topic:iotId:` 上抛
 
 @param iotId 设备唯一标识
 @param topic 下推 Topic 的业务部分，由具体业务确定
 @return 返回 NO，则不上抛；返回 YES，则会使用 `onLinkDownData:topic:iotId:` 上抛
 */
-(BOOL)arrowHandle:(NSString *)iotId topic:(NSString * _Nullable)topic;
@end

//回调函数定义如下
typedef void(^RTCXLinkAppResponseHandler)(RTCXLinkAppResponse *response);

@protocol RTCXLinkAppProtocol <NSObject>

@property (nonatomic, assign) RTCXLinkAppStatus status;
/**
 设置通道的下推侦听者，如果不需要用的时候，记得调用 `removeDownStreamListener:` 。
 `LKAppExpress` 收到云端下推的处理逻辑如下所示:
 
 if ([downListener arrowHandle: iotId] == YES) {
    [downListener onLinkDownData: data iotId: iotId];
 } else {
    NSLOG_PRINTF(@"message will ignored");
 }
 
 @param downListener 侦听下推消息，参见 `RTCXLinkAppDownListener`
 */
- (void)addLinkDownDataListener:(id<RTCXLinkAppDownListener>)downListener;

/**
 取消通道的某个下推侦听者
 
 @param downListener 侦听下推消息，参见 `LKExpDownListener`
 */
-(void)removeLinkDownDataListener:(id<RTCXLinkAppDownListener>)downListener;

/**
 app 向云端订阅 topic 的接口。
 
 @param topic 订阅的消息的 topic，由具体业务确定。暂时不生效，建议传Nil，可选
 @param productKey 设备型号  必选
 @param deviceName 设备序列号SN  必选
 @param iotId 平台为设备颁发的ID，设备的唯一标识符 必选
 @param deviceType  设备类型 0：普通设备；1：专属版设备；2：AP设备；默认0，必选
 @param completionHandler 订阅流程完成的 callback，如果 error 为空表示订阅成功，否则订阅失败
 */
- (void)subscribeToTopic:(NSString * _Nullable)topic productKey:(NSString * _Nonnull)productKey deviceName:(NSString * _Nonnull)deviceName iotId:(NSString * _Nonnull)iotId deviceType:(NSInteger)deviceType complete:(void (^)(NSError  * _Nullable error))completionHandler;

/**
 app向云端取消订阅 topic 的接口。
 
 @param topic 取消订阅的消息的 topic，由具体业务确定。暂时不生效，建议传Nil，可选
 @param productKey 设备型号  必选
 @param deviceName 设备序列号SN  必选
 @param iotId 平台为设备颁发的ID，设备的唯一标识符 必选
 @param deviceType  设备类型 0：普通设备；1：专属版设备；2：AP设备；默认0，必选
 @param completionHandler 取消订阅流程完成的 callback，如果 error 为空表示订阅成功，否则订阅失败
 */
- (void)unsubscribeToTopic:(NSString * _Nullable)topic productKey:(NSString * _Nonnull)productKey deviceName:(NSString * _Nonnull)deviceName iotId:(NSString * _Nonnull)iotId deviceType:(NSInteger)deviceType complete:(void (^)(NSError  * _Nullable error))completionHandler;

/**
 RPC请求接口，封装了业务的上行 request 以及下行 response。
 
 @param topic 请求的 topic，由具体业务确定。暂时不生效，建议传Nil，可选
 @param productKey 设备型号  必选
 @param deviceName 设备序列号SN  必选
 @param iotId 平台为设备颁发的ID，设备的唯一标识符 必选
 @param deviceType  设备类型 0：普通设备；1：专属版设备；2：AP设备；默认0，必选
 @param opts 可选配置项，可空，预留
 @param data 业务参数。
 @param responseHandler 业务服务器响应回调接口，参见 `RTCXLinkAppResponse`
 
-(void)invokeToTopic:(NSString * _Nullable)topic productKey:(NSString * _Nonnull)productKey deviceName:(NSString * _Nonnull)deviceName iotId:(NSString * _Nonnull)iotId deviceType:(NSInteger)deviceType opts:(NSDictionary* _Nullable)opts data:(NSData *)data respHandler:(RTCXLinkAppResponseHandler)responseHandler;
 */

/**
 发布消息接口，不同于 `invokeToTopic:productKey:deviceName:iotId:deviceType:opts:params:respHandler:` 。这个接口不会有业务回执。
 
 @param topic 请求的 topic，由具体业务确定。暂时不生效，建议传Nil，可选
 @param productKey 设备型号  必选
 @param deviceName 设备序列号SN  必选
 @param iotId 平台为设备颁发的ID，设备的唯一标识符 必选
 @param deviceType  设备类型 0：普通设备；1：专属版设备；2：AP设备；默认0，必选
 @param data 业务参数。
 @param completeCallback 业务服务器响应回调接口
 
-(void)publishToTopic:(NSString * _Nullable)topic productKey:(NSString * _Nonnull)productKey deviceName:(NSString * _Nonnull)deviceName iotId:(NSString * _Nonnull)iotId deviceType:(NSInteger)deviceType data:(NSData *)data complete:(void(^)(NSError* _Nullable))completeCallback;
 */

/**
 增加通道连接状态变化 listener
 @param listener 通道连接状态侦听者
 */
-(void)addLinkConnectListener:(id<LRTCXLinkAppConnectListener>)listener;

/**
 移除通道连接状态变化 listener
 @param listener 通道连接状态侦听者
 */
-(void)removeLinkConnectListener:(id<LRTCXLinkAppConnectListener>)listener;

@end

NS_ASSUME_NONNULL_END
