//
//  ListRightVariableRightCaretAlltextAndLinks.swift
//  MVMCoreUI
//
//  Created by Lekshmi S on 23/07/20.
//  Copyright © 2020 Verizon Wireless. All rights reserved.
//


@objcMembers open class ListRightVariableRightCaretAllTextAndLinks: TableViewCell {
    //--------------------------------------------------
    // MARK: - Outlets
    //--------------------------------------------------
    
    public let rightLabel = Label(fontStyle: .RegularBodySmall)
    public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink()
    public var stack: Stack<StackModel>
    
    //--------------------------------------------------
    // MARK: - Initializers
    //--------------------------------------------------
    
    public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        // Fill for left vertical alignment because bottom constraint was breaking with leading. CXTDT-145456
        stack = Stack<StackModel>.createStack(with: [(view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading, verticalAlignment: .fill)), (view: rightLabel, model: StackItemModel(horizontalAlignment: .trailing, verticalAlignment: .leading))], axis: .horizontal)
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }
    
    public required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //-----------------------------------------------------
    // MARK: - Lifecycle
    //-----------------------------------------------------
    
    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 alignAccessoryToHero() -> CGPoint? {
        let heroCenter = super.alignAccessoryToHero()
        
        // Aligns the center of the right side items to the headline.
        if let heroCenter = heroCenter,
            let stackItem = stack.stackItems.last as? StackItem {
            let convertedPoint = stack.convert(heroCenter, from: self)
            stackItem.containerHelper.topConstraint?.constant = max(convertedPoint.y - rightLabel.bounds.midY, 0.0)
        }
        
        return heroCenter
    }
    
    //--------------------------------------------------
    // MARK: - Molecular
    //--------------------------------------------------
    
    open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
        super.set(with: model, delegateObject, additionalData)
        
        guard let model = model as? ListRightVariableRightCaretAllTextAndLinksModel else { return }
        rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
        eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
        updateAccessibilityLabel()
    }
    
    open override func reset() {
        super.reset()
        rightLabel.setFontStyle(.RegularBodySmall)
    }
    
    open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
        return 90
    }
    
    //--------------------------------------------------
    // 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
        }
    }
}
