//
//  ListRightVariablePriceChangeAllTextAndLinks.swift
//  MVMCoreUI
//
//  Created by Kruthika KP on 13/04/20.
//  Copyright © 2020 Verizon Wireless. All rights reserved.
//


@objcMembers open class ListRightVariablePriceChangeAllTextAndLinks: TableViewCell {
    //-----------------------------------------------------
    // MARK: - Outlets
    //-----------------------------------------------------
    
    public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink()
    public let arrow = Arrow()
    public let rightLabel = Label(fontStyle: .RegularBodySmall)
    private let stack: Stack<StackModel>
    private let arrowStackItem: StackItem
    private let rightLabelStackItem: StackItem
    
    //-----------------------------------------------------
    // MARK: - Initializers
    //-----------------------------------------------------
    
    public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading),
                                                StackItemModel(horizontalAlignment: .fill),
                                                StackItemModel(spacing: 6, horizontalAlignment: .fill)],
                                    axis: .horizontal)
        arrowStackItem = StackItem(andContain: arrow)
        rightLabelStackItem = StackItem(andContain: rightLabel)
        let stackItems = [StackItem(andContain: eyebrowHeadlineBodyLink), arrowStackItem, rightLabelStackItem]
        stack = Stack<StackModel>(with: stackModel, stackItems: stackItems)
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }
    
    public required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //-----------------------------------------------------
    // MARK: - Lifecycle
    //-----------------------------------------------------
    
    open override func alignAccessoryToHero() -> CGPoint? {
        let heroCenter = super.alignAccessoryToHero()
        
        // Aligns the center of the right side items to the headline.
        if let heroCenter = heroCenter {
            let convertedPoint = stack.convert(heroCenter, from: self)
            arrowStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY
            rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY
        }
        
        return heroCenter
    }
    
    open override func setupView() {
        super.setupView()
        
        rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
        rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal)
        addMolecule(stack)
        stack.restack()
    }
    
    open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
        super.set(with: model, delegateObject, additionalData)
        
        guard let model = model as? ListRightVariablePriceChangeAllTextAndLinksModel else { return }
        
        eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
        rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
        arrow.set(with: model.arrow, delegateObject, additionalData)
        updateAccessibilityLabel()
    }
    
    open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
        return 121
    }
    
    //--------------------------------------------------
    // MARK: - Accessibility
    //--------------------------------------------------
    func getAccessibilityMessage() -> String? {
        
        guard let rightLabelText = rightLabel.text else {
            return eyebrowHeadlineBodyLink.getAccessibilityMessage()
        }
        
        guard let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() else {
            return rightLabelText
        }
        
        return label + ", " + rightLabelText
    }
    
    func updateAccessibilityLabel() {
        
        let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
        isAccessibilityElement = !linkShowing
        accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none
        
        if !linkShowing {
            // Make whole cell focusable if no link.
            accessibilityLabel = getAccessibilityMessage()
        } else if let accessoryView = accessoryView {
            // Both caret and link. Read all content on caret.
            accessoryView.accessibilityLabel = getAccessibilityMessage()
            accessibilityElements = [accessoryView, eyebrowHeadlineBodyLink.link]
        } else {
            // Only link. Manually add accessibility elements to ensure they are read in the right order.
            var elements: [Any] = []
            
            if let otherElements = eyebrowHeadlineBodyLink.getAccessibilityElements() {
                elements.append(otherElements)
            }
            
            if let rightLabelText = rightLabel.text, !rightLabelText.isEmpty {
                elements.append(rightLabel)
            }
            
            accessibilityElements = elements
        }
    }
}
