//
//  AliyunCameraView.h
//  AliyunIdentityFace
//
//  Created by 顾鹿 on 2024/7/17.
//  Copyright © 2024 aliyun.com. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

#pragma mark - 状态定义
typedef enum : NSUInteger {
    APMCameraRunningStarting,
    APMCameraRunningStarted,
    APMCameraRunning,
    APMCameraNoCameraPermission,
    APMCameraRunningStopped,
    APMCameraRunningError,
} APMCameraRunningStatus;

@class AliyunCameraView;
@protocol AliyunCameraViewDelegate <NSObject>
@optional
- (void)cameraView:(AliyunCameraView *)cameraView didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer;
@end
#pragma mark - handler定义
typedef void (^APMCameraRunningHandler)(APMCameraRunningStatus status, NSError *error);
typedef void (^APMCameraPictureHandler)(NSData *imageData, NSError *error);
typedef void (^APMCameraOperationHandler)(BOOL result);

#pragma mark - AliyunCameraView
@interface AliyunCameraView : UIView

@property (nonatomic, assign) AVCaptureDevicePosition currentPosition;
@property (nonatomic, assign, readonly) AVCaptureFlashMode flashMode;
@property (nonatomic, assign, readonly) AVCaptureTorchMode torchMode;
@property (nonatomic, assign) AVCaptureFocusMode focusMode;
@property (nonatomic, assign) AVCaptureExposureMode exposureMode;
@property (nonatomic, assign) AVCaptureWhiteBalanceMode whiteBalanceMode;
@property (nonatomic, assign, readonly) CMTime minExposureDuration;
@property (nonatomic, assign, readonly) CMTime maxExposureDuration;
@property (nonatomic, assign, readonly) float minISO;
@property (nonatomic, assign, readonly) float maxISO;
@property (nonatomic, assign) NSUInteger fps;
@property (nonatomic) BOOL automaticallyAdjustsVideoHDREnabled;
@property (nonatomic, getter=isVideoHDREnabled) BOOL videoHDREnabled;
@property (nonatomic, readonly) float exposureTargetOffset;
@property (nonatomic, readonly) float exposureTargetBias;
@property (nonatomic, readonly) float minExposureTargetBias;
@property (nonatomic, readonly) float maxExposureTargetBias;
@property (nonatomic, strong) UIImage *loadingImage;
@property (nonatomic, weak) id<AliyunCameraViewDelegate> delegate;
@property (nonatomic, assign) OSType frameFormat;
@property (nonatomic, assign) BOOL needFocusAndZoom;
@property (nonatomic, assign) BOOL needRunningAnimation;
@property (nonatomic, assign) BOOL enableVideoStabilization;
@property (nonatomic, assign) BOOL hiddenPreviewWhenStop;
@property (nonatomic, strong) NSString *preset;
@property (nonatomic, assign) AVCaptureVideoOrientation cameraOrientation;
@property (nonatomic, assign) BOOL useDeviceOrientation;
@property (nonatomic, assign, readonly) AVCaptureVideoOrientation deviceOrientation;
@property (nonatomic, assign) BOOL usePreviewLayer;
@property (nonatomic, weak) UIView *containerPreview;

+ (BOOL)isFlashSupport:(AVCaptureDevicePosition)position;
+ (BOOL)isTorchSupport:(AVCaptureDevicePosition)position;

- (void)switchCamera:(APMCameraOperationHandler)handler;
- (void)setFlashMode:(AVCaptureFlashMode)flashMode handler:(APMCameraOperationHandler)handler;
- (void)setTorchMode:(AVCaptureTorchMode)torchMode handler:(APMCameraOperationHandler)handler;
- (void)setExposureTime:(CMTime)expTime ISO:(float)iso completionHandler:(void (^)(CMTime syncTime))handler;
- (void)setExposureTargetBias:(float)bias completionHandler:(void (^)(CMTime syncTime))handler;

- (void)startRunning:(APMCameraRunningHandler)handler;
- (void)stopRunning;
- (void)takePicture:(APMCameraPictureHandler)handler;
- (CGPoint)imagePositionForPoint:(CGPoint)pointInView;
- (void)focusWithPoint:(CGPoint)point;
- (void)zoomWithFactor:(float)factor;
+ (AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition)position;
- (void)setCameraOrientation:(AVCaptureVideoOrientation)orientation;
- (void)turnOnFlashWithHandler:(APMCameraOperationHandler)handler;
- (void)turnOffFlashWithHandler:(APMCameraOperationHandler)handler;

#if DEBUG
#pragma mark - Mock (DEBUG-only 内部测试：hook 摄像头，注入本地视频帧)
// 仅 Debug 编译生效，Release 包不包含任何 mock 符号。镜像刷脸 AliyunCameraService 的 mock 接口。
@property (nonatomic, strong) AVSampleBufferDisplayLayer *mockDisplayLayer;
+ (void)setMockEnabled:(BOOL)enabled;
+ (BOOL)isMockEnabled;
+ (nullable instancetype)currentMockInstance;
- (void)injectSampleBuffer:(CMSampleBufferRef)sampleBuffer;
#endif
@end
