import UIKit

/// Telegram-exact context menu card.
///
/// Source: ContextActionsContainerNode.swift + ContextActionNode.swift + DefaultDarkPresentationTheme.swift
/// - Background: .systemMaterial blur + UIColor(0x252525, alpha: 0.78) tint
/// - Items: 17pt regular, text LEFT + icon RIGHT (Telegram standard)
/// - Icon container: 32pt, right-aligned 16pt from edge
/// - Corner radius: 14pt continuous
/// - Separator: screenPixel, white 15% alpha, full width
/// - Destructive: 0xeb5545
final class TelegramContextMenuCardView: UIView {

    // MARK: - Layout Style

    enum LayoutStyle {
        /// Icons RIGHT, text LEFT — Telegram `ContextActionNode` (message context menu)
        case iconRight
        /// Icons LEFT, text RIGHT — Telegram `ContextControllerActionsStackNode` (gallery menu)
        case iconLeft
    }

    // MARK: - Constants

    private static let itemHeight: CGFloat = 44
    private static let cornerRadius: CGFloat = 14
    private static let screenPixel = 1.0 / max(UIScreen.main.scale, 1)

    // iconRight constants (ContextActionNode)
    private static let irHPad: CGFloat = 16
    private static let irIconContainerW: CGFloat = 32
    private static let irIconSideInset: CGFloat = 12

    // iconLeft constants (ContextControllerActionsStackNode)
    private static let ilIconSideInset: CGFloat = 20
    private static let ilIconContainerW: CGFloat = 32
    private static let ilIconSpacing: CGFloat = 8
    private static let ilSideInset: CGFloat = 18

    // MARK: - Colors (adaptive light/dark)

    private static let textColor = UIColor { traits in
        traits.userInterfaceStyle == .dark ? .white : .black
    }
    private static let destructiveColor = UIColor(red: 0xEB/255, green: 0x55/255, blue: 0x45/255, alpha: 1)
    private static let separatorColor = UIColor { traits in
        traits.userInterfaceStyle == .dark
            ? UIColor(white: 1, alpha: 0.15)
            : UIColor(white: 0, alpha: 0.1)
    }
    private static let highlightColor = UIColor { traits in
        traits.userInterfaceStyle == .dark
            ? UIColor(white: 1, alpha: 0.15)
            : UIColor(white: 0, alpha: 0.08)
    }

    // MARK: - Public

    let itemCount: Int
    var onItemSelected: (() -> Void)?

    /// Calculates minimum width needed to fit all items without clipping.
    var preferredWidth: CGFloat {
        var maxTextW: CGFloat = 0
        for label in titleLabels {
            let sz = label.sizeThatFits(CGSize(width: .greatestFiniteMagnitude, height: Self.itemHeight))
            maxTextW = max(maxTextW, ceil(sz.width))
        }
        switch layoutStyle {
        case .iconLeft:
            return Self.ilIconSideInset + Self.ilIconContainerW + Self.ilIconSpacing + maxTextW + Self.ilSideInset
        case .iconRight:
            return Self.irHPad + maxTextW + Self.irIconSideInset + Self.irIconContainerW + Self.irHPad
        }
    }

    // MARK: - Views

    private let items: [TelegramContextMenuItem]

    // Row subviews stored for layout
    private var titleLabels: [UILabel] = []
    private var iconViews: [UIImageView] = []
    private var highlightViews: [UIView] = []
    private var separators: [UIView] = []

    private let showSeparators: Bool
    private let layoutStyle: LayoutStyle

    // MARK: - Init

    init(items: [TelegramContextMenuItem], showSeparators: Bool = true, layoutStyle: LayoutStyle = .iconRight) {
        self.items = items
        self.itemCount = items.count
        self.showSeparators = showSeparators
        self.layoutStyle = layoutStyle
        super.init(frame: .zero)
        setup()
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) { fatalError() }

    // MARK: - Setup

    private func setup() {
        clipsToBounds = true
        layer.cornerRadius = Self.cornerRadius
        layer.cornerCurve = .continuous

        // Telegram iPhone: no blur, just semi-transparent backgroundColor
        // (ContextActionsContainerNode.swift — blur only on iPad/regular width)
        backgroundColor = UIColor { traits in
            traits.userInterfaceStyle == .dark
                ? UIColor(red: 0x25/255, green: 0x25/255, blue: 0x25/255, alpha: 0.78)
                : UIColor(red: 0xF9/255, green: 0xF9/255, blue: 0xF9/255, alpha: 0.78)
        }

        for (i, item) in items.enumerated() {
            let color = item.isDestructive ? Self.destructiveColor : Self.textColor

            // Highlight
            let hl = UIView()
            hl.backgroundColor = Self.highlightColor
            hl.alpha = 0
            addSubview(hl)
            highlightViews.append(hl)

            // Title
            let label = UILabel()
            label.text = item.title
            label.font = .systemFont(ofSize: 17, weight: .regular)
            label.textColor = color
            addSubview(label)
            titleLabels.append(label)

            // Icon
            let iv = UIImageView()
            iv.image = UIImage(systemName: item.iconName)?
                .withConfiguration(UIImage.SymbolConfiguration(pointSize: 17, weight: .medium))
            iv.tintColor = color
            iv.contentMode = .center
            addSubview(iv)
            iconViews.append(iv)

            // Separator (optional — Telegram gallery menu has none)
            if showSeparators, i < items.count - 1 {
                let sep = UIView()
                sep.backgroundColor = Self.separatorColor
                addSubview(sep)
                separators.append(sep)
            }

            // Row gesture
            let rowView = UIView()
            rowView.backgroundColor = .clear
            rowView.tag = i
            let press = UILongPressGestureRecognizer(target: self, action: #selector(rowPress(_:)))
            press.minimumPressDuration = 0
            press.cancelsTouchesInView = false
            rowView.addGestureRecognizer(press)
            addSubview(rowView)
        }
    }

    // MARK: - Layout

    override func layoutSubviews() {
        super.layoutSubviews()
        let w = bounds.width

        for i in 0..<items.count {
            let y = CGFloat(i) * Self.itemHeight
            let rowRect = CGRect(x: 0, y: y, width: w, height: Self.itemHeight)

            highlightViews[i].frame = rowRect

            switch layoutStyle {
            case .iconRight:
                // Text LEFT, icon RIGHT (ContextActionNode)
                let titleX = Self.irHPad
                let titleW = w - Self.irHPad - Self.irIconSideInset - Self.irIconContainerW - Self.irHPad
                titleLabels[i].frame = CGRect(x: titleX, y: y, width: titleW, height: Self.itemHeight)
                let iconX = w - Self.irHPad - Self.irIconContainerW
                iconViews[i].frame = CGRect(x: iconX, y: y, width: Self.irIconContainerW, height: Self.itemHeight)

            case .iconLeft:
                // Icon LEFT, text RIGHT (ContextControllerActionsStackNode)
                iconViews[i].frame = CGRect(x: Self.ilIconSideInset, y: y, width: Self.ilIconContainerW, height: Self.itemHeight)
                let titleX = Self.ilIconSideInset + Self.ilIconContainerW + Self.ilIconSpacing
                let titleW = w - titleX - Self.ilSideInset
                titleLabels[i].frame = CGRect(x: titleX, y: y, width: titleW, height: Self.itemHeight)
            }

            // Gesture receiver (topmost, transparent)
            if let rv = subviews.first(where: { $0.tag == i && $0.gestureRecognizers?.isEmpty == false }) {
                rv.frame = rowRect
            }
        }

        // Separators
        for (i, sep) in separators.enumerated() {
            let y = CGFloat(i + 1) * Self.itemHeight
            sep.frame = CGRect(x: 0, y: y, width: w, height: Self.screenPixel)
        }
    }

    // MARK: - Interaction

    @objc private func rowPress(_ g: UILongPressGestureRecognizer) {
        let i = g.view?.tag ?? -1
        guard i >= 0, i < items.count else { return }

        switch g.state {
        case .began:
            UIView.animate(withDuration: 0.08) { self.highlightViews[i].alpha = 1 }
        case .ended:
            let loc = g.location(in: g.view)
            UIView.animate(withDuration: 0.3) { self.highlightViews[i].alpha = 0 }
            if g.view?.bounds.contains(loc) == true {
                let handler = items[i].handler
                onItemSelected?()
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { handler() }
            }
        case .cancelled, .failed:
            UIView.animate(withDuration: 0.3) { self.highlightViews[i].alpha = 0 }
        default: break
        }
    }
}
