//
//  ProgressBarView.swift
//  MVMCoreUI
//
//  Created by Panth Patel on 5/3/19.
//  Copyright © 2019 Verizon Wireless. All rights reserved.
//

import UIKit

@objcMembers public class CornerLabels: View {
    var middleView: UIView?
    let topLeftLabel = Label(fontStyle: .BoldBodySmall)
    let topRightLabel = Label(fontStyle: .BoldBodySmall)
    let bottomLeftLabel = Label(fontStyle: .RegularMicro)
    let bottomRightLabel = Label(fontStyle: .RegularMicro)
    let topLabelsView = MVMCoreUICommonViewsUtility.commonView()
    let bottomLabelsView = MVMCoreUICommonViewsUtility.commonView()
    
    /// The space between the molecule and top labels. Set to 0 if the top labels or molecule are not set.
    var spaceAboveMolecule: CGFloat = 6.0 {
        didSet {
            if spaceAboveMolecule != oldValue {
                topLabelToMoleculeConstraint?.constant = spaceAboveMolecule
            }
        }
    }
    
    /// The space between the molecule and bottom labels. Set to 0 if the bottom labels or molecule are not set.
    var spaceBelowMolecule: CGFloat = 6.0 {
        didSet {
            if spaceBelowMolecule != oldValue {
                bottomLabelToMoleculeConstraint?.constant = spaceBelowMolecule
            }
        }
    }
    
    var topLabelToMoleculeConstraint: NSLayoutConstraint?
    var bottomLabelToMoleculeConstraint: NSLayoutConstraint?
    
    public func addMiddleView(_ view: UIView) {
        insertSubview(view, at: 0)
        topLabelToMoleculeConstraint?.isActive = false
        bottomLabelToMoleculeConstraint?.isActive = false
        
        view.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor).isActive = true
        layoutMarginsGuide.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        
        topLabelToMoleculeConstraint = view.topAnchor.constraint(equalTo: topLabelsView.bottomAnchor, constant: spaceAboveMolecule)
        topLabelToMoleculeConstraint?.isActive = true
        bottomLabelToMoleculeConstraint = bottomLabelsView.topAnchor.constraint(equalTo: view.bottomAnchor, constant: spaceBelowMolecule)
        bottomLabelToMoleculeConstraint?.isActive = true
        self.middleView = view
    }

    // MARK: - MVMCoreViewProtocol
    open override func updateView(_ size: CGFloat) {
        super.updateView(size)
        topLeftLabel.updateView(size)
        topRightLabel.updateView(size)
        bottomLeftLabel.updateView(size)
        bottomRightLabel.updateView(size)
        (middleView as? MVMCoreViewProtocol)?.updateView(size)
    }
    
    public override func setupView() {
        super.setupView()
        guard topLeftLabel.superview == nil else {
            return
        }
        
        topRightLabel.textAlignment = .right
        bottomRightLabel.textAlignment = .right

        addSubview(topLabelsView)
        addSubview(bottomLabelsView)
        topLabelsView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true
        topLabelsView.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor).isActive = true
        layoutMarginsGuide.rightAnchor.constraint(equalTo: topLabelsView.rightAnchor).isActive = true
        
        topLabelToMoleculeConstraint = bottomLabelsView.topAnchor.constraint(equalTo: topLabelsView.bottomAnchor, constant: 0)
        topLabelToMoleculeConstraint?.isActive = true
        bottomLabelToMoleculeConstraint = topLabelToMoleculeConstraint
        
        bottomLabelsView.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor).isActive = true
        layoutMarginsGuide.rightAnchor.constraint(equalTo: bottomLabelsView.rightAnchor).isActive = true
        layoutMarginsGuide.bottomAnchor.constraint(equalTo: bottomLabelsView.bottomAnchor).isActive = true
        
        topLabelsView.addSubview(topLeftLabel)
        topLabelsView.addSubview(topRightLabel)
        setCompetitionConstraints(topLeftLabel,topRightLabel)
        
        bottomLabelsView.addSubview(bottomLeftLabel)
        bottomLabelsView.addSubview(bottomRightLabel)
        setCompetitionConstraints(bottomLeftLabel,bottomRightLabel)

        topLeftLabel.topAnchor.constraint(equalTo: topLabelsView.topAnchor).isActive = true
        topLeftLabel.leftAnchor.constraint(equalTo: topLabelsView.leftAnchor).isActive = true
        topLabelsView.bottomAnchor.constraint(greaterThanOrEqualTo: topLeftLabel.bottomAnchor).isActive = true
        topRightLabel.topAnchor.constraint(equalTo: topLabelsView.topAnchor).isActive = true
        topLabelsView.rightAnchor.constraint(equalTo: topRightLabel.rightAnchor).isActive = true
        topLabelsView.bottomAnchor.constraint(greaterThanOrEqualTo: topRightLabel.bottomAnchor).isActive = true

        var constraint = topLabelsView.bottomAnchor.constraint(equalTo: topLeftLabel.bottomAnchor)
        constraint.priority = topLeftLabel.contentHuggingPriority(for: .vertical) - 10
        constraint.isActive = true
        
        constraint = topLabelsView.bottomAnchor.constraint(equalTo: topRightLabel.bottomAnchor)
        constraint.priority = topRightLabel.contentHuggingPriority(for: .vertical) - 10
        constraint.isActive = true
        
        topRightLabel.leftAnchor.constraint(equalTo: topLeftLabel.rightAnchor, constant: 16).isActive = true
        
        bottomLeftLabel.topAnchor.constraint(equalTo: bottomLabelsView.topAnchor).isActive = true
        bottomLeftLabel.leftAnchor.constraint(equalTo: bottomLabelsView.leftAnchor).isActive = true
        bottomLabelsView.bottomAnchor.constraint(greaterThanOrEqualTo: bottomLeftLabel.bottomAnchor).isActive = true
        bottomRightLabel.topAnchor.constraint(equalTo: bottomLabelsView.topAnchor).isActive = true
        bottomRightLabel.rightAnchor.constraint(equalTo: bottomLabelsView.rightAnchor).isActive = true
        bottomLabelsView.bottomAnchor.constraint(greaterThanOrEqualTo: bottomRightLabel.bottomAnchor).isActive = true
        
        constraint = bottomLabelsView.bottomAnchor.constraint(equalTo: bottomLeftLabel.bottomAnchor)
        constraint.priority = bottomLeftLabel.contentHuggingPriority(for: .vertical) - 10
        constraint.isActive = true
        
        constraint = bottomLabelsView.bottomAnchor.constraint(equalTo: bottomRightLabel.bottomAnchor)
        constraint.priority = bottomRightLabel.contentHuggingPriority(for: .vertical) - 10
        constraint.isActive = true
        
        bottomRightLabel.leftAnchor.constraint(greaterThanOrEqualTo: bottomLeftLabel.rightAnchor, constant: 16).isActive = true
    }
    
    /// Sets the rules for the labels if they were to collide. The first view will take priority, but the second view has a minimum width when competing.
    func setCompetitionConstraints(_ view1: UIView,_ view2: UIView) {
        view1.setContentHuggingPriority(UILayoutPriority(rawValue: 700), for: .horizontal)
        view2.setContentHuggingPriority(UILayoutPriority(rawValue: 750), for: .horizontal)
        view1.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 350), for: .horizontal)
        view2.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 300), for: .horizontal)
        let width = view2.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.40)
        width.priority = UILayoutPriority(rawValue: 400)
        width.isActive = true
    }
    
    // MARK: - MoleculeViewProtocol
    public override func reset() {
        super.reset()
        
        styleDefault()
        spaceAboveMolecule = 6.0
        spaceBelowMolecule = 6.0
        (middleView as? MoleculeViewProtocol)?.reset()
    }
    
    func styleDefault() {
        topLeftLabel.setFontStyle(.BoldBodySmall)
        topRightLabel.setFontStyle(.BoldBodySmall)
        bottomLeftLabel.setFontStyle(.RegularMicro)
        bottomRightLabel.setFontStyle(.RegularMicro)
    }
    
    public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
        return 34
    }

    public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
        super.set(with: model, delegateObject, additionalData)
        guard let model = model as? CornerLabelsModel else { return }
        if let moleculeModel = model.molecule {
            if middleView != nil {
                (middleView as? MoleculeViewProtocol)?.set(with: moleculeModel, delegateObject, additionalData)
            } else if let molecule = ModelRegistry.createMolecule(moleculeModel, delegateObject: delegateObject, additionalData: additionalData) {
                addMiddleView(molecule)
            }
        }
        
        topLeftLabel.setOptional(with: model.topLeftLabel, delegateObject, additionalData)
        topRightLabel.setOptional(with: model.topRightLabel, delegateObject, additionalData)
        bottomLeftLabel.setOptional(with: model.bottomLeftLabel, delegateObject, additionalData)
        bottomRightLabel.setOptional(with: model.bottomRightLabel, delegateObject, additionalData)
        
        topLabelToMoleculeConstraint?.constant = (middleView != nil && (topLeftLabel.hasText || topRightLabel.hasText)) ? spaceAboveMolecule : 0
        bottomLabelToMoleculeConstraint?.constant = (middleView != nil && (bottomLeftLabel.hasText || bottomRightLabel.hasText)) ? spaceBelowMolecule : 0
    }
}
