import UIKit

// MARK: - ChatMessageListItem

/// Bridges ChatMessage + pre-calculated layout to RosettaListView.
/// Telegram equivalent: ChatMessageItemImpl.
///
/// Layout is pre-calculated by LayoutEngine (background thread).
/// This class just holds the results and creates/configures nodes.
final class ChatMessageListItem: RosettaListItem {

    let message: ChatMessage
    let layout: MessageCellLayout
    let textLayout: CoreTextTextLayout?
    let timestampText: String
    let actions: MessageCellActions
    let replyName: String?
    let replyText: String?
    let replyMessageId: String?
    let forwardSenderName: String?
    let forwardSenderKey: String?

    // MARK: - RosettaListItem

    var id: String { message.id }
    var approximateHeight: CGFloat { layout.totalHeight }
    var reuseIdentifier: String { "msg" }

    init(
        message: ChatMessage,
        layout: MessageCellLayout,
        textLayout: CoreTextTextLayout?,
        timestampText: String,
        actions: MessageCellActions,
        replyName: String? = nil,
        replyText: String? = nil,
        replyMessageId: String? = nil,
        forwardSenderName: String? = nil,
        forwardSenderKey: String? = nil
    ) {
        self.message = message
        self.layout = layout
        self.textLayout = textLayout
        self.timestampText = timestampText
        self.actions = actions
        self.replyName = replyName
        self.replyText = replyText
        self.replyMessageId = replyMessageId
        self.forwardSenderName = forwardSenderName
        self.forwardSenderKey = forwardSenderKey
    }

    func nodeConfiguredForParams(
        async: @escaping (@escaping () -> Void) -> Void,
        params: RosettaListLayoutParams,
        previousItem: RosettaListItem?,
        nextItem: RosettaListItem?,
        completion: @escaping (RosettaListNode, RosettaListNodeLayout) -> Void
    ) {
        let node = MessageListNode()
        applyToNode(node)
        let nodeLayout = RosettaListNodeLayout(
            contentSize: CGSize(width: params.width, height: layout.totalHeight),
            insets: .zero
        )
        completion(node, nodeLayout)
    }

    func updateNode(
        async: @escaping (@escaping () -> Void) -> Void,
        node: RosettaListNode,
        params: RosettaListLayoutParams,
        previousItem: RosettaListItem?,
        nextItem: RosettaListItem?,
        animation: RosettaListUpdateAnimation,
        completion: @escaping (RosettaListNodeLayout) -> Void
    ) {
        if let messageNode = node as? MessageListNode {
            applyToNode(messageNode)
        }
        let nodeLayout = RosettaListNodeLayout(
            contentSize: CGSize(width: params.width, height: layout.totalHeight),
            insets: .zero
        )
        completion(nodeLayout)
    }

    private func applyToNode(_ node: MessageListNode) {
        node.cell.apply(layout: layout)
        node.cell.configure(
            message: message,
            timestamp: timestampText,
            textLayout: textLayout,
            actions: actions,
            replyName: replyName,
            replyText: replyText,
            replyMessageId: replyMessageId,
            forwardSenderName: forwardSenderName,
            forwardSenderKey: forwardSenderKey
        )
    }
}

// MARK: - MessageListNode

/// RosettaListNode containing a NativeMessageCell.
/// NativeMessageCell is UICollectionViewCell but works as plain UIView
/// when instantiated directly (not dequeued from UICollectionView).
final class MessageListNode: RosettaListNode {

    let cell = NativeMessageCell(frame: .zero)

    override init(frame: CGRect) {
        super.init(frame: frame)
        // UICollectionViewCell.contentView is the actual content container
        cell.frame = bounds
        cell.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        contentView.addSubview(cell.contentView)
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        cell.prepareForReuse()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        cell.contentView.frame = contentView.bounds
        cell.bounds = contentView.bounds
        cell.layoutSubviews()
    }
}

// MARK: - UnreadSeparatorListItem

/// Unread separator for RosettaListView.
final class UnreadSeparatorListItem: RosettaListItem {

    var id: String { "__unread_separator__" }
    var approximateHeight: CGFloat { 25 }
    var reuseIdentifier: String { "sep" }

    func nodeConfiguredForParams(
        async: @escaping (@escaping () -> Void) -> Void,
        params: RosettaListLayoutParams,
        previousItem: RosettaListItem?,
        nextItem: RosettaListItem?,
        completion: @escaping (RosettaListNode, RosettaListNodeLayout) -> Void
    ) {
        let node = UnreadSeparatorNode()
        let nodeLayout = RosettaListNodeLayout(
            contentSize: CGSize(width: params.width, height: 25),
            insets: .zero
        )
        completion(node, nodeLayout)
    }

    func updateNode(
        async: @escaping (@escaping () -> Void) -> Void,
        node: RosettaListNode,
        params: RosettaListLayoutParams,
        previousItem: RosettaListItem?,
        nextItem: RosettaListItem?,
        animation: RosettaListUpdateAnimation,
        completion: @escaping (RosettaListNodeLayout) -> Void
    ) {
        completion(RosettaListNodeLayout(
            contentSize: CGSize(width: params.width, height: 25),
            insets: .zero
        ))
    }
}

// MARK: - UnreadSeparatorNode

final class UnreadSeparatorNode: RosettaListNode {

    private let bar: UIView = {
        let v = UIView()
        v.backgroundColor = UIColor(red: 0.16, green: 0.16, blue: 0.18, alpha: 1)
        return v
    }()

    private let label: UILabel = {
        let l = UILabel()
        l.text = "Unread Messages"
        l.font = .systemFont(ofSize: 13, weight: .regular)
        l.textColor = .white
        l.textAlignment = .center
        return l
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.addSubview(bar)
        bar.addSubview(label)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        bar.frame = contentView.bounds
        label.frame = bar.bounds
    }
}
