import Foundation
import UIKit
import AsyncDisplayKit
import TelegramCore
import SwiftSignalKit
import Display
import TelegramPresentationData
import AccountContext
import TelegramStringFormatting
import ChatPresentationInterfaceState
import AccessoryPanelNode
import AppBundle

final class WebpagePreviewAccessoryPanelNode: AccessoryPanelNode {
    private(set) var webpage: TelegramMediaWebpage
    private(set) var url: String
    
    let closeButton: HighlightableButtonNode
    let lineNode: ASImageNode
    let iconView: UIImageView
    let titleNode: TextNode
    private var titleString: NSAttributedString?
    
    let textNode: TextNode
    private var textString: NSAttributedString?
    
    var theme: PresentationTheme
    var strings: PresentationStrings
    
    private var validLayout: (size: CGSize, inset: CGFloat, interfaceState: ChatPresentationInterfaceState)?
    
    init(context: AccountContext, url: String, webpage: TelegramMediaWebpage, theme: PresentationTheme, strings: PresentationStrings) {
        self.url = url
        self.webpage = webpage
        self.theme = theme
        self.strings = strings
        
        self.closeButton = HighlightableButtonNode()
        self.closeButton.setImage(PresentationResourcesChat.chatInputPanelCloseIconImage(theme), for: [])
        self.closeButton.hitTestSlop = UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0)
        self.closeButton.displaysAsynchronously = false
        
        self.lineNode = ASImageNode()
        self.lineNode.displayWithoutProcessing = true
        self.lineNode.displaysAsynchronously = false
        self.lineNode.image = PresentationResourcesChat.chatInputPanelVerticalSeparatorLineImage(theme)
        
        self.iconView = UIImageView()
        self.iconView.image = UIImage(bundleImageName: "Chat/Input/Accessory Panels/LinkSettingsIcon")?.withRenderingMode(.alwaysTemplate)
        self.iconView.tintColor = theme.chat.inputPanel.panelControlAccentColor
        
        self.titleNode = TextNode()
        self.titleNode.displaysAsynchronously = false
        
        self.textNode = TextNode()
        self.textNode.displaysAsynchronously = false
        
        super.init()
        
        self.closeButton.addTarget(self, action: #selector(self.closePressed), forControlEvents: [.touchUpInside])
        self.addSubnode(self.closeButton)
        
        self.addSubnode(self.lineNode)
        self.view.addSubview(self.iconView)
        self.addSubnode(self.titleNode)
        self.addSubnode(self.textNode)
        
        self.updateWebpage()
    }
        
    override func animateIn() {
        self.iconView.layer.animateScale(from: 0.001, to: 1.0, duration: 0.2)
    }
    
    override func animateOut() {
        self.iconView.layer.animateScale(from: 1.0, to: 0.001, duration: 0.2, removeOnCompletion: false)
    }
    
    override public func didLoad() {
        super.didLoad()
        
        self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
    }
    
    override func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) {
        self.updateThemeAndStrings(theme: theme, strings: strings, force: false)
    }
    
    func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings, force: Bool) {
        if self.theme !== theme || self.strings !== strings || force {
            self.strings = strings
           
            if self.theme !== theme {
                self.theme = theme
                
                self.closeButton.setImage(PresentationResourcesChat.chatInputPanelCloseIconImage(theme), for: [])
                self.lineNode.image = PresentationResourcesChat.chatInputPanelVerticalSeparatorLineImage(theme)
                self.iconView.tintColor = theme.chat.inputPanel.panelControlAccentColor
            }
            
            if let text = self.titleString?.string {
                self.titleString = NSAttributedString(string: text, font: Font.medium(15.0), textColor: self.theme.chat.inputPanel.panelControlAccentColor)
            }
            
            if let text = self.textString?.string {
                self.textString = NSAttributedString(string: text, font: Font.regular(15.0), textColor: self.theme.chat.inputPanel.primaryTextColor)
            }
            
            self.updateWebpage()
            
            if let (size, inset, interfaceState) = self.validLayout {
                self.updateState(size: size, inset: inset, interfaceState: interfaceState)
            }
        }
    }
    
    func replaceWebpage(url: String, webpage: TelegramMediaWebpage) {
        if self.url != url || !self.webpage.isEqual(to: webpage) {
            self.url = url
            self.webpage = webpage
            self.updateWebpage()
        }
    }
    
    private func updateWebpage() {
        var authorName = ""
        var text = ""
        switch self.webpage.content {
            case .Pending:
                authorName = self.strings.Channel_NotificationLoading
                text = self.url
            case let .Loaded(content):
                if let contentText = content.text {
                    text = contentText
                } else {
                    if let file = content.file, let mediaKind = mediaContentKind(EngineMedia(file)) {
                        if content.type == "telegram_background" {
                            text = strings.Message_Wallpaper
                        } else if content.type == "telegram_theme" {
                            text = strings.Message_Theme
                        } else {
                            text = stringForMediaKind(mediaKind, strings: self.strings).0.string
                        }
                    } else if content.type == "telegram_theme" {
                        text = strings.Message_Theme
                    } else if content.type == "video" {
                        text = stringForMediaKind(.video, strings: self.strings).0.string
                    } else if content.type == "telegram_story" {
                        text = stringForMediaKind(.story, strings: self.strings).0.string
                    } else if let _ = content.image {
                        text = stringForMediaKind(.image, strings: self.strings).0.string
                    }
                }
                
                if let title = content.title {
                    authorName = title
                } else if let websiteName = content.websiteName {
                    authorName = websiteName
                } else {
                    authorName = content.displayUrl
                }
            
        }
        
        self.titleString = NSAttributedString(string: authorName, font: Font.medium(15.0), textColor: self.theme.chat.inputPanel.panelControlAccentColor)
        self.textString = NSAttributedString(string: text, font: Font.regular(15.0), textColor: self.theme.chat.inputPanel.primaryTextColor)
        
        if let (size, inset, interfaceState) = self.validLayout {
            self.updateState(size: size, inset: inset, interfaceState: interfaceState)
        }
    }
    
    override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
        return CGSize(width: constrainedSize.width, height: 45.0)
    }
    
    override func updateState(size: CGSize, inset: CGFloat, interfaceState: ChatPresentationInterfaceState) {
        self.validLayout = (size, inset, interfaceState)
        
        let bounds = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: 45.0))
        let leftInset: CGFloat = 55.0
        let textLineInset: CGFloat = 10.0
        let rightInset: CGFloat = 55.0
        let textRightInset: CGFloat = 20.0
        
        let closeButtonSize = CGSize(width: 44.0, height: bounds.height)
        self.closeButton.frame = CGRect(origin: CGPoint(x: bounds.size.width - closeButtonSize.width - inset, y: 2.0), size: closeButtonSize)
        
        self.lineNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 8.0), size: CGSize(width: 2.0, height: bounds.size.height - 10.0))
        
        if let icon = self.iconView.image {
            self.iconView.frame = CGRect(origin: CGPoint(x: 7.0 + inset, y: 10.0), size: icon.size)
        }
        
        let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
        let makeTextLayout = TextNode.asyncLayout(self.textNode)
        
        let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: self.titleString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: bounds.size.width - leftInset - textLineInset - rightInset - textRightInset, height: bounds.size.height), alignment: .natural, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets()))
        
        let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: self.textString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: bounds.size.width - leftInset - textLineInset - rightInset - textRightInset, height: bounds.size.height), alignment: .natural, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets()))
        
        self.titleNode.frame = CGRect(origin: CGPoint(x: leftInset + textLineInset, y: 7.0), size: titleLayout.size)
        
        self.textNode.frame = CGRect(origin: CGPoint(x: leftInset + textLineInset, y: 25.0), size: textLayout.size)
        
        let _ = titleApply()
        let _ = textApply()
    }
    
    
    @objc func closePressed() {
        if let dismiss = self.dismiss {
            dismiss()
        }
    }
    
    private var previousTapTimestamp: Double?
    @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) {
        if case .ended = recognizer.state {
            let timestamp = CFAbsoluteTimeGetCurrent()
            if let previousTapTimestamp = self.previousTapTimestamp, previousTapTimestamp + 1.0 > timestamp {
                return
            }
            self.previousTapTimestamp = CFAbsoluteTimeGetCurrent()
            self.interfaceInteraction?.presentLinkOptions(self)
            Queue.mainQueue().after(1.5) {
                self.updateThemeAndStrings(theme: self.theme, strings: self.strings, force: true)
            }
            
            //let _ = ApplicationSpecificNotice.incrementChatReplyOptionsTip(accountManager: self.context.sharedContext.accountManager, count: 3).start()
        }
    }
}