//
//  KMVerificationCodeView.swift
//  PDF Reader Pro
//
//  Created by lizhe on 2023/2/23.
//

import Cocoa

typealias KMVerificationCodeViewCancelAction = (_ view: KMVerificationCodeView) -> Void
typealias KMVerificationCodeViewVerificationCodeAction = (_ view: KMVerificationCodeView, _ data: KMRegisterModel, _ codeString: String) -> Void
typealias KMVerificationCodeViewDoneAction = (_ view: KMVerificationCodeView, _ data: KMRegisterModel, _ sender: NSButton) -> Void
typealias KMVerificationCodeViewCloseAction = (_ view: KMVerificationCodeView) -> Void
typealias KMVerificationCodeViewReSendAction = (_ view: KMVerificationCodeView, _ sender: NSTextView) -> Void
class KMVerificationCodeView: KMBaseXibView {

    @IBOutlet weak var titleLabel: NSTextField!
    @IBOutlet weak var describeLabel: NSTextField!
    @IBOutlet var timerTextView: NSTextView!
    
    @IBOutlet weak var cancellationButton: NSButton!
    @IBOutlet weak var cancelButton: NSButton!
    @IBOutlet weak var closeButton: NSButton!
    
    @IBOutlet weak var textFieldContentView: NSView!
    @IBOutlet weak var code1ContentView: NSView!
    @IBOutlet weak var code1TextField: KMBaseTextField!
    
    @IBOutlet weak var code2ContentView: NSView!
    @IBOutlet weak var code2TextField: KMBaseTextField!
    
    @IBOutlet weak var code3ContentView: NSView!
    @IBOutlet weak var code3TextField: KMBaseTextField!
    
    @IBOutlet weak var code4ContentView: NSView!
    @IBOutlet weak var code4TextField: KMBaseTextField!
    
    @IBOutlet weak var code5ContentView: NSView!
    @IBOutlet weak var code5TextField: KMBaseTextField!
    
    @IBOutlet weak var code6ContentView: NSView!
    @IBOutlet weak var code6TextField: KMBaseTextField!
    
    @IBOutlet weak var doneButtonTopConstraint: NSLayoutConstraint!
    @IBOutlet weak var alertView: KMLightMemberAlertView!
    
    @IBOutlet weak var alertHeightConstraint: NSLayoutConstraint!
    @IBOutlet weak var closeBox: KMBox!
    
    var cancellationButtonVC: KMDesignButton!
    var cancelButtonVC: KMDesignButton!
    
    var cancelAction: KMVerificationCodeViewCancelAction?
    var doneAction: KMVerificationCodeViewDoneAction?
    var closeAction: KMVerificationCodeViewCloseAction?
    var reSendAction: KMVerificationCodeViewReSendAction?
    var verificationCodeAction: KMVerificationCodeViewVerificationCodeAction?
    
    var timer: Timer?
    var time: Int = -1
    let startTime = 60
    //验证码
    var verificationCode: String {
        get {
            return self.code1TextField.textField.stringValue + self.code2TextField.textField.stringValue + self.code3TextField.textField.stringValue + self.code4TextField.textField.stringValue + self.code5TextField.textField.stringValue + self.code6TextField.textField.stringValue
        }
    }
    var verificationCodeState: KMRequestServerErrorCodeType = .unknown
    var inputType: KMRegisterLogType = .login {
        didSet {
            switch self.inputType {
            case .register:
                self.verifyCodeType = .register
            case .loginInputPassword:
                self.verifyCodeType = .resetPassword
            case .accountInfo:
                self.verifyCodeType = .logOff
            default:
                KMPrint("")
            }
            
            self.cleanVerificationCode()
            self.reloadData()
            self.updateLanguage()
        }
    }
    
    var verifyCodeType: KMVerifyCodeType = .unknown {
        didSet {
            self.reloadData()
            self.updateLanguage()
        }
    }
    
    var isNetworking: Bool = false //是否正在进行网络请求
    var codeIsTrue: Bool = false //验证码是否正确
    var model: KMRegisterModel = KMRegisterModel()
    
    deinit {
        self.endTimer()
        KMPrint("KMVerificationCodeView dealloc")
    }
    
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    }
    
    override func setup() {
        super.setup()
        
        self.backgroundColor(NSColor.km_init(hex: "#FFFFFF"))
        
        self.titleLabel.font = NSFont.SFProTextSemiboldFont(20.0)
        self.titleLabel.textColor = NSColor.km_init(hex: "#252629")
        
        self.describeLabel.font = NSFont.SFProTextRegularFont(14.0)
        self.describeLabel.textColor = NSColor.km_init(hex: "#252629")
        
        self.timerTextView.delegate = self
        self.timerTextView.frame = (self.timerTextView.enclosingScrollView?.contentView.bounds)!
        self.timerTextView.autoresizingMask = [.width, .height]
        
        let textFieldArray = [self.code1TextField,self.code2TextField,self.code3TextField,self.code4TextField,self.code5TextField,self.code6TextField]
        
        for i in 0...textFieldArray.count - 1 {
            let textField = textFieldArray[i]
            if textField != nil {
                textField!.textField.textColor = NSColor.km_init(hex: "#252629")
                textField!.textField.font = NSFont.SFProTextSemiboldFont(20.0)
                textField?.maxLen = 1
                textField?.model.isCanNull = true
                textField?.textField.tag = i + 10
                textField!.textField.alignment = .center
                textField?.superview?.border(NSColor.km_init(hex: "#DFE1E5"), 1, 2)
                textField?.textField.onFocus = { [unowned self] in
                    self.cancelAllTextFieldFouce()
                    textField?.superview?.border(NSColor.km_init(hex: "#1770F4"), 1, 2)
                }
                
                textField?.textDidEndEditing = { [unowned self] string in
                    textField?.superview?.border(NSColor.km_init(hex: "#DFE1E5"), 1, 2)
                }
                
                textField?.textDidChange = { [unowned self] string in
                    //自动验证验证码
                    self.autoVerificationCode()
                    
                    var isNext = true
                    if string == "" {
                        isNext = false
                    }
                    for item in textFieldArray {
                        let t = textField?.textField
                        var tag = t!.tag + 1
                        if !isNext {
                            tag = t!.tag - 1
                        }
                        tag = max(10, tag)
                        if item?.textField.tag == tag {
                            item?.textField.becomeFirstResponder()
                            item?.superview?.border(NSColor.km_init(hex: "#1770F4"), 1, 2)
                            break
                        }
                    }
                }
                
                textField?.textDeleteAction = { [unowned self] string in
                    if string == "" {
                        for item in textFieldArray {
                            let t = textField?.textField
                            let tag = max(10, t!.tag - 1)

                            if item?.textField.tag == tag {
                                item?.textField.becomeFirstResponder()
                                item?.superview?.border(NSColor.km_init(hex: "#1770F4"), 1, 2)
                                break
                            }
                        }
                    }
                }
            }
        }
        
        self.cancellationButtonVC = KMDesignButton(withType: .Text)
        self.cancellationButton.addSubview(self.cancellationButtonVC.view)
        self.cancellationButtonVC?.view.frame = self.cancellationButton.bounds
        self.cancellationButtonVC.target = self
        self.cancellationButtonVC.action = #selector(doneButtonAction)
        self.cancellationButtonVC.button(type: .Cta, size: .m)
        self.cancellationButtonVC.button.keyEquivalent = KMKeyEquivalent.enter
        
        self.cancelButtonVC = KMDesignButton(withType: .Text)
        self.cancelButton.addSubview(self.cancelButtonVC.view)
        self.cancelButtonVC?.view.frame = self.cancelButton.bounds
        self.cancelButtonVC.target = self
        self.cancelButtonVC.action = #selector(cancelButtonAction)
        self.cancelButtonVC.button(type: .Sec, size: .m)
        self.cancelButtonVC.button.keyEquivalent = KMKeyEquivalent.enter
        
        self.closeBox.moveCallback = { [weak self] (mouseEntered, mouseBox) in
            if mouseEntered {
                self?.closeButton.image = NSImage(named: "control_btn_icon_close_hov")
            } else {
                self?.closeButton.image = NSImage(named: "control_btn_icon_close")
            }
        }
    }
    
    override func reloadData() {
        super.reloadData()
        
        if inputType == .accountInfo {
            self.closeButton.isHidden = false
            self.cancelButtonVC.button(type: .Sec, size: .m)
            self.cancelButtonVC.updateUI()
        } else {
            self.closeButton.isHidden = true
            self.cancelButtonVC.button(type: .Text, size: .m)
            self.cancelButtonVC.updateUI()
        }
        
        let textFieldArray = [self.code1TextField,self.code2TextField,self.code3TextField,self.code4TextField,self.code5TextField,self.code6TextField]
        for item in textFieldArray {
            item?.isEnabled = !self.isNetworking
        }
        
        if self.verificationCode.count == 6 &&
//            self.time != -1 &&
            self.codeIsTrue {
            self.cancellationButtonVC.enabled = true
        } else {
            self.cancellationButtonVC.enabled = false
            self.showAlert(result: Result(code: 0))
        }
    }
    
    override func updateLanguage() {
        super.updateLanguage()
        
        if self.verifyCodeType == .unknown {
            self.titleLabel.stringValue = ""
        } else if self.verifyCodeType == .register {
            self.titleLabel.stringValue = NSLocalizedString("Sign Up", comment: "")
        } else if self.verifyCodeType == .logOff {
            self.titleLabel.stringValue = NSLocalizedString("Cancel Account", comment: "")
        } else if self.verifyCodeType == .resetPassword {
            self.titleLabel.stringValue = NSLocalizedString("Reset Password", comment: "")
        }
        
        self.describeLabel.stringValue = NSLocalizedString("Enter the verification code", comment: "")
        
        if inputType == .unknown {
            self.cancelButtonVC.stringValue = ""
        } else if inputType == .accountInfo {
            self.cancelButtonVC.stringValue = NSLocalizedString("Cancel", comment: "")
        } else {
            self.cancelButtonVC.stringValue = NSLocalizedString("Back to previous step", comment: "")
        }
        
        if self.verifyCodeType == .unknown {
            self.cancellationButtonVC.stringValue = ""
        } else if self.verifyCodeType == .register {
            self.cancellationButtonVC.stringValue = NSLocalizedString("Sign Up", comment: "")
        } else if self.verifyCodeType == .logOff {
            self.cancellationButtonVC.stringValue = NSLocalizedString("Cancellation", comment: "")
        } else if self.verifyCodeType == .resetPassword {
            self.cancellationButtonVC.stringValue = NSLocalizedString("Next Step", comment: "")
        }
        
        
        let tempTime: String = String(self.time)
        var timeString = "(" + tempTime + NSLocalizedString("s", comment: "") + ")"
        if tempTime == "60" {
            timeString = NSLocalizedString("Click to resend", comment: "")
        } else if tempTime == "-1" {
            timeString = " "
        }
        //singin
        let string = NSLocalizedString("Didn't receive the verification code?", comment: "") + "  " + timeString
        let attributedString = NSMutableAttributedString.init(string: string)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = .left;
        attributedString.addAttributes([NSAttributedString.Key.font : NSFont.SFProTextRegularFont(12.0),
                                        NSAttributedString.Key.foregroundColor : NSColor.km_init(hex: "#252629"),
                                        NSAttributedString.Key.paragraphStyle : paragraphStyle],
                                    range: NSRange(location: 0, length: string.count))

        let range = string.range(of: NSLocalizedString(timeString, comment: ""))
        attributedString.setAttributes([NSAttributedString.Key.font : NSFont.SFProTextRegularFont(12.0),
                                        NSAttributedString.Key.foregroundColor : NSColor.km_init(hex: "#1770F4"),
                                        NSAttributedString.Key.underlineColor : NSColor.clear,
                                        NSAttributedString.Key.link : "timer://"],
                                       range: string.nsRange(from: range!)!)

        self.timerTextView.textStorage?.setAttributedString(attributedString)
        
    }
    
    func cleanVerificationCode() {
        let textFieldArray = [self.code1TextField,self.code2TextField,self.code3TextField,self.code4TextField,self.code5TextField,self.code6TextField]
        for item in textFieldArray {
            item?.stringValue = ""
            item?.textField.resignFirstResponder()
            
            if item != self.code1TextField {
                item?.superview?.border(NSColor.km_init(hex: "#DFE1E5"), 1, 2)
            }
        }
        self.model.verifyCode = ""
    }
    
    //验证码请求完成
    func updateNetworkingState(complete: Bool, codeIsTure: Bool) {
        self.isNetworking = !complete
        self.codeIsTrue = codeIsTure
        self.reloadData()
        if !codeIsTure {
            self.code6TextField.textField.becomeFirstResponder()
        }
    }
    
    //自动验证验证码
    func autoVerificationCode() {
        let textFieldArray = [self.code1TextField,self.code2TextField,self.code3TextField,self.code4TextField,self.code5TextField,self.code6TextField]
        for item in textFieldArray {
            item?.textField.resignFirstResponder()
        }
        
        if self.verificationCode.count == 6 {
            if self.verificationCodeAction != nil {
                self.isNetworking = true
                self.model.verifyCode = self.verificationCode
                self.verificationCodeAction!(self, self.model, self.verificationCode)
            }
        }
    }
}

protocol KMVerificationCodeViewTimer {}
extension KMVerificationCodeView: KMVerificationCodeViewTimer {
    func cleanTimer() {
        self.time = startTime
        self.updateLanguage()
    }
    
    func resetTimer() {
        self.time = startTime
        self.beginTimer()
        self.updateTimerData(timer: self.timer!)
    }
    
    func beginTimer() {
        if self.timer != nil {
            self.endTimer()
        }
        if self.time == -1 {
            self.time = startTime
        }
        self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTimerData), userInfo: nil, repeats: true)
    }
    
    func endTimer() {
        self.timer?.invalidate()
        self.timer = nil
        self.updateLanguage()
    }
    
    @objc func updateTimerData(timer: Timer) {
        self.time -= 1
        if self.time == 0 {
            self.endTimer()
            self.time = startTime
        }
        self.updateLanguage()
    }
}

protocol KMVerificationCodeViewAction {}
extension KMVerificationCodeView: KMVerificationCodeViewAction {
    func sendVerificationCode() {
        guard let callBack = reSendAction else { return }
        self.timerTextView.isSelectable = false
        callBack(self, self.timerTextView)
    }
    
    @IBAction func cancelButtonAction(_ sender: NSButton) {
        self.endTimer()
        guard let callBack = cancelAction else { return }
        
        callBack(self)
    }
    
    @IBAction func doneButtonAction(_ sender: NSButton) {
        guard let callBack = doneAction else { return }
        self.model.verifyCode = self.verificationCode
        
        self.changeDoneButtonState(enable: false)
        callBack(self, self.model, sender)
    }
    
    @IBAction func closeButtonAction(_ sender: Any) {
        guard let callBack = closeAction else { return }
        self.endTimer()
        callBack(self)
    }
    
    func showAlert(result: Result?) {
        if result != nil {
            self.alertView.result = result!
            self.alertHeightConstraint.constant = self.alertView.fetchAlertHeight()
            
            if result?.code != 0 && result?.code != 200 {
                self.textFieldAlert()
            }
        }
    }
    
    func changeDoneButtonState(enable: Bool) {
        self.cancellationButtonVC.enabled = enable
    }
    
    func cancelAllTextFieldFouce() {
        let textFieldArray = [self.code1TextField,self.code2TextField,self.code3TextField,self.code4TextField,self.code5TextField,self.code6TextField]
        for item in textFieldArray {
            item?.superview?.border(NSColor.km_init(hex: "#DFE1E5"), 1, 2)
        }
    }
    
    func textFieldAlert() {
        let textFieldArray = [self.code1TextField,self.code2TextField,self.code3TextField,self.code4TextField,self.code5TextField,self.code6TextField]
        for item in textFieldArray {
            item?.superview?.border(NSColor.red, 1, 2)
        }
    }
}

extension KMVerificationCodeView: NSTextViewDelegate {
    func textView(_ textView: NSTextView, clickedOnLink link: Any, at charIndex: Int) -> Bool {
        if link as! String == "timer://" && self.time == 60 {
            guard let callBack = reSendAction else { return true }
            textView.isSelectable = false
            callBack(self, textView)
        }
        return true
    }
}

extension KMVerificationCodeView: NSTextFieldDelegate {
    func controlTextDidEndEditing(_ obj: Notification) {
        KMPrint("controlTextDidEndEditing")
        let textField = obj.object as? NSTextField
        for view in self.textFieldContentView.subviews {
            let t = view.subviews.first as? FocusAwareTextField
            if t == textField {
                view.border(NSColor.km_init(hex: "#DFE1E5"), 1, 4)
            }
        }
    }
}

extension KMVerificationCodeView {
    override var acceptsFirstResponder: Bool {
            return true
        }
        
    override func performKeyEquivalent(with event: NSEvent) -> Bool {
        if event.type == .keyDown, event.modifierFlags.contains(.command), event.characters == "v" {
            if let pasteboardString = NSPasteboard.general.string(forType: .string) {
                KMPrint(pasteboardString)
                if let num = Int(pasteboardString) {
                    let textFieldArray = [self.code1TextField,self.code2TextField,self.code3TextField,self.code4TextField,self.code5TextField,self.code6TextField]
                    for index in 0...textFieldArray.count - 1 {
                        if index < pasteboardString.count {
                            let textField = textFieldArray[index]
                            let fifthChar = pasteboardString[pasteboardString.index(pasteboardString.startIndex, offsetBy: index)]
                            textField?.textField.stringValue = String(fifthChar)
                            textField?.stringValue = String(fifthChar)
                            textField?.textField.becomeFirstResponder()
                        }
                    }
                    if pasteboardString.count == 6 {
                        self.autoVerificationCode()
                    }
                }
                // 处理剪贴板中的字符串
                return true
            }
        }
        return super.performKeyEquivalent(with: event)
    }
}