import Foundation
import UIKit
import Display
import AsyncDisplayKit
import TelegramPresentationData
import ComponentFlow

public struct CounterControllerTitle: Equatable {
    public var title: String
    public var counter: String?
    
    public init(title: String, counter: String?) {
        self.title = title
        self.counter = counter
    }
}

public final class CounterControllerTitleView: UIView {
    private let titleNode: ImmediateTextNode

    private var subtitleNode: ImmediateTextNode
    private var disappearingSubtitleNode: ImmediateTextNode?
    
    public var title: CounterControllerTitle = CounterControllerTitle(title: "", counter: nil) {
        didSet {
            if self.title != oldValue {
                self.update(animated: oldValue.title.isEmpty == self.title.title.isEmpty)
            }
        }
    }
    
    public var theme: PresentationTheme {
        didSet {
            self.update(animated: false)
        }
    }
    
    private var primaryTextColor: UIColor?
    private var secondaryTextColor: UIColor?

    private var nextLayoutTransition: ContainedViewLayoutTransition?
    
    public func updateTextColors(primary: UIColor?, secondary: UIColor?, transition: ContainedViewLayoutTransition) {
        self.primaryTextColor = primary
        self.secondaryTextColor = secondary
        
        if case let .animated(duration, curve) = transition {
            if let snapshotView = self.snapshotContentTree() {
                snapshotView.frame = self.bounds
                self.addSubview(snapshotView)
                
                snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, timingFunction: curve.timingFunction, removeOnCompletion: false, completion: { _ in
                    snapshotView.removeFromSuperview()
                })
                self.titleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration, timingFunction: curve.timingFunction)
                self.subtitleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: duration, timingFunction: curve.timingFunction)
            }
        }
        
        self.update(animated: false)
    }
    
    private func update(animated: Bool) {
        let primaryTextColor = self.primaryTextColor ?? self.theme.rootController.navigationBar.primaryTextColor
        let secondaryTextColor = self.secondaryTextColor ?? self.theme.rootController.navigationBar.secondaryTextColor
        self.titleNode.attributedText = NSAttributedString(string: self.title.title, font: Font.semibold(17.0), textColor: primaryTextColor)

        let subtitleText = NSAttributedString(string: self.title.counter ?? "", font: Font.with(size: 13.0, traits: .monospacedNumbers), textColor: secondaryTextColor)
        if let previousSubtitleText = self.subtitleNode.attributedText, previousSubtitleText.string.isEmpty != subtitleText.string.isEmpty && subtitleText.string.isEmpty {
            if let disappearingSubtitleNode = self.disappearingSubtitleNode {
                self.disappearingSubtitleNode = nil
                disappearingSubtitleNode.removeFromSupernode()
            }

            self.disappearingSubtitleNode = self.subtitleNode

            self.subtitleNode = ImmediateTextNode()
            self.subtitleNode.displaysAsynchronously = false
            self.subtitleNode.maximumNumberOfLines = 1
            self.subtitleNode.truncationType = .end
            self.subtitleNode.isOpaque = false
            self.subtitleNode.attributedText = subtitleText
            self.addSubnode(self.subtitleNode)
        } else {
            self.subtitleNode.attributedText = subtitleText
        }
        
        self.accessibilityLabel = self.title.title
        self.accessibilityValue = self.title.counter
        
        if animated {
            self.nextLayoutTransition = .animated(duration: 0.4, curve: .spring)
        }
        self.setNeedsLayout()
    }
    
    public init(theme: PresentationTheme) {
        self.theme = theme
        
        self.titleNode = ImmediateTextNode()
        self.titleNode.displaysAsynchronously = false
        self.titleNode.maximumNumberOfLines = 1
        self.titleNode.truncationType = .end
        self.titleNode.isOpaque = false
        
        self.subtitleNode = ImmediateTextNode()
        self.subtitleNode.displaysAsynchronously = false
        self.subtitleNode.maximumNumberOfLines = 1
        self.subtitleNode.truncationType = .end
        self.subtitleNode.isOpaque = false
        
        super.init(frame: CGRect())
        
        self.isAccessibilityElement = true
        self.accessibilityTraits = .header
        
        self.addSubnode(self.titleNode)
        self.addSubnode(self.subtitleNode)
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override public func layoutSubviews() {
        super.layoutSubviews()
        
        let size = self.bounds.size
        let spacing: CGFloat = 0.0
        
        let titleSize = self.titleNode.updateLayout(CGSize(width: max(1.0, size.width), height: size.height))
        let subtitleSize = self.subtitleNode.updateLayout(CGSize(width: max(1.0, size.width), height: size.height))
        
        let combinedHeight: CGFloat
        if self.title.counter != nil {
            combinedHeight = titleSize.height + subtitleSize.height + spacing
        } else {
            combinedHeight = titleSize.height
        }

        var transition: ContainedViewLayoutTransition = .immediate
        if let nextLayoutTransition = self.nextLayoutTransition {
            if !self.titleNode.bounds.isEmpty {
                transition = nextLayoutTransition
            }
            self.nextLayoutTransition = nil
        }
        
        let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: floor((size.height - combinedHeight) / 2.0)), size: titleSize)
        self.titleNode.bounds = CGRect(origin: CGPoint(), size: titleFrame.size)
        transition.updatePosition(node: self.titleNode, position: titleFrame.center)
        
        let subtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - subtitleSize.width) / 2.0), y: floor((size.height - combinedHeight) / 2.0) + titleSize.height + spacing), size: subtitleSize)
        self.subtitleNode.bounds = CGRect(origin: CGPoint(), size: subtitleFrame.size)
        transition.updatePosition(node: self.subtitleNode, position: subtitleFrame.center)
        transition.updateTransformScale(node: self.subtitleNode, scale: self.title.counter != nil ? 1.0 : 0.001)
        transition.updateAlpha(node: self.subtitleNode, alpha: self.title.counter != nil ? 1.0 : 0.0)

        if let disappearingSubtitleNode = self.disappearingSubtitleNode {
            transition.updatePosition(node: disappearingSubtitleNode, position: subtitleFrame.center)
            transition.updateTransformScale(node: disappearingSubtitleNode, scale: self.title.counter != nil ? 1.0 : 0.001)
            transition.updateAlpha(node: disappearingSubtitleNode, alpha: self.title.counter != nil ? 1.0 : 0.0, completion: { [weak disappearingSubtitleNode] _ in
                disappearingSubtitleNode?.removeFromSupernode()
            })
        }
    }
}