import Foundation
import UIKit
import AsyncDisplayKit
import Display
import SwiftSignalKit
import TelegramPresentationData
import TelegramStringFormatting
import AppBundle
import ChatPresentationInterfaceState

final class ChatTextInputSlowmodePlaceholderNode: ASDisplayNode {
    private var theme: PresentationTheme
    private let iconNode: ASImageNode
    private let iconArrowContainerNode: ASDisplayNode
    private let iconArrowNode: ASImageNode
    private let textNode: ImmediateTextNode
    
    private var slowmodeState: ChatSlowmodeState?
    private var validLayout: CGSize?
    
    private var timer: SwiftSignalKit.Timer?
    
    init(theme: PresentationTheme) {
        self.theme = theme
        self.textNode = ImmediateTextNode()
        self.textNode.displaysAsynchronously = false
        
        self.iconNode = ASImageNode()
        self.iconNode.displaysAsynchronously = false
        self.iconNode.displayWithoutProcessing = true
        self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/SlowmodeFrame"), color: theme.chat.inputPanel.inputPlaceholderColor)
        
        self.iconArrowNode = ASImageNode()
        self.iconArrowNode.displaysAsynchronously = false
        self.iconArrowNode.displayWithoutProcessing = true
        self.iconArrowNode.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/SlowmodeArrow"), color: theme.chat.inputPanel.inputPlaceholderColor)
        self.iconArrowNode.frame = CGRect(origin: CGPoint(), size: self.iconArrowNode.image?.size ?? CGSize())
        
        self.iconArrowContainerNode = ASDisplayNode()
        self.iconArrowContainerNode.addSubnode(self.iconArrowNode)
        
        super.init()
        
        self.isUserInteractionEnabled = false
        
        self.addSubnode(self.iconNode)
        self.addSubnode(self.iconArrowContainerNode)
        self.addSubnode(self.textNode)
    }
    
    deinit {
        self.timer?.invalidate()
    }
    
    func updateState(_ slowmodeState: ChatSlowmodeState) {
        if self.slowmodeState != slowmodeState {
            self.slowmodeState = slowmodeState
            self.update()
            
            if self.timer == nil {
                let timer = SwiftSignalKit.Timer(timeout: 0.5, repeat: true, completion: { [weak self] in
                    self?.update()
                }, queue: .mainQueue())
                self.timer = timer
                timer.start()
            }
        }
    }
    
    private func update() {
        if let slowmodeState = self.slowmodeState {
            switch slowmodeState.variant {
            case .pendingMessages:
                self.textNode.attributedText = NSAttributedString(string: stringForDuration(slowmodeState.timeout), font: Font.regular(17.0), textColor: self.theme.chat.inputPanel.inputPlaceholderColor)
            case let .timestamp(timeoutTimestamp):
                let timestamp = Int32(Date().timeIntervalSince1970)
                let timeout = max(0, timeoutTimestamp - timestamp)
                self.textNode.attributedText = NSAttributedString(string: stringForDuration(timeout), font: Font.regular(17.0), textColor: self.theme.chat.inputPanel.inputPlaceholderColor)
                if timeout <= 30 {
                    if self.iconArrowNode.layer.animation(forKey: "rotation") == nil {
                        let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
                        basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
                        basicAnimation.duration = 1.0
                        basicAnimation.fromValue = NSNumber(value: Float(0.0))
                        basicAnimation.toValue = NSNumber(value: Float(Double.pi * 2.0))
                        basicAnimation.repeatCount = Float.infinity
                        basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
                        self.iconArrowNode.layer.add(basicAnimation, forKey: "rotation")
                    }
                } else {
                    self.iconArrowNode.layer.removeAnimation(forKey: "rotation")
                }
            }
        }
        if let validLayout = self.validLayout {
            self.updateLayout(size: validLayout)
        }
    }
    
    func updateLayout(size: CGSize) {
        self.validLayout = size
        
        var leftInset: CGFloat = 0.0
        if let image = self.iconNode.image {
            let imageSize = image.size
            leftInset += imageSize.width + 4.0
            let iconArrowFrame = CGRect(origin: CGPoint(x: 0.0, y: 1.0), size: imageSize)
            self.iconNode.frame = iconArrowFrame
            
            if let arrowImage = self.iconArrowNode.image {
                self.iconArrowContainerNode.frame = CGRect(origin: CGPoint(x: iconArrowFrame.minX, y: iconArrowFrame.maxY - arrowImage.size.height), size: arrowImage.size)
            }
        }
        
        let textSize = self.textNode.updateLayout(size)
        self.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: textSize)
    }
}