#import "AliyunOnePass.h"
#import <React/RCTLog.h>

#import <ATAuthSDK/ATAuthSDK.h>

TXCommonHandler* _tXCommonHandler;
TXCustomModel* _tXCustomModel;

@implementation AliyunOnePass

RCT_EXPORT_MODULE();

- (NSArray<NSString *> *) supportedEvents{
  return @[
    @"onVerifyResult"
  ];
}

- (NSDictionary *) constantsToExport{
  return @{
    @"ON_VERIFY_RESULT": @"onVerifyResult",
    @"SUCCESS": @"600000",
    @"ENTER_COMPLETE": @"600001",
    @"ENTER_ERROR": @"600002",
    @"AVAILABLE": @"600000",
    @"NO_NET": @"600008",
    @"TIMEOUT": @"600015",
    @"GET_CODE_FAILED": @"600012",
    @"CANCEL": @"700000",
    @"SWITCH": @"700001",
    @"LOGIN": @"700002",
    @"CHECK": @"700003",
    @"PRIVACY": @"700004",
  };
}

+ (BOOL) requiresMainQueueSetup{
  return NO;
}

- (dispatch_queue_t) methodQueue{
  return dispatch_get_main_queue();
}

RCT_EXPORT_METHOD(init:(NSString *)secret
              resolver:(RCTPromiseResolveBlock)resolve 
              rejecter:(RCTPromiseRejectBlock)reject){
  _tXCommonHandler = [TXCommonHandler sharedInstance];
  [_tXCommonHandler setAuthSDKInfo: secret complete: ^(NSDictionary * _Nonnull resultDic) {
    [self sendEventWithName: @"onVerifyResult" body: resultDic];
  }];
  resolve(@"");
}

RCT_EXPORT_METHOD(checkEnvAvailable){
  [_tXCommonHandler checkEnvAvailableWithAuthType: PNSAuthTypeLoginToken complete: ^(NSDictionary * _Nullable resultDic) {
    [self sendEventWithName: @"onVerifyResult" body: resultDic];
  }];
}

RCT_EXPORT_METHOD(preLogin){
  [_tXCommonHandler accelerateLoginPageWithTimeout: 0.0 complete: ^(NSDictionary * _Nonnull resultDic) {
    RCTLogInfo(@"prelogin msg：%@", [resultDic objectForKey: @"resultCode"]); 
  }];
}

RCT_EXPORT_METHOD(setAuthUIConfig:(NSDictionary *)config 
                         resolver:(RCTPromiseResolveBlock)resolve 
                         rejecter:(RCTPromiseRejectBlock)reject){
  _tXCustomModel = [[TXCustomModel alloc] init];

  [self setModel: config model: _tXCustomModel];

  resolve(@"");
}

RCT_EXPORT_METHOD(login:(RCTPromiseResolveBlock)resolve 
               rejecter:(RCTPromiseRejectBlock)reject){
  [_tXCommonHandler 
    getLoginTokenWithTimeout: 0.0 
                  controller: [UIApplication sharedApplication].keyWindow.rootViewController 
                       model: _tXCustomModel 
                    complete: ^(NSDictionary * _Nonnull resultDic) {
                      [self sendEventWithName: @"onVerifyResult" body: resultDic];
                    }
  ];
  resolve(@"");
}

RCT_EXPORT_METHOD(cancelLoading:(RCTPromiseResolveBlock)resolve 
                       rejecter:(RCTPromiseRejectBlock)reject){
  [_tXCommonHandler hideLoginLoading];
  resolve(@"");
}

RCT_EXPORT_METHOD(quit:(RCTPromiseResolveBlock)resolve 
              rejecter:(RCTPromiseRejectBlock)reject){
  [_tXCommonHandler cancelLoginVCAnimated: YES complete: ^{
    resolve(@"");
  }];
}

- (void) setModel:(NSDictionary *)config 
            model:(TXCustomModel *)model {
  NSString *navColor = [config objectForKey: @"navColor"];
  if (navColor != nil) {
    model.navColor = [self colorWithHexString: navColor];
  }

  NSString *navText = [config objectForKey: @"navText"];
  NSString *navTextColor = [config objectForKey: @"navTextColor"];
  NSString *navTextSize = [config objectForKey: @"navTextSize"];
  if (navText != nil && navTextColor != nil && navTextSize != nil) {
    model.navTitle = [[NSAttributedString alloc] 
      initWithString: navText 
          attributes: @{
            NSForegroundColorAttributeName: [self colorWithHexString: navTextColor], 
            NSFontAttributeName: [UIFont systemFontOfSize: [navTextSize doubleValue]]
          }
    ];
  }

  NSString *navBackImgPath = [config objectForKey: @"navBackImgPath"];
  if (navBackImgPath != nil) {
    model.navBackImage = [UIImage imageNamed: navBackImgPath];
  }

  NSString *navBackHidden = [config objectForKey: @"navBackHidden"];
  if (navBackHidden != nil) {
    model.hideNavBackItem = [navBackHidden boolValue];
  }

  NSString *navBackImgWidth = [config objectForKey: @"navBackImgWidth"];
  NSString *navBackImgHeight = [config objectForKey: @"navBackImgHeight"];
  model.navBackButtonFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
    CGFloat x = frame.origin.x;
    CGFloat y = frame.origin.y;
    CGFloat width = frame.size.width;
    CGFloat height = frame.size.height;
    if (navBackImgWidth != nil) {
      width = [navBackImgWidth floatValue];
    }
    if (navBackImgHeight != nil) {
      height = [navBackImgHeight floatValue];
    }
    return CGRectMake(x, y, width, height);
  };

  NSString *navHidden = [config objectForKey: @"navHidden"];
  if (navHidden != nil) {
    model.navIsHidden = [navHidden boolValue];
  }

  NSString *webNavColor = [config objectForKey: @"webNavColor"];
  if (webNavColor != nil) {
    model.privacyNavColor = [self colorWithHexString: webNavColor];
  }
  NSString *webNavTextColor = [config objectForKey: @"webNavTextColor"];
  if (webNavTextColor != nil) {
    model.privacyNavTitleColor = [self colorWithHexString: webNavTextColor];
  }
  NSString *webNavTextSize = [config objectForKey: @"webNavTextSize"];
  if (webNavTextSize != nil) {
    model.privacyNavTitleFont = [UIFont systemFontOfSize: [webNavTextSize doubleValue]];
  }
  NSString *webNavBackImgPath = [config objectForKey: @"webNavBackImgPath"];
  if (webNavBackImgPath != nil) {
    model.privacyNavBackImage = [UIImage imageNamed: webNavBackImgPath];
  }

  NSString *light = [config objectForKey: @"light"];
  if (light != nil) {
    BOOL value = [light boolValue];
    if (value) {
      model.preferredStatusBarStyle = UIStatusBarStyleDarkContent;
    }else {
      model.preferredStatusBarStyle = UIStatusBarStyleLightContent;
    }
  }

  NSString *logoImgPath = [config objectForKey: @"logoImgPath"];
  if (logoImgPath != nil) {
    model.logoImage = [UIImage imageNamed: logoImgPath];
  }
  NSString *logoHidden = [config objectForKey: @"logoHidden"];
  if (logoHidden != nil) {
    model.logoIsHidden = [logoHidden boolValue];
  }
  NSString *logoWidth = [config objectForKey: @"logoWidth"];
  NSString *logoHeight = [config objectForKey: @"logoHeight"];
  NSString *logoOffsetTop = [config objectForKey: @"logoOffsetTop"];
  model.logoFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
    CGFloat y = frame.origin.y;
    CGFloat width = frame.size.width;
    CGFloat height = frame.size.height;
    if (logoOffsetTop != nil) {
      y = [logoOffsetTop floatValue];
    }
    if (logoWidth != nil) {
      width = [logoWidth floatValue];
    }
    if (logoHeight != nil) {
      height = [logoHeight floatValue];
    }
    return CGRectMake((screenSize.width - width) / 2, y, width, height);
  };

  NSString *sloganText = [config objectForKey: @"sloganText"];
  NSString *sloganTextColor = [config objectForKey: @"sloganTextColor"];
  NSString *sloganTextSize = [config objectForKey: @"sloganTextSize"];
  if (sloganText != nil && sloganTextColor != nil && sloganTextSize != nil) {
    model.sloganText = [[NSAttributedString alloc] 
      initWithString: sloganText 
          attributes: @{
            NSForegroundColorAttributeName: [self colorWithHexString: sloganTextColor], 
            NSFontAttributeName: [UIFont systemFontOfSize: [sloganTextSize doubleValue]]
          }
    ];
  }

  NSString *sloganOffsetTop = [config objectForKey: @"sloganOffsetTop"];
  model.sloganFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
    CGFloat x = frame.origin.x;
    CGFloat y = frame.origin.y;
    CGFloat width = frame.size.width;
    CGFloat height = frame.size.height;
    if (sloganOffsetTop != nil) {
      y = [sloganOffsetTop floatValue];
    }
    return CGRectMake(x, y, width, height);
  };

  NSString *numberColor = [config objectForKey: @"numberColor"];
  if (numberColor != nil) {
    model.numberColor = [self colorWithHexString: numberColor];
  }
  NSString *numberSize = [config objectForKey: @"numberSize"];
  if (numberSize != nil) {
    model.numberFont = [UIFont systemFontOfSize: [numberSize doubleValue]];
  }
  NSString *numberOffsetTop = [config objectForKey: @"numberOffsetTop"];
  model.numberFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
    CGFloat x = frame.origin.x;
    CGFloat y = frame.origin.y;
    CGFloat width = frame.size.width;
    CGFloat height = frame.size.height;
    
    if (numberOffsetTop != nil) {
      y = [numberOffsetTop floatValue];
    }
    return CGRectMake(x, y, width, height);
  };

  NSString *btnText = [config objectForKey: @"btnText"];
  NSString *btnTextColor = [config objectForKey: @"btnTextColor"];
  NSString *btnTextSize = [config objectForKey: @"btnTextSize"];
  if (btnText != nil && btnTextColor != nil && btnTextSize != nil) {
    model.loginBtnText = [[NSAttributedString alloc] 
      initWithString: btnText 
          attributes: @{
            NSForegroundColorAttributeName: [self colorWithHexString: btnTextColor], 
            NSFontAttributeName: [UIFont systemFontOfSize: [btnTextSize doubleValue]]
          }
    ];
  }

  NSString *btnWidth = [config objectForKey: @"btnWidth"];
  NSString *btnHeight = [config objectForKey: @"btnHeight"];
  NSString *btnOffsetTop = [config objectForKey: @"btnOffsetTop"];
  model.loginBtnFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
    CGFloat x = frame.origin.x;
    CGFloat y = frame.origin.y;
    CGFloat width = frame.size.width;
    CGFloat height = frame.size.height;
    if (btnOffsetTop != nil) {
      y = [btnOffsetTop floatValue];
    }
    if (btnWidth != nil) {
      width = [btnWidth floatValue];
    }
    if (btnHeight != nil) {
      height = [btnHeight floatValue];
    }
    return CGRectMake(x, y, width, height);
  };

  NSString *btnBackgroundImgPath = [config objectForKey: @"btnBackgroundImgPath"];
  if (btnBackgroundImgPath != nil) {
    model.loginBtnBgImgs = @[
      [UIImage imageNamed: btnBackgroundImgPath], 
      [UIImage imageNamed: btnBackgroundImgPath], 
      [UIImage imageNamed: btnBackgroundImgPath]
    ];
  }

  model.autoHideLoginLoading = NO;

  NSString *switchAccHidden = [config objectForKey: @"switchAccHidden"];
  if (switchAccHidden != nil) {
    model.changeBtnIsHidden = [switchAccHidden boolValue];
  }
  NSString *switchAccText = [config objectForKey: @"switchAccText"];
  NSString *switchAccTextColor = [config objectForKey: @"switchAccTextColor"];
  NSString *switchAccTextSize = [config objectForKey: @"switchAccTextSize"];
  if (switchAccText != nil && switchAccTextColor != nil && switchAccTextSize != nil) {
    model.changeBtnTitle = [[NSAttributedString alloc] 
      initWithString: switchAccText 
          attributes: @{
            NSForegroundColorAttributeName: [self colorWithHexString: switchAccTextColor], 
            NSFontAttributeName: [UIFont systemFontOfSize: [switchAccTextSize doubleValue]]
          }
    ];
  }
  NSString *switchOffsetTop = [config objectForKey: @"switchOffsetTop"];
  model.changeBtnFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
    CGFloat x = frame.origin.x;
    CGFloat y = frame.origin.y;
    CGFloat width = frame.size.width;
    CGFloat height = frame.size.height;
    
    if (switchOffsetTop != nil) {
      y = [switchOffsetTop floatValue];
    }
    return CGRectMake(x, y, width, height);
  };

  NSString *privacyOneName = [config objectForKey: @"privacyOneName"];
  NSString *privacyOneURL = [config objectForKey: @"privacyOneURL"];
  if (privacyOneName != nil && privacyOneURL != nil) {
    model.privacyOne = @[privacyOneName, privacyOneURL];
  }
  NSString *privacyTwoName = [config objectForKey: @"privacyTwoName"];
  NSString *privacyTwoURL = [config objectForKey: @"privacyTwoURL"];
  if (privacyTwoName != nil && privacyTwoURL != nil) {
    model.privacyTwo = @[privacyTwoName, privacyTwoURL];
  }
  NSString *privacyThreeName = [config objectForKey: @"privacyThreeName"];
  NSString *privacyThreeURL = [config objectForKey: @"privacyThreeURL"];
  if (privacyThreeName != nil && privacyThreeURL != nil) {
    model.privacyThree = @[privacyThreeName, privacyThreeURL];
  }
  NSString *privacyColor = [config objectForKey: @"privacyColor"];
  NSString *privacyLightColor = [config objectForKey: @"privacyLightColor"];
  if (privacyColor != nil && privacyLightColor != nil) {
    model.privacyColors = @[
      [self colorWithHexString: privacyColor], 
      [self colorWithHexString: privacyLightColor]
    ];
  }
  NSString *privacyOffsetTop = [config objectForKey: @"privacyOffsetTop"];
  model.privacyFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
    CGFloat x = frame.origin.x;
    CGFloat y = frame.origin.y;
    CGFloat width = frame.size.width;
    CGFloat height = frame.size.height;
    if (privacyOffsetTop != nil) {
      y = [privacyOffsetTop floatValue];
    }
    return CGRectMake(x, y, width, height);
  };
  NSString *privacyTextSize = [config objectForKey: @"privacyTextSize"];
  if (privacyTextSize != nil) {
    model.privacyFont = [UIFont systemFontOfSize: [privacyTextSize doubleValue]];
  }
  NSString *privacyBefore = [config objectForKey: @"privacyBefore"];
  if (privacyBefore != nil) {
    model.privacyPreText = privacyBefore;
  }
  NSString *privacyEnd = [config objectForKey: @"privacyEnd"];
  if (privacyEnd != nil) {
    model.privacySufText = privacyEnd;
  }

  model.privacyAlignment = NSTextAlignmentCenter;

  NSString *checkedImgPath = [config objectForKey: @"checkedImgPath"];
  NSString *unCheckedImgPath = [config objectForKey: @"unCheckedImgPath"];
  if (checkedImgPath != nil && unCheckedImgPath != nil) {
    model.checkBoxImages = @[
      [UIImage imageNamed: unCheckedImgPath], 
      [UIImage imageNamed: checkedImgPath]
    ];
  }

  NSString *vendorPrivacyPrefix = [config objectForKey: @"vendorPrivacyPrefix"];
  if (vendorPrivacyPrefix != nil) {
    model.privacyOperatorPreText = vendorPrivacyPrefix;
  }
  NSString *vendorPrivacySuffix = [config objectForKey: @"vendorPrivacySuffix"];
  if (vendorPrivacySuffix != nil) {
    model.privacyOperatorSufText = vendorPrivacySuffix;
  }

  model.supportedInterfaceOrientations = UIInterfaceOrientationMaskPortrait;
}

- (UIColor *) colorWithHexString:(NSString *)color{
  NSString *cString = [
    [color stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]] 
    uppercaseString
  ];

  // String should be 6 or 8 characters
  if ([cString length] < 6) {
    return [UIColor clearColor];
  }

  // 判断前缀
  if ([cString hasPrefix: @"0X"])
    cString = [cString substringFromIndex: 2];
  if ([cString hasPrefix: @"#"])
    cString = [cString substringFromIndex: 1];
  if ([cString length] != 6)
    return [UIColor clearColor];
  // 从六位数值中找到RGB对应的位数并转换
  NSRange range;
  range.location = 0;
  range.length = 2;
  //R、G、B
  NSString *rString = [cString substringWithRange: range];
  range.location = 2;
  NSString *gString = [cString substringWithRange: range];
  range.location = 4;
  NSString *bString = [cString substringWithRange: range];
  // Scan values
  unsigned int r, g, b;
  [[NSScanner scannerWithString: rString] scanHexInt: &r];
  [[NSScanner scannerWithString: gString] scanHexInt: &g];
  [[NSScanner scannerWithString: bString] scanHexInt: &b];

  return [UIColor 
    colorWithRed: ((float) r / 255.0f) 
           green: ((float) g / 255.0f) 
            blue: ((float) b / 255.0f) 
           alpha: 1.0f
  ];
}

@end
