//
//  LoginController.swift
//  OrderScheduling
//
//  Created by 中道 on 2023/8/4.
//

import Foundation
import SnapKit
import RxRelay
import RxCocoa
import RxSwift
import DDProgressHUDKit_Private
import DDAutoUIKit_Private
import DDControlsKit_Private
import DDUtilsSwiftKit_Private
import SwiftyRSA

class LoginController : ZDViewController {
    private let disposeBag = DisposeBag()
    private let loginView = LoginView.init()
    private let loginNoticeView = CommonAlertView()
    private let agreeSub = ReplaySubject<Bool>.create(bufferSize: 1)
    private let loginSub = ReplaySubject<Bool>.create(bufferSize: 1)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        dd_navigationBarBackgroundColor = .clear
        navigationItem.leftBarButtonItems = nil
        addSubviews()
        addActions()
    }
}
extension LoginController {
    func addSubviews() {
        view.addSubview(loginView)
        loginView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        loginView.backgroundImageView.image = UIImage(named: "login_backgroundImage")
        loginView.inputContentView.backgroundColor = UIColor.white
        loginView.phoneView.titleLabel.text = "用户名"
        loginView.phoneView.textfield.attributedPlaceholder = NSAttributedString(string: "请输入用户名",attributes: [.foregroundColor: UIColor.hex("203152").alpha(0.2),.font:UIFont.regularFont(auto(14))])
        loginView.phoneView.textfield.text = USER.phone
        loginView.codeView.titleLabel.text = "密码"
        loginView.codeView.textfield.attributedPlaceholder = NSAttributedString(string: "请输入密码",attributes: [.foregroundColor: UIColor.hex("203152").alpha(0.2),.font:UIFont.regularFont(auto(14))])
        loginView.codeView.textfield.isSecureTextEntry = true
        loginView.codeView.eyeButton.isHidden = false
        loginView.codeView.eyeButton.adjustsImageWhenHighlighted = false
        loginView.codeView.eyeButton.setImage(UIImage(named: "login_eye_close")?.withTintColor(.lightGray), for: .normal)
        loginView.codeView.eyeButton.setImage(UIImage(named: "login_eye_open")?.withTintColor(.lightGray), for: .selected)
        loginView.agreeButton.setBackgroundImage(UIImage(named: "login_agree_unselected"), for: .normal)
        loginView.agreeButton.setBackgroundImage(UIImage(named: "login_agree_selected"), for: .selected)
        let privacyText = NSAttributedString.init(string: "已阅读并同意",attributes: [.foregroundColor:UIColor.hex("203152"),.font:UIFont.regularFont(auto(14))]).dd_mutable()
        let privacyText_appendUser = NSAttributedString.init(string: "《用户协议》",attributes: [.foregroundColor:UIColor.hex("354D93"),.font:UIFont.regularFont(auto(14))]).dd_mutable()
        privacyText_appendUser.addAttribute(.link, value: login_attach_userAgreement_key, range: NSRange(location: 0, length: privacyText_appendUser.length))
        let privacyText_appendPrivacy = NSAttributedString.init(string: "《隐私协议》",attributes: [.foregroundColor:UIColor.hex("354D93"),.font:UIFont.regularFont(auto(14))]).dd_mutable()
        privacyText_appendPrivacy.addAttribute(.link, value: login_attach_privacy_key, range: NSRange(location: 0, length: privacyText_appendPrivacy.length))
        loginView.agreeTextView.attributedText = privacyText.dd_append(privacyText_appendUser).dd_append(privacyText_appendPrivacy)
        loginView.agreeTextView.textContainerInset = .zero
        loginView.agreeTextView.textContainer.lineFragmentPadding = 0
        loginView.agreeTextView.isEditable = false
        loginView.agreeTextView.delegate = self
        
        loginView.loginButton.backgroundColor = .hex("1C6CCE").alpha(0.4)
        loginView.loginButton.setTitle("登录", for: .normal)
        
        loginNoticeView.sureButton.setTitle("登录", for: .normal)
    }
}
extension LoginController {
    func addActions() {
        loginView.codeView.eyeButton.rx.tap
            .observe(on: MainScheduler.instance)
            .subscribe(onNext: {[weak self] in
                if let isSelected = self?.loginView.codeView.eyeButton.isSelected {
                    self?.loginView.codeView.eyeButton.isSelected = !isSelected
                    self?.loginView.codeView.textfield.isSecureTextEntry = isSelected
                }
            })
            .disposed(by: disposeBag)
        
        loginView.agreeButton.rx.tap
            .asDriver()
            .drive(onNext: {[weak self] _ in
                if let isSelected = self?.loginView.agreeButton.isSelected {
                    self?.agreeButtonBinder.onNext(!isSelected)
                    self?.agreeSub.onNext(!isSelected)
                }
            })
            .disposed(by: disposeBag)
        
        Observable.combineLatest(loginView.phoneView.textfield.rx.text, loginView.codeView.textfield.rx.text,agreeSub)
            .asDriver(onErrorJustReturn: ("","",false))
            .drive(onNext: {[weak self] (phone,code,isAgree) in
                if phone?.isEmpty == false && code?.isEmpty == false && isAgree == true {
                    self?.loginView.loginButton.isEnabled = true
                    self?.loginView.loginButton.backgroundColor = .hex("1C6CCE").alpha(1)
                }else{
                    self?.loginView.loginButton.isEnabled = false
                    self?.loginView.loginButton.backgroundColor = .hex("1C6CCE").alpha(0.4)
                }
            })
            .disposed(by: disposeBag)
        
        loginView.loginButton.rx.tap
            .observe(on: MainScheduler.instance)
            .do(onNext: {[weak self] _ in
                self?.view.dd_showHUD()
            })
            .map({[weak self] _ in
                CheckLoginParameters(username: self?.loginView.phoneView.textfield.text ?? "", deviceId: USER.deviceId ?? "")
            })
            .flatMapLatest({ checkLoginParameters in
                return RQ.checkLogin(parameters: checkLoginParameters)
            })
            .observe(on: MainScheduler.instance)
            .do(onNext: {[weak self] _ in
                self?.view.dd_hideHUD()
            })
            .observe(on: MainScheduler.instance)
            .subscribe(onNext: {[weak self] response in
                if response?.code == 200 {
                    self?.loginSub.onNext(true)
                }else{
                    self?.view.dd_makeToast(response?.msg)
                }
            })
            .disposed(by: disposeBag)
        
        loginNoticeView.sureButton.rx.tap
            .observe(on: MainScheduler.instance)
            .subscribe(onNext: {[weak self] in
                ENTRY.dismiss(name: loginNoticeEntry) {[weak self] in
                    self?.loginSub.onNext(true)
                }
            })
            .disposed(by: disposeBag)
        
        loginNoticeView.cancelButton.rx.tap
            .observe(on: MainScheduler.instance)
            .subscribe(onNext: {
                ENTRY.dismiss(name: loginNoticeEntry) {
                }
            })
            .disposed(by: disposeBag)
                
        loginSub
            .observe(on: MainScheduler.instance)
            .do(onNext: {[weak self] _ in
                self?.view.dd_showHUD()
            })
            .observe(on: MainScheduler.instance)
            .map({[weak self] _ in
                let username = self?.loginView.phoneView.textfield.text ?? ""
                let clientType = "rescueApp"
                let appVsersion = APPINFO.bundleVersionShort()
                let brand = "iPhone"
                let model = DEVICEINFO.deviceModel()
                let sdkRelease = UIDevice.current.systemVersion
                let platform = "iOS"
                let deviceId = USER.deviceId ?? ""
                let regId = USER.regId ?? ""
                
                let timeInterval = Int(Date().timeIntervalSince1970)

                let publicKey = try PublicKey(pemEncoded: "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDf05hs909mzFcBmZez2HfiElirxm89cJVmPIB6x63EnErH1gDpEDwkTIA9iNPBx7b9TwraGIktZ/+qQK17aRrHuD9Bd2KoJaZ1+p3slilEP53ub+I/bd/klDYGgXWooxJ4N8H8MBk/xKgB3MLqVMPf54G9hBtfetodWGYSPr/TrwIDAQAB")
                
                let pwd = self?.loginView.codeView.textfield.text ?? ""
                let pwdStr = "rescueApp${\(pwd)}${\(timeInterval)}"
                let clear = try? ClearMessage(string: pwdStr, using: .utf8)
                let encrypted = try? clear?.encrypted(with: publicKey, padding: .PKCS1)
                let base64String = encrypted?.base64String ?? ""

                let str = "{\"username\":\"\(username)\",\"password\":\"\(base64String)\",\"timestamp\":\"\(timeInterval)\",\"clientType\":\"\(clientType)\",\"appVersion\":\"\(appVsersion)\",\"brand\":\"\(brand)\",\"model\":\"\(model)\",\"sdkRelease\":\"\(sdkRelease)\",\"platform\":\"\(platform)\",\"deviceId\":\"\(deviceId)\",\"regId\":\"\(regId)\"}"
                return str
            })
            .flatMapLatest({ app_login_json in
                return RQ.login(parameters: LoginParameters(app_login_json: app_login_json, client_id: true))
            })
            .observe(on: MainScheduler.instance)
            .do(onNext: {[weak self] _ in
                self?.view.dd_hideHUD()
            })
            .observe(on: MainScheduler.instance)
            .subscribe(onNext: {[weak self] responseModel in
                if responseModel?.success == true {
                    if let token = responseModel?.data?.accessToken.tokenValue {
                        USER.setToken(token: token)
                        USER.setRefreshToken(token: responseModel?.data?.refreshToken.tokenValue)
                        USER.setSupplierType(supplierType: responseModel?.data?.additionalParameters.user_info?.supplierType)
                        USER.setPhone(phone: self?.loginView.phoneView.textfield.text)
                        USER.setSupplierName(supplierName: responseModel?.data?.additionalParameters.user_info?.supplierName)
                        USER.setUserId(userId: responseModel?.data?.additionalParameters.user_info?.userId)
                        USER.setSupplierId(supplierId: responseModel?.data?.additionalParameters.user_info?.supplierId)
                        USER.setUsername(username: responseModel?.data?.additionalParameters.user_info?.username)
                    }
                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: Notification_loginSuccessToRescueController), object: nil)
                }else{
                    print("错误")
                    self?.view.dd_makeToast(responseModel?.msg)
                }
            })
            .disposed(by: disposeBag)
    }
}

extension LoginController {
    var agreeButtonBinder : Binder<Bool> {
        return Binder(loginView.agreeButton) { agreeButton, isSelected in
            agreeButton.isSelected = isSelected
        }
    }
}

extension LoginController : UITextViewDelegate {
    public func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        if URL.absoluteString == login_attach_userAgreement_key {
            let vc = WebViewController.init(title: "用户协议",url: "https://www.sinoassist.com/res/protocol/protocol.html")
            navigationController?.pushViewController(vc, animated: true)
        }
        if URL.absoluteString == login_attach_privacy_key {
            let vc = WebViewController.init(title: "隐私协议",url: "https://www.sinoassist.com/res/protocol/driverPrivacy.html")
            navigationController?.pushViewController(vc, animated: true)
        }
        return false
    }
}

class LoginView : DDView {
    public let backgroundImageView : DDImageView
    public let inputContentView : DDView
    public let phoneView : LoginInputView
    public let codeView : LoginInputView
    public let agreeButton : DDButton
    public let agreeTextView : DDTextView
    public let loginButton : DDButton
    override init(frame: CGRect) {
        backgroundImageView = DDImageView.init()
        inputContentView = DDView.init()
        phoneView = LoginInputView.init()
        codeView = LoginInputView.init()
        agreeButton = DDButton.init()
        agreeTextView = DDTextView.init()
        loginButton = DDButton.dd_initCustom()
        super.init(frame: frame)
        
        addSubview(backgroundImageView)
        inputContentView.layer.shadowColor = UIColor.black.alpha(0.3).cgColor
        inputContentView.layer.shadowRadius = 5
        inputContentView.layer.shadowOffset = CGSize(width: 0, height: 0)
        inputContentView.layer.shadowOpacity = 1
        addSubview(inputContentView)
        phoneView.textfield.keyboardType = .default
        inputContentView.addSubview(phoneView)
        codeView.textfield.keyboardType = .default
        inputContentView.addSubview(codeView)
        agreeButton.contentMode = .scaleAspectFill
        inputContentView.addSubview(agreeButton)
        inputContentView.addSubview(agreeTextView)
        loginButton.isEnabled = false
        addSubview(loginButton)
        
        backgroundImageView.snp.makeConstraints { make in
            make.top.left.right.equalToSuperview()
            make.height.equalTo(auto(423))
        }
        
        inputContentView.layer.cornerRadius = auto(10)
        inputContentView.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalTo(backgroundImageView.snp.bottom).offset(-auto(180))
            make.height.equalTo(auto(205))
            make.width.equalTo(auto(340))
        }

        phoneView.snp.makeConstraints { make in
            make.left.right.equalToSuperview()
            make.top.equalToSuperview()
            make.height.equalTo(auto(75))
        }
        
        codeView.snp.makeConstraints { make in
            make.left.right.equalToSuperview()
            make.top.equalTo(phoneView.snp.bottom)
            make.height.equalTo(phoneView)
        }
        
        agreeButton.snp.makeConstraints { make in
            make.top.equalTo(codeView.snp.bottom).offset(auto(20))
            make.left.equalTo(auto(20))
        }
        
        agreeTextView.snp.makeConstraints { make in
            make.centerY.equalTo(agreeButton)
            make.left.equalTo(agreeButton.snp.right).offset(auto(5))
            make.right.equalToSuperview()
            make.height.equalTo(18)
        }
        
        loginButton.layer.cornerRadius = auto(25)
        loginButton.snp.makeConstraints { make in
            make.top.equalTo(inputContentView.snp.bottom).offset(auto(30))
            make.width.equalTo(auto(300))
            make.height.equalTo(auto(50))
            make.centerX.equalToSuperview()
        }
    }
    
    required public init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

class LoginInputView : DDView {
    public let titleLabel : DDLabel
    public let textfield : DDTextField
    public let eyeButton : DDButton
    public let line : DDView
    override init(frame: CGRect) {
        titleLabel = DDLabel.dd_init(withText: "", font: .regularFont(auto(15)), textColor: .hex("203152"))
        textfield = DDTextField.init()
        eyeButton = DDButton.dd_initCustom()
        line = DDView.init()
        line.backgroundColor = .hex("F1F2F5")
        super.init(frame: frame)
        
        addSubview(titleLabel)
        addSubview(textfield)
        eyeButton.isHidden = true
        addSubview(eyeButton)
        addSubview(line)
        
        line.snp.makeConstraints { make in
            make.bottom.equalToSuperview()
            make.left.equalTo(auto(20))
            make.right.equalTo(-auto(20))
            make.height.equalTo(1)
        }
        
        titleLabel.snp.makeConstraints { make in
            make.left.equalTo(line)
            make.top.equalTo(auto(25))
        }
        
        textfield.snp.makeConstraints { make in
            make.left.equalTo(titleLabel)
            make.bottom.equalTo(line.snp.top).offset(-auto(5))
            make.left.equalTo(line)
            make.right.equalTo(eyeButton.snp.left).offset(-auto(5))
        }

        eyeButton.snp.makeConstraints { make in
            make.right.equalToSuperview().offset(-auto(10))
            make.centerY.equalTo(textfield)
            make.width.equalTo(auto(48))
        }
    }
    
    required public init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
