import Foundation
import UIKit
import AsyncDisplayKit
import Display
import TelegramCore
import Postbox
import SwiftSignalKit
import TelegramPresentationData
import ChatPresentationInterfaceState
import SolidRoundedButtonNode
import TooltipUI
import ChatInputPanelNode

public final class ChatBotStartInputPanelNode: ChatInputPanelNode {
    private let button: SolidRoundedButtonNode
    
    private var statusDisposable: Disposable?
    
    private var presentationInterfaceState: ChatPresentationInterfaceState?
    
    override public var interfaceInteraction: ChatPanelInterfaceInteraction? {
        didSet {
            if let _ = self.interfaceInteraction {
                if self.statusDisposable == nil {
                    if let startingBot = self.interfaceInteraction?.statuses?.startingBot {
                        self.statusDisposable = (startingBot |> deliverOnMainQueue).startStrict(next: { [weak self] value in
                            if let strongSelf = self {
                                strongSelf.inProgress = value
                            }
                        })
                    }
                }
            }
        }
    }
    
    private var inProgress = false {
        didSet {
            if self.inProgress != oldValue {
                if self.inProgress {
                    self.button.transitionToProgress()
                } else {
                    self.button.transitionFromProgress()
                }
            }
        }
    }
    
    private var theme: PresentationTheme
    private var strings: PresentationStrings
    
    private var tooltipController: TooltipScreen?
    private var tooltipDismissed = false
    
    public init(theme: PresentationTheme, strings: PresentationStrings) {
        self.theme = theme
        self.strings = strings
        
        self.button = SolidRoundedButtonNode(title: self.strings.Bot_Start, theme: SolidRoundedButtonTheme(theme: theme), height: 50.0, cornerRadius: 11.0, gloss: true)
        self.button.progressType = .embedded
        
        super.init()
        
        self.addSubnode(self.button)

        self.button.pressed = { [weak self] in
            self?.buttonPressed()
        }
    }
    
    deinit {
        self.statusDisposable?.dispose()
        self.tooltipController?.dismiss()
    }
    
    public func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) {
        if self.theme !== theme || self.strings !== strings {
            self.theme = theme
            self.strings = strings
            
            self.button.updateTheme(SolidRoundedButtonTheme(theme: theme))
        }
    }
    
    @objc private func buttonPressed() {
        guard let _ = self.context, let presentationInterfaceState = self.presentationInterfaceState else {
            return
        }
        
        self.interfaceInteraction?.sendBotStart(presentationInterfaceState.botStartPayload)
        
        if let tooltipController = self.tooltipController {
            self.tooltipDismissed = false
            self.tooltipController = nil
            tooltipController.dismiss()
        }
    }
    
    override public func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition) {
        super.updateAbsoluteRect(rect, within: containerSize, transition: transition)
        
        let absoluteFrame = self.button.view.convert(self.button.bounds, to: nil)
        let location = CGRect(origin: CGPoint(x: absoluteFrame.midX, y: absoluteFrame.minY - 1.0), size: CGSize())
        
        if let tooltipController = self.tooltipController, self.view.window != nil {
            tooltipController.location = .point(location, .bottom)
        }
    }
    
    
    override public func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
        if self.presentationInterfaceState != interfaceState {
            self.presentationInterfaceState = interfaceState
        }
        
        let inset: CGFloat = max(leftInset, 16.0)
        let maximumWidth: CGFloat = min(430.0, width)
        let proceedHeight = self.button.updateLayout(width: maximumWidth - inset * 2.0, transition: transition)
        let buttonSize = CGSize(width: maximumWidth - inset * 2.0, height: proceedHeight)
        
        let panelHeight = defaultHeight(metrics: metrics) + 27.0
        
        self.button.frame = CGRect(origin: CGPoint(x: leftInset + floor((width - leftInset - rightInset - buttonSize.width) / 2.0), y: 8.0), size: buttonSize)
        
        if !self.tooltipDismissed, let context = self.context {
            let absoluteFrame = self.button.view.convert(self.button.bounds, to: nil)
            let location = CGRect(origin: CGPoint(x: absoluteFrame.midX, y: absoluteFrame.minY - 1.0), size: CGSize())
            
            if let tooltipController = self.tooltipController {
                if self.view.window != nil {
                    tooltipController.location = .point(location, .bottom)
                }
            } else {
                let controller = TooltipScreen(account: context.account, sharedContext: context.sharedContext, text: .plain(text: self.strings.Bot_TapToUse), icon: .downArrows, location: .point(location, .bottom), displayDuration: .infinite, shouldDismissOnTouch: { _, _ in
                    return .ignore
                })
                controller.alwaysVisible = true
                self.tooltipController = controller
                
                let delay: Double
                if case .regular = metrics.widthClass {
                    delay = 0.1
                } else {
                    delay = 0.35
                }
                Queue.mainQueue().after(delay, {
                    let absoluteFrame = self.button.view.convert(self.button.bounds, to: nil)
                    let location = CGRect(origin: CGPoint(x: absoluteFrame.midX, y: absoluteFrame.minY - 1.0), size: CGSize())
                    controller.location = .point(location, .bottom)
                    self.interfaceInteraction?.presentControllerInCurrent(controller, nil)
                })
            }
        }
        
        return panelHeight
    }
    
    override public func minimalHeight(interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat {
        return defaultHeight(metrics: metrics) + 27.0
    }
}