//
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//

import SignalServiceKit
import SignalUI

public class CVComponentReactions: CVComponentBase, CVComponent, CVAccessibilityComponent {

    public var componentKey: CVComponentKey { .reactions }

    private let reactions: CVComponentState.Reactions
    private var reactionState: InteractionReactionState {
        reactions.reactionState
    }
    private var viewState: CVReactionCountsView.State {
        reactions.viewState
    }

    init(itemModel: CVItemModel,
         reactions: CVComponentState.Reactions) {
        self.reactions = reactions

        super.init(itemModel: itemModel)
    }

    public func buildComponentView(componentDelegate: CVComponentDelegate) -> CVComponentView {
        CVComponentViewReactions()
    }

    public func configureForRendering(componentView componentViewParam: CVComponentView,
                                      cellMeasurement: CVCellMeasurement,
                                      componentDelegate: CVComponentDelegate) {
        guard let componentView = componentViewParam as? CVComponentViewReactions else {
            owsFailDebug("Unexpected componentView.")
            componentViewParam.reset()
            return
        }

        let reactionCountsView = componentView.reactionCountsView
        reactionCountsView.configure(state: viewState,
                                     cellMeasurement: cellMeasurement)
    }

    public func measure(maxWidth: CGFloat, measurementBuilder: CVCellMeasurement.Builder) -> CGSize {
        owsAssertDebug(maxWidth > 0)

        return CVReactionCountsView.measure(state: viewState,
                                            measurementBuilder: measurementBuilder)
    }

    // MARK: - Events

    public override func handleTap(sender: UIGestureRecognizer,
                                   componentDelegate: CVComponentDelegate,
                                   componentView: CVComponentView,
                                   renderItem: CVRenderItem) -> Bool {

        guard let message = interaction as? TSMessage else {
            owsFailDebug("Invalid interaction.")
            return false
        }
        componentDelegate.didTapReactions(reactionState: reactionState, message: message)
        return true
    }

    // MARK: - Accessibility

    public var accessibilityDescription: String {
        var fullString = ""
        let pills = [viewState.pill1, viewState.pill2, viewState.pill3].compactMap{ $0 }

        for pill in pills {
            let string: String
            switch pill {
            case .emoji(let emoji, let count, _):
                string = String(
                    format: OWSLocalizedString(
                        "MESSAGE_REACTIONS_ACCESSIBILITY_LABEL_%d",
                        tableName: "PluralAware",
                        comment: "Accessibility label reading out a reaction to a message and its count. Embeds {{ count }} and {{ emoji name }}."
                    ),
                    count,
                    emoji
                )
            case .moreCount(let count, _):
                string = String(
                    format: OWSLocalizedString(
                        "OVERFLOW_REACTIONS_ACCESSIBILITY_LABEL_%d",
                        tableName: "PluralAware",
                        comment: "Accessibility label stating that there are additional reactions to a message that couldn't be displayed. Embeds {{ count of additional reactions }}"
                    ),
                    count
                )
            }
            fullString.append(string)
            fullString.append(" ")
        }

        return fullString
    }

    // MARK: -

    // Used for rendering some portion of an Conversation View item.
    // It could be the entire item or some part thereof.
    public class CVComponentViewReactions: NSObject, CVComponentView {

        fileprivate let reactionCountsView = CVReactionCountsView()

        public var isDedicatedCellView = false

        public var rootView: UIView {
            reactionCountsView
        }

        public func setIsCellVisible(_ isCellVisible: Bool) {}

        public func reset() {
            reactionCountsView.reset()
        }

    }
}
