//
//  RadioButton.swift
//  MVMCoreUI
//
//  Created by Suresh, Kamlesh on 4/25/19.
//  Copyright © 2019 Verizon Wireless. All rights reserved.
//

import UIKit


@objcMembers open class RadioButton: Control, MFButtonProtocol {
    //--------------------------------------------------
    // MARK: - Properties
    //--------------------------------------------------
    
    public var diameter: CGFloat = 30 {
        didSet { widthConstraint?.constant = diameter }
    }
    
    @objc public override var isSelected: Bool {
        didSet {
            radioModel?.state = isSelected
            updateAccessibilityLabel()
        }
    }
    
    public var enabledColor: UIColor = .mvmBlack
    public var disabledColor: UIColor = .mvmCoolGray3
    public var delegateObject: MVMCoreUIDelegateObject?
    var additionalData: [AnyHashable: Any]?
    
    public var radioModel: RadioButtonModel? {
        model as? RadioButtonModel
    }
    
    lazy public var radioGroupName: String? = { radioModel?.fieldKey }()
    
    lazy public var radioButtonSelectionHelper: RadioButtonSelectionHelper? = {
        
        guard let radioGroupName = radioGroupName,
            let radioButtonModel = delegateObject?.formHolderDelegate?.formValidator?.radioButtonsModelByGroup[radioGroupName]
            else { return nil }
        
        return radioButtonModel
    }()
    
    public override var isEnabled: Bool {
        didSet {
            isUserInteractionEnabled = isEnabled
            setNeedsDisplay()
        }
    }
    
    //--------------------------------------------------
    // MARK: - Constraints
    //--------------------------------------------------
    
    public var widthConstraint: NSLayoutConstraint?
    public var heightConstraint: NSLayoutConstraint?
    
    //--------------------------------------------------
    // MARK: - Lifecycle
    //--------------------------------------------------
    
    open override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }
        
        let color = isEnabled == false ? disabledColor.cgColor : enabledColor.cgColor
        layer.cornerRadius = bounds.width * 0.5
        layer.borderColor = color
        layer.borderWidth = bounds.width * 0.0333
        
        if isSelected {
            // Space around inner circle is 1/5 the size
            context.addEllipse(in: CGRect(x: bounds.width * 0.2,
                                          y: bounds.height * 0.2,
                                          width: bounds.width * 0.6,
                                          height: bounds.height * 0.6))
            context.setFillColor(color)
            context.fillPath()
        }
    }
    
    //--------------------------------------------------
    // MARK: - Validation
    //--------------------------------------------------
    
    /// The action performed when tapped.
    func tapAction() {
        if !isEnabled {
            return
        }
        
        let wasPreviouslySelected = isSelected
        if let radioButtonModel = radioButtonSelectionHelper {
            radioButtonModel.selected(self)
        } else {
            isSelected = !isSelected
        }
        
        if let radioModel = radioModel, let actionModel = radioModel.action, isSelected, !wasPreviouslySelected {
            Button.performButtonAction(with: actionModel, button: self, delegateObject: delegateObject, additionalData: additionalData, sourceModel: radioModel)
        }
        
        _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
        setNeedsDisplay()
    }
    
    public func isValidField() -> Bool { isSelected }
    
    public func formFieldName() -> String? {
        radioModel?.fieldKey
    }
    
    public func formFieldGroupName() -> String? {
        radioModel?.fieldKey
    }
    
    public func formFieldValue() -> AnyHashable? {
        guard let radioModel = radioModel, radioModel.enabled else { return nil }
        return radioModel.fieldValue
    }
    
    //--------------------------------------------------
    // MARK: - Methods
    //--------------------------------------------------
    
    /// Adjust accessibility label based on state of RadioButton.
    func updateAccessibilityLabel() {
        if let message = MVMCoreUIUtility.hardcodedString(withKey: "radio_button"),
            let selectedState = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "radio_selected_state" : "radio_not_selected_state") {
            accessibilityLabel = message + selectedState
        }
    }
    
    //--------------------------------------------------
    // MARK: - MVMViewProtocol
    //--------------------------------------------------
    
    open override func setupView() {
        super.setupView()
        
        backgroundColor = .mvmWhite
        clipsToBounds = true
        widthConstraint = widthAnchor.constraint(equalToConstant: 30)
        widthConstraint?.isActive = true
        heightConstraint = heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1)
        heightConstraint?.isActive = true
        
        addTarget(self, action: #selector(tapAction), for: .touchUpInside)
        isAccessibilityElement = true
        accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint")
        accessibilityTraits = .button
        updateAccessibilityLabel()
    }
    
    public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
        super.set(with: model, delegateObject, additionalData)
        self.delegateObject = delegateObject
        self.additionalData = additionalData
        
        guard let model = model as? RadioButtonModel else { return }
        
        isSelected = model.state
        isEnabled = model.enabled && !model.readOnly
        RadioButtonSelectionHelper.setupForRadioButtonGroup(model, self, delegateObject: delegateObject)
    }
    
    public override func reset() {
        super.reset()
        backgroundColor = .mvmWhite
    }
}
