//
// Copyright 2025 Circle Internet Group, Inc. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
//  NumericPinCodeView.swift
//  Pods
//
//  Created by evahsu on 2019/10/17.
//

import UIKit
import CYBAVOWallet

@objc(NumericPinCodeInputView)
class NumericPinCodeInputView: UIView {
    public static let styleAttr: StyleAttr = StyleAttr(
        fixedOrder: false,
        disabled: true,
        buttonWidth: 70,
        buttonHeight: 70,
        horizontalSpacing: 5,
        verticalSpacing: 7,
        buttonTextColor: UIColor.darkGray,
        buttonTextColorPressed: UIColor.lightGray,
        buttonTextColorDisabled: UIColor.red,
        buttonBackgroundColor: UIColor.lightGray,
        buttonBackgroundColorPressed: UIColor.darkGray,
        buttonBackgroundColorDisabled: UIColor.yellow,
        buttonBorderRadius: 33,
        buttonBorderWidth: 0,
        buttonBorderColor: UIColor.green,
        buttonBorderColorPressed: UIColor.blue,
        buttonBorderColorDisabled: UIColor.orange,
        backspaceButtonWidth: 70,
        backspaceButtonHeight: 70,
        backspaceButtonTextColor: UIColor.darkGray,
        backspaceButtonTextColorPressed: UIColor.lightGray,
        backspaceButtonTextColorDisabled: UIColor.yellow,
        backspaceButtonBackgroundColor: UIColor.lightGray,
        backspaceButtonBackgroundColorPressed: UIColor.darkGray,
        backspaceButtonBackgroundColorDisabled: UIColor.red,
        backspaceButtonBorderRadius: 33,
        backspaceButtonBorderWidth: 0,
        backspaceButtonBorderColor: UIColor.blue,
        backspaceButtonBorderColorPressed: UIColor.red,
        backspaceButtonBorderColorDisabled: UIColor.black)

    @objc var bridge: RCTBridge!
    @objc var disabled: Bool = false {
        didSet {
            NumericPinCodeInputView.styleAttr.disabled = disabled
            pinInputView.setDiabled(disabled: disabled)
        }
    }
    @objc var backspaceButtonText: String = "⌫" {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonText = backspaceButtonText
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var keepKey: Bool = false {
        didSet {
            pinInputView.setKeepKey(isKeep: keepKey)
        }
    }
    @objc var maxLength: NSInteger = 0 {
        didSet {
            pinInputView.setMaxLength(length: maxLength)
        }
    }
    @objc var fixedOrder: Bool = false {
        didSet {
            NumericPinCodeInputView.styleAttr.fixedOrder = fixedOrder
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr

        }
    }
    @objc var hapticFeedback: Bool = false {
        didSet {
            pinInputView.setHapticFeedback(hapicFeedback: hapticFeedback)
        }
    }
    @objc var horizontalSpacing: NSInteger = 0 {
        didSet {
            NumericPinCodeInputView.styleAttr.horizontalSpacing = Int(horizontalSpacing)
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
            updateSize()
        }
    }
    @objc var verticalSpacing: NSInteger = 0 {
        didSet {
            NumericPinCodeInputView.styleAttr.verticalSpacing = Int(verticalSpacing)
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
            updateSize()
        }
    }
    @objc var buttonWidth: NSInteger = 70 {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonWidth = buttonWidth
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
            updateSize()
        }
    }
    @objc var buttonHeight: NSInteger = 70 {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonHeight = buttonHeight
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
            updateSize()
        }
    }
    @objc var buttonTextSize: CGFloat = 0 {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonTextFont = UIFont.systemFont(ofSize: buttonTextSize * 35 / 12, weight: UIFont.Weight.thin)
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var buttonTextColor: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonTextColor = buttonTextColor
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var buttonTextColorPressed: UIColor = UIColor.red  {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonTextColorPressed = buttonTextColorPressed
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var buttonTextColorDisabled: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonTextColorDisabled = buttonTextColorDisabled
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var buttonBackgroundColor: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonBackgroundColor = buttonBackgroundColor
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var buttonBackgroundColorPressed: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonBackgroundColorPressed = buttonBackgroundColorPressed
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var buttonBackgroundColorDisabled: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonBackgroundColorDisabled = buttonBackgroundColorDisabled
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var buttonBorderRadius: CGFloat = 0 {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonBorderRadius = buttonBorderRadius
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var buttonBorderWidth: CGFloat = 0 {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonBorderWidth = buttonBorderWidth
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }

    @objc var buttonBorderColor: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonBorderColor = buttonBorderColor
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr}
    }
    @objc var buttonBorderColorPressed: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonBorderColorPressed = buttonBorderColorPressed
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var buttonBorderColorDisabled: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.buttonBorderColorDisabled = buttonBorderColorDisabled
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var androidButtonRippleColor: UIColor = UIColor.red {
        didSet {}
    }

    @objc var backspaceButtonWidth: NSInteger = 0 {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonWidth = backspaceButtonWidth
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var backspaceButtonHeight: NSInteger = 0 {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonHeight = backspaceButtonHeight
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var backspaceButtonTextSize: CGFloat = 0 {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonTextFont = UIFont.systemFont(ofSize: backspaceButtonTextSize * 35 / 12, weight: UIFont.Weight.regular)
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }

    @objc var backspaceButtonTextColor: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonTextColor = backspaceButtonTextColor
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var backspaceButtonTextColorPressed: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonTextColorPressed = backspaceButtonTextColorPressed
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var backspaceButtonTextColorDisabled: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonTextColorDisabled = backspaceButtonTextColorDisabled
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr}
    }
    @objc var backspaceButtonBackgroundColor: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonBackgroundColor = backspaceButtonBackgroundColor
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }

    @objc var backspaceButtonBackgroundColorPressed: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonBackgroundColorPressed = backspaceButtonBackgroundColorPressed
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var backspaceButtonBackgroundColorDisabled: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonBackgroundColorDisabled = backspaceButtonBackgroundColorDisabled
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr}
    }
    @objc var backspaceButtonBorderRadius: CGFloat = 0 {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonBorderRadius = backspaceButtonBorderRadius
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var backspaceButtonBorderWidth: CGFloat = 0 {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonBorderWidth = backspaceButtonBorderWidth
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var backspaceButtonBorderColor: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonBorderColor = backspaceButtonBorderColor
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var backspaceButtonBorderColorPressed: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonBorderColorPressed = backspaceButtonBorderColorPressed
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        }
    }
    @objc var backspaceButtonBorderColorDisabled: UIColor = UIColor.red {
        didSet {
            NumericPinCodeInputView.styleAttr.backspaceButtonBorderColorDisabled = backspaceButtonBorderColorDisabled
            pinInputView.styleAttr = NumericPinCodeInputView.styleAttr}
    }
    @objc var androidBackspaceButtonRippleColor: UIColor = UIColor.red {
        didSet {}
    }
    @objc var onChanged: RCTDirectEventBlock?
    @objc var onSubmit: RCTDirectEventBlock?
    @objc var onSubmitPlain: RCTDirectEventBlock?
    @objc var onStrengthLevel: RCTDirectEventBlock?
    @objc var onSamePin: RCTDirectEventBlock?

    public func clear(){
        pinInputView.clear()
    }
    public func submitPlain(requestId: Int){
        let text = self.pinInputView.submitPlain()
        if let callback = self.onSubmitPlain{
            let dict:[String:Any] = [PinSecretBridge.REQUEST_ID: requestId, PinSecretBridge.PLAIN_TEXT: text]
            callback(dict)
        }
    }
    public func submitForMultiple(requestId: Int){
        let pinSecret = self.pinInputView.submitForMultiple()
        if let callback = self.onSubmit{
            let key = PinSecretBridge.put(pinSecret: pinSecret)
            let dict:[String:Int] = [PinSecretBridge.REQUEST_ID: requestId, PinSecretBridge.PIN_SECRET_KEY: key]
            callback(dict)
        }
    }
    public func submit(requestId: Int){
        let pinSecret = self.pinInputView.submit()
        if let callback = self.onSubmit{
            let key = PinSecretBridge.put(pinSecret: pinSecret)
            let dict:[String:Int] = [PinSecretBridge.REQUEST_ID: requestId, PinSecretBridge.PIN_SECRET_KEY: key]
            callback(dict)
        }
    }
    public func getStrengthLevel(requestId: Int, checkLength: Int){
        let level = self.pinInputView.getStrengthLevel(checkLength: checkLength)
        if let callback = self.onStrengthLevel{
            let dict: [String: Any] = [PinSecretBridge.REQUEST_ID: requestId, PinSecretBridge.LEVEL: level]
            callback(dict)
        }
    }
    public func isSamePin(requestId: Int, pinSecret1: NSDictionary, pinSecret2: NSDictionary){
         guard let pinSecretD1 = PinSecretBridge.fromDictionary(dict: pinSecret1) else{
            if let callback = self.onSamePin{
                let dict:[String:Any] = [PinSecretBridge.REQUEST_ID: requestId, PinSecretBridge.IS_SAME: false]
                callback(dict)
            }
            return
        }
         guard let pinSecretD2 = PinSecretBridge.fromDictionary(dict: pinSecret2) else{
            if let callback = self.onSamePin{
                let dict:[String:Any] = [PinSecretBridge.REQUEST_ID: requestId, PinSecretBridge.IS_SAME: false]
                callback(dict)
            }
            return
        }
        let isSame = self.pinInputView.isSamePin(pinSecret1: pinSecretD1, pinSecret2: pinSecretD2)
        if let callback = self.onSamePin{
            let dict:[String:Any] = [PinSecretBridge.REQUEST_ID: requestId, PinSecretBridge.IS_SAME: isSame]
            callback(dict)
        }
    }
    public var pinInputView: CYBAVOWallet.NumericPinCodeInputView = {
        let pinInputView = CYBAVOWallet.NumericPinCodeInputView()

//        let lightGray = UIColor(red: 227.0/255.0, green: 227.0/255.0, blue: 227.0/255.0, alpha: 1.0)
//        let darkGray = UIColor(red: 59.0/255.0, green: 59.0/255.0, blue: 58.0/255.0, alpha: 1.0)
//        NumericPinCodeInputView.styleAttr.circleBackgroundColor = lightGray
//        NumericPinCodeInputView.styleAttr.tappedTextColor = lightGray
//        NumericPinCodeInputView.styleAttr.indicatorFillColor = lightGray
//        NumericPinCodeInputView.styleAttr.textColor = darkGray
//        NumericPinCodeInputView.styleAttr.tappedColor = darkGray
//        NumericPinCodeInputView.styleAttr.indicatorStrokeColor = darkGray
//        pinInputView.styleAttr = NumericPinCodeInputView.styleAttr
        return pinInputView
    }()
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.frame=frame
        pinInputView.setOnPinInputListener(delegate: self)
        addSubview(pinInputView)

    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    public override func layoutSubviews() {
      updateSize()
    }
    private func updateSize() {
        let width = NumericPinCodeInputView.styleAttr.buttonWidth * 3 + NumericPinCodeInputView.styleAttr.horizontalSpacing * 2
        let height =  NumericPinCodeInputView.styleAttr.buttonHeight * 4 + NumericPinCodeInputView.styleAttr.verticalSpacing * 4
        pinInputView.frame = CGRect(x: 0,
                                  y: 0,
                                    width: width,
                                  height: height)
        bounds = pinInputView.bounds
        bridge.uiManager.setSize(CGSize(width: width, height: height), for: self)
    }
}

extension NumericPinCodeInputView: OnPinInputListener {
    func onChanged(length: Int) {
        if let callback = onChanged{
            let dict:[String:Int] = ["length": length]
            callback(dict)
        }
    }
}
