//
//  EZAPWiFiConfigViewController.m
//  EZOpenSDKDemo
//
//  Created by linyong on 2018/6/4.
//  Copyright © 2018年 Ezviz. All rights reserved.
//

#import "EZAPWiFiConfigViewController.h"
#import <NetworkExtension/NEHotspotConfigurationManager.h>
#import "GlobalKit.h"
#import "EZCommonTool.h"
#import "EZHCNetDeviceSDK.h"
#import "EZConfigTokenInfo.h"
#import "EZAPConfigResultViewController.h"
#import "EZDeviceTableViewController.h"

#define SEARCH_MAX_COUNT (20)

@interface EZAPWiFiConfigViewController () {
    BOOL connect2DeviceHotspotAutoFailed;///< 尝试过自动连接设备热点失败
}

@property (weak, nonatomic) IBOutlet UIView *tipsView;
@property (weak, nonatomic) IBOutlet UILabel *wifiNameLabel;
@property (weak, nonatomic) IBOutlet UILabel *wifiPwdLabel;
@property (weak, nonatomic) IBOutlet UILabel *stepTwoLabel;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *processingIndicator;
@property (weak, nonatomic) IBOutlet UIButton *addBtn;
@property (weak, nonatomic) IBOutlet UILabel *addTipsLabel;

@property (nonatomic, copy) NSString *devicWifiName;
@property (nonatomic, copy) NSString *devicWifiPsw;
@property (nonatomic, strong) NSTimer *timer;///< 用户手动连接设备热点后，定时判断是否已经连接上设备热点

@property (nonatomic, strong) EZConfigTokenInfo *tokenInfo;
@property (nonatomic, strong) NSTimer *searchTimer;///< EZAPConfigTypeHttp模式配网需要轮询
@property (nonatomic, assign) NSInteger searchCount;///< 轮询次数

@end

@implementation EZAPWiFiConfigViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = NSLocalizedString(@"wifi_mode_wifi_connect",@"连接到设备Wi-Fi");
    
    [self initSubviews];
    if (self.apConfigType == EZAPConfigTypeHttp) {
        // EZAPConfigTypeHttp模式配网，连接设备热点之前需要先获取token信息
        [EZOPENSDK getNewApConfigToken:^(EZConfigTokenInfo * _Nonnull tokenInfo, NSError * _Nonnull error) {
            if (error) {
                [EZToast show:[NSString stringWithFormat:@"%@", error]];
                return;
            }
            self.tokenInfo = tokenInfo;
            [self connect2DeviceHotspot];
        }];
    } else {
        [self connect2DeviceHotspot];
    }
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (connect2DeviceHotspotAutoFailed) {
        [self startTimer];
        [self addNotifications];
    }
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    if (connect2DeviceHotspotAutoFailed) {
        [self stopTimer];
        [self stopConfigWifi];
        [self removeNotifications];
    }
}

#pragma mark - views

- (void)initSubviews {
    self.processingIndicator.hidden = YES;
    self.devicWifiName = [NSString stringWithFormat:@"%@_%@",[GlobalKit shareKit].WiFiConfigPrefix,[GlobalKit shareKit].deviceSerialNo];
    if (self.apConfigType == EZAPConfigTypeHttp) {
        self.devicWifiPsw = @"";
    } else {
        self.devicWifiPsw = [NSString stringWithFormat:@"%@_%@",[GlobalKit shareKit].WiFiConfigPrefix,[GlobalKit shareKit].deviceVerifyCode];
    }
    self.wifiNameLabel.text = self.devicWifiName;
    self.wifiPwdLabel.text = self.devicWifiPsw;
    NSString *str = [NSString stringWithFormat:NSLocalizedString(@"wifi_step_two_msg",@"进入手机系统Wi-Fi设置界面，选择名称为%@的网络，用提示的密码进行连接"),self.devicWifiName];
    NSMutableAttributedString *aStr = [[NSMutableAttributedString alloc] initWithString:str];
    
    // 关键字符颜色调整
    [aStr addAttribute:NSForegroundColorAttributeName value:[UIColor orangeColor] range:[str rangeOfString:self.devicWifiName]];
    
    // 行间距调整
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    [paragraphStyle setLineSpacing:5];
    [aStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [aStr length])];
    
    self.stepTwoLabel.attributedText = aStr;
}

- (void)startAction {
    self.processingIndicator.hidden = NO;
    self.addBtn.hidden = YES;
    self.addTipsLabel.hidden = YES;
    [self.processingIndicator startAnimating];
}

- (void)stopAction {
    [self.processingIndicator stopAnimating];
    self.processingIndicator.hidden = YES;
}

#pragma mark - notification

- (void)addNotifications {
    [self removeNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationDidBecomeActive)
                                                 name:UIApplicationDidBecomeActiveNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationWillResignActive)
                                                 name:UIApplicationWillResignActiveNotification
                                               object:nil];
}

- (void)removeNotifications {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)applicationDidBecomeActive {
    [self startTimer];
}

- (void)applicationWillResignActive {
    [self stopTimer];
}

#pragma mark - Actions

/** 复制密码 */
- (IBAction)copyPwdBtnClick:(id)sender {
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    pasteboard.string = self.wifiPwdLabel.text;
    
    [self.view makeToast:@"done" duration:1.5 position:@"center"];
}

/** 进入设置界面 */
- (IBAction)enterSettingBtnClick:(id)sender {
    [EZCommonTool toSystemWiFiSettingPage];
}

/** 添加设备 */
- (IBAction)addBtnClick:(id)sender {
    [self performSegueWithIdentifier:@"go2WifiConfigResult" sender:nil];
}

#pragma mark - support

- (void)configWifiUseAP {
    [EZOPENSDK startAPConfigWifiWithSsid:self.ssid
                                password:self.password
                            deviceSerial:[GlobalKit shareKit].deviceSerialNo
                              verifyCode:[GlobalKit shareKit].deviceVerifyCode
                            deviceStatus:^(EZWifiConfigStatus status, NSString * _Nonnull deviceSerial) {
        switch (status) {
            case DEVICE_WIFI_SENT_SUCCESS:// 向设备发送WiFi信息成功
                // 等待设备配网，如果wifi密码错误，最后会回调DEVICE_PLATFORM_REGIST_FAILED
                [EZToast show:NSLocalizedString(@"wifi_info_send_success", @"向设备发送WiFi信息成功")];
                break;
            case DEVICE_WIFI_SENT_FAILED:// 向设备发送WiFi信息失败
                // 配网失败，可以重试
                [EZToast show:@"配网失败，请稍后重试"];
                self.tipsView.hidden = NO;
                break;
            case DEVICE_PLATFORM_REGISTED:// 设备注册平台成功
                // TODO 将设备添加到自己账号下
                [EZToast show:@"设备注册平台成功"];
                
                [self stopAction];
                self.addBtn.hidden = NO;
                break;
            case DEVICE_PLATFORM_REGIST_FAILED:// 设备注册平台失败
                // TODO 可以自行开启新一轮轮询
                [EZToast show:@"设备注册平台失败"];
                [self stopAction];
                self.tipsView.hidden = NO;
                
                break;
            default:
                break;
        }
    }];
    
    //    [EZOPENSDK startAPConfigWifiWithSsid:self.ssid
    //                                password:self.password
    //                            deviceSerial:[GlobalKit shareKit].deviceSerialNo
    //                              verifyCode:[GlobalKit shareKit].deviceVerifyCode
    //                                  result:^(BOOL ret) {
    //
    //        // 注意：返回YES仅仅代表成功将WiFi信息发送给设备，不代表设备配网成功。发送成功后，会出现添加设备按钮，然后去查询设备是否配网成功并注册到平台
    //        if (ret) {
    //            [self sendWiFi2DeviceSuccess];
    //            NSLog(@"send WiFi info to device success");
    //        } else {
    //            [self sendWiFi2DeviceFailed];
    //            NSLog(@"send WiFi info to device failed");
    //        }
    //    }];
}

- (void)configWifiUseHttp {
    // 延迟5秒，等热点连接好的时候再去配网；设置里面热点连接过程中会转圈圈，此时还未连接成功
    DISPATCH_AFTER(5, ^{
        // 步骤4：发起配网请求，设备配网成功后会自动绑定到账号下
        [EZOPENSDK startNewApConfigWithToken:self.tokenInfo.token
                                        ssid:self.ssid password:self.password
                                   lbsDomain:self.tokenInfo.lbsDomain
                           completionHandler:^(EZNewAPConfigStatus status, NSError * _Nonnull error) {
            NSLog(@"EZNewAPConfigStatus result--->%ld", (long)status);
            switch (status) {
                case EZNewAPConfigStatusConnectSuccess:
                case EZNewAPConfigStatusUnknow:
                    // 步骤5：设备联网成功或者未知错误(某些型号设备无返回值)的时候发起轮询设备的绑定情况
                    [self startSearchTimer];
                    break;
                case EZNewAPConfigStatusPasswordError:
                    
                    break;
                case EZNewAPConfigStatusNoAPFound:
                    
                    break;
                    
                default:
                    break;
            }
        }];
    });
}

- (void)sendWiFi2DeviceSuccess {
    [self stopAction];
    self.addBtn.hidden = NO;
    self.addTipsLabel.hidden = NO;
}

- (void)sendWiFi2DeviceFailed {
    [self stopAction];
    self.tipsView.hidden = NO;
    [self.view makeToast:@"config wifi fail" duration:1.5 position:@"center"];
}

#pragma mark - 定时器 | timer

- (void)startTimer {
    [self stopTimer];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(timerCallback) userInfo:nil repeats:YES];
}

- (void)stopTimer {
    if (!self.timer) {
        return;
    }
    if ([self.timer isValid]) {
        [self.timer invalidate];
    }
    self.timer = nil;
}

- (void)timerCallback {
    // 网络不一致，拦截。必须连接上设备热点后才能发起配网！
    if (![[EZCommonTool getWiFiName] isEqualToString:self.devicWifiName]) {
        return;
    }
    [self stopTimer];
    [self startAction];
    
    [self startConfigWifi];
}

- (void)startSearchTimer {
    [self stopSearchTimer];
    self.searchTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(searchDeviceFromService) userInfo:nil repeats:YES];
}

- (void)stopSearchTimer {
    if (!self.searchTimer) {
        return;
    }
    if ([self.searchTimer isValid]) {
        [self.searchTimer invalidate];
    }
    self.searchTimer = nil;
    self.searchCount = 0;
}

- (void)searchDeviceFromService {
    self.searchCount ++;
    if (self.searchCount >= SEARCH_MAX_COUNT) {
        [self.searchTimer invalidate];
        self.searchTimer = nil;
        return;
    }
    [EZOPENSDK queryPlatformBindStatus:[GlobalKit shareKit].deviceSerialNo completion:^(BOOL isBindSuccess, NSError * _Nonnull error) {
        if (isBindSuccess) {
            [EZToast show:NSLocalizedString(@"wifi_device_bind_success", @"设备已联网成功并绑定账号")];
            [self stopSearchTimer];
            [self pop2RootViewController];
        } else {
            NSLog(@"error--->%@", error);
        }
    }];
}

#pragma mark - private methods

/** 连接设备热点 */
- (void)connect2DeviceHotspot {
    // 系统>=11，可以自动连接热备热点
    [self startAction];
    
    // 创建将要连接的WIFI配置实例
    NEHotspotConfiguration *hotspotConfig;
    if (self.apConfigType == EZAPConfigTypeHttp) {
        hotspotConfig = [[NEHotspotConfiguration alloc] initWithSSID:self.devicWifiName];
    } else {
        hotspotConfig = [[NEHotspotConfiguration alloc] initWithSSID:self.devicWifiName passphrase:self.devicWifiPsw isWEP:NO];
    }
    // 开始连接 (调用此方法后系统会自动弹窗确认)
    [[NEHotspotConfigurationManager sharedManager] applyConfiguration:hotspotConfig completionHandler:^(NSError * _Nullable error) {
        // 系统api-applyConfiguration有bug，就算连接失败，error也是nil。需要判断下当前WiFi是否是热备热点，是的话才算连接成功
        if ([[EZCommonTool getWiFiName] isEqualToString:self.devicWifiName]) {
            NSLog(@"connect to device hotspot success");
            [self startConfigWifi];
        } else {
            NSLog(@"connect to device hotspot failed");
            self.tipsView.hidden = NO;
            connect2DeviceHotspotAutoFailed = YES;
            [self stopAction];
        }
    }];
}

/** 开始配网 */
- (void)startConfigWifi {
    if (self.apConfigType == EZAPConfigTypeNetSDK) {
        [self configWifiUseAP];
    } else if (self.apConfigType == EZAPConfigTypeHttp) {
        [self configWifiUseHttp];
    }
}

/** 结束配网 */
- (void)stopConfigWifi {
    if (self.apConfigType == EZAPConfigTypeNetSDK) {
        [EZOPENSDK stopAPConfigWifi];
    } else if (self.apConfigType == EZAPConfigTypeHttp) {
        [self stopSearchTimer];
    }
}

/** 返回到设备列表页面 */
- (void)pop2RootViewController {
    NSArray *viewControllers = self.navigationController.viewControllers;
    for (UIViewController *vc in viewControllers) {
        if ([vc isKindOfClass:[EZDeviceTableViewController class]]) {
            ((EZDeviceTableViewController *)vc).needRefresh = YES;
            [self.navigationController popToViewController:vc animated:YES];
            break;
        }
    }
}

#pragma mark - Navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

}

@end
