//
//  ListLeftVariableIconWithRightCaretAllTextLinks.swift
//  MVMCoreUI
//
//  Created by Dhamodaram Nandi on 26/10/20.
//  Copyright © 2020 Verizon Wireless. All rights reserved.
//

@objcMembers open class ListLeftVariableIconWithRightCaretAllTextLinks: TableViewCell {
    //--------------------------------------------------
    // MARK: - Outlets
    //--------------------------------------------------
    
    public let leftImage = LoadImageView(pinnedEdges: .all)
    public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(spacing: 2.0)
    public let rightLabel = Label(fontStyle: .RegularBodySmall)
    
    public lazy var rightLabelStackItem: StackItem = {
        return StackItem(andContain: rightLabel)
    }()
    
    public lazy var stack: Stack<StackModel> = {
        return Stack<StackModel>(with: StackModel(molecules: [StackItemModel(horizontalAlignment: .fill),
                                                              
                                                              StackItemModel(horizontalAlignment: .fill),
                                                              
                                                              StackItemModel(horizontalAlignment: .fill)],
                                                  axis: .horizontal), stackItems: [StackItem(andContain: leftImage), StackItem(andContain: eyebrowHeadlineBodyLink), rightLabelStackItem])
        
    }()
    
    open override func alignAccessoryToHero() -> CGPoint? {
        // Ensures that the right label is centered vertically with headline.
        let heroCenter = super.alignAccessoryToHero()
        if let heroCenter = heroCenter {
            let convertedPoint = stack.convert(heroCenter, from: self)
            rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - stack.bounds.midY
        }
        return heroCenter
    }
    
    //-----------------------------------------------------
    // MARK: - View Lifecycle
    //--------------------------------------------------
    
    override open func setupView() {
        super.setupView()
        
        leftImage.addSizeConstraintsForAspectRatio = true
        leftImage.contentMode = .scaleAspectFit
        rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
        rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal)
        addMolecule(stack)
        stack.restack()
    }
    
    //--------------------------------------------------
    // MARK: - Molecule
    //---------------------------------------------------
    
    open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
        super.set(with: model, delegateObject, additionalData)
        
        guard let model = model as? ListLeftVariableIconWithRightCaretAllTextLinksModel else { return }
        
        leftImage.set(with: model.image, delegateObject, additionalData)
        eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
        rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
        updateAccessibilityLabel()
    }
    
    open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
        return 90
    }
    
    open override func reset() {
        super.reset()
        rightLabel.setFontStyle(.RegularBodySmall)
    }
    
    //--------------------------------------------------
    // MARK: - Accessibility
    //--------------------------------------------------
    
    func getAccessibilityMessage() -> String? {
        var message = ""
        if let leftImageLabel = leftImage.imageView.accessibilityLabel {
            message += leftImageLabel + ", "
        }
        if let label = eyebrowHeadlineBodyLink.getAccessibilityMessage() {
            message += label + ", "
        }
        if let rightLabel = rightLabel.text  {
            message += rightLabel
        }
        return message
    }
    
    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] = []
            elements.append(leftImage.imageView)
            if let otherElements = eyebrowHeadlineBodyLink.getAccessibilityElements() {
                elements.append(otherElements)
            }
            if let rightLabelText = rightLabel.text, !rightLabelText.isEmpty {
                elements.append(rightLabel)
            }
            accessibilityElements = elements
        }
    }
}

