import Foundation
import UIKit
import SwiftSignalKit
import Postbox
import TelegramCore
import AsyncDisplayKit
import Display
import ContextUI
import UndoUI
import AccountContext
import ChatMessageItemView
import ChatMessageItemCommon
import MessageUI
import ChatControllerInteraction
import UrlWhitelist
import OpenInExternalAppUI
import SafariServices

extension ChatControllerImpl {
    func openLinkContextMenu(url: String, params: ChatControllerInteraction.LongTapParams) -> Void {
        guard let message = params.message, let contentNode = params.contentNode else {
            var (cleanUrl, _) = parseUrl(url: url, wasConcealed: false)
            var canAddToReadingList = true
            var canOpenIn = availableOpenInOptions(context: self.context, item: .url(url: url)).count > 1
            let mailtoString = "mailto:"
            let telString = "tel:"
            var openText = self.presentationData.strings.Conversation_LinkDialogOpen
            var phoneNumber: String?
            
            var isPhoneNumber = false
            var isEmail = false
            var hasOpenAction = true
            
            if cleanUrl.hasPrefix(mailtoString) {
                canAddToReadingList = false
                cleanUrl = String(cleanUrl[cleanUrl.index(cleanUrl.startIndex, offsetBy: mailtoString.distance(from: mailtoString.startIndex, to: mailtoString.endIndex))...])
                isEmail = true
            } else if cleanUrl.hasPrefix(telString) {
                canAddToReadingList = false
                phoneNumber = String(cleanUrl[cleanUrl.index(cleanUrl.startIndex, offsetBy: telString.distance(from: telString.startIndex, to: telString.endIndex))...])
                cleanUrl = phoneNumber!
                openText = self.presentationData.strings.UserInfo_PhoneCall
                canOpenIn = false
                isPhoneNumber = true
                
                if cleanUrl.hasPrefix("+888") {
                    hasOpenAction = false
                }
            } else if canOpenIn {
                openText = self.presentationData.strings.Conversation_FileOpenIn
            }
            
            let actionSheet = ActionSheetController(presentationData: self.presentationData)
            var items: [ActionSheetItem] = []
            items.append(ActionSheetTextItem(title: cleanUrl))
            if hasOpenAction {
                items.append(ActionSheetButtonItem(title: openText, color: .accent, action: { [weak self, weak actionSheet] in
                    actionSheet?.dismissAnimated()
                    if let strongSelf = self {
                        if canOpenIn {
                            strongSelf.openUrlIn(url)
                        } else {
                            strongSelf.openUrl(url, concealed: false)
                        }
                    }
                }))
            }
            if let phoneNumber = phoneNumber {
                items.append(ActionSheetButtonItem(title: self.presentationData.strings.Conversation_AddContact, color: .accent, action: { [weak self, weak actionSheet] in
                    actionSheet?.dismissAnimated()
                    if let strongSelf = self {
                        strongSelf.controllerInteraction?.addContact(phoneNumber)
                    }
                }))
            }
            items.append(ActionSheetButtonItem(title: canAddToReadingList ? self.presentationData.strings.ShareMenu_CopyShareLink : self.presentationData.strings.Conversation_ContextMenuCopy, color: .accent, action: { [weak actionSheet, weak self] in
                actionSheet?.dismissAnimated()
                guard let self else {
                    return
                }
                UIPasteboard.general.string = cleanUrl
                
                let content: UndoOverlayContent
                if isPhoneNumber {
                    content = .copy(text: self.presentationData.strings.Conversation_PhoneCopied)
                } else if isEmail {
                    content = .copy(text: self.presentationData.strings.Conversation_EmailCopied)
                } else if canAddToReadingList {
                    content = .linkCopied(text: self.presentationData.strings.Conversation_LinkCopied)
                } else {
                    content = .copy(text: self.presentationData.strings.Conversation_TextCopied)
                }
                self.present(UndoOverlayController(presentationData: self.presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
            }))
            if canAddToReadingList {
                items.append(ActionSheetButtonItem(title: self.presentationData.strings.Conversation_AddToReadingList, color: .accent, action: { [weak actionSheet] in
                    actionSheet?.dismissAnimated()
                    if let link = URL(string: url) {
                        let _ = try? SSReadingList.default()?.addItem(with: link, title: nil, previewText: nil)
                    }
                }))
            }
            actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
                ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
                    actionSheet?.dismissAnimated()
                })
            ])])
            self.chatDisplayNode.dismissInput()
            self.present(actionSheet, in: .window(.root))
            
            return
        }
        
        guard let messages = self.chatDisplayNode.historyNode.messageGroupInCurrentHistoryView(message.id) else {
            return
        }
        
        var updatedMessages = messages
        for i in 0 ..< updatedMessages.count {
            if updatedMessages[i].id == message.id {
                let message = updatedMessages.remove(at: i)
                updatedMessages.insert(message, at: 0)
                break
            }
        }
        
        var (cleanUrl, _) = parseUrl(url: url, wasConcealed: false)
        var canAddToReadingList = true
        let canOpenIn = availableOpenInOptions(context: self.context, item: .url(url: url)).count > 1
        
        let mailtoString = "mailto:"
        var openText = self.presentationData.strings.Conversation_LinkDialogOpen
        
        if cleanUrl.hasPrefix(mailtoString) {
            canAddToReadingList = false
            cleanUrl = String(cleanUrl[cleanUrl.index(cleanUrl.startIndex, offsetBy: mailtoString.distance(from: mailtoString.startIndex, to: mailtoString.endIndex))...])
//            isEmail = true
        } else if canOpenIn {
            openText = self.presentationData.strings.Conversation_FileOpenIn
        }
            
        let recognizer: TapLongTapOrDoubleTapGestureRecognizer? = nil// anyRecognizer as? TapLongTapOrDoubleTapGestureRecognizer
        let gesture: ContextGesture? = nil // anyRecognizer as? ContextGesture
        
        let source: ContextContentSource
//                if let location = location {
//                    source = .location(ChatMessageContextLocationContentSource(controller: self, location: messageNode.view.convert(messageNode.bounds, to: nil).origin.offsetBy(dx: location.x, dy: location.y)))
//                } else {
            source = .extracted(ChatMessageLinkContextExtractedContentSource(chatNode: self.chatDisplayNode, contentNode: contentNode))
//                }
        
        var items: [ContextMenuItem] = []
        
        items.append(
            .action(ContextMenuActionItem(text: openText, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Browser"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
                guard let self else {
                    return
                }
                f(.default)
                
                if canOpenIn {
                    self.openUrlIn(url)
                }
                else {
                    self.openUrl(url, concealed: false)
                }
            }))
        )
        
        items.append(
            .action(ContextMenuActionItem(text: self.presentationData.strings.Conversation_ContextMenuCopyLink, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.contextMenu.primaryColor) }, action: { [weak self]  _, f in
                f(.default)

                guard let self else {
                    return
                }
                
                UIPasteboard.general.string = url

                self.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
            }))
        )
        
        if canAddToReadingList {
            items.append(
                .action(ContextMenuActionItem(text: self.presentationData.strings.Conversation_AddToReadingList, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Add"), color: theme.contextMenu.primaryColor) }, action: { _, f in
                    f(.default)
                    
                    if let link = URL(string: url) {
                        let _ = try? SSReadingList.default()?.addItem(with: link, title: nil, previewText: nil)
                    }
                }))
            )
        }
        
        self.canReadHistory.set(false)
        
        let controller = ContextController(presentationData: self.presentationData, source: source, items: .single(ContextController.Items(content: .list(items))), recognizer: recognizer, gesture: gesture, disableScreenshots: false)
        controller.dismissed = { [weak self] in
            self?.canReadHistory.set(true)
        }
        
        self.window?.presentInGlobalOverlay(controller)
    }
}