//
//  O2MindMapCanvasController.swift
//  O2Platform
//
//  Created by FancyLou on 2021/12/17.
//  Copyright © 2021 zoneland. All rights reserved.
//

import UIKit
import CocoaLumberjack
import Promises

class O2MindMapCanvasController: UIViewController {

    private lazy var viewModel: O2MindMapViewModel = {
        return O2MindMapViewModel()
    }()
    
    var id: String? // 脑图id
    
    private var mindMapItem: MindMapItem? // 脑图对象
    private var root: MindRootNode? // 脑图具体内容的对象
    
    private var canvas: O2MindMapCanvasView? // 脑图画布
    
    // 底部工具栏
    private var bottomBar: O2MindMapCanvasBottomBar?
    // 点击画布
    private var selectedNode: MindNodeData? = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "脑图"
        self.view.backgroundColor = O2MindMapCanvasView.canvasBgColor // 背景色
        self.loadMindMap()
    }
    
    private func addSavebtn() {
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "保存", style: .plain, target: self, action: #selector(saveMindMap))
    }
    
    
    // MARK: - 事件
    
    // 双指缩放
    @objc private func scale(sender: UIPinchGestureRecognizer?) {
        if let scale = sender?.scale {
            if self.canvas != nil {
                self.canvas!.transform = self.canvas!.transform.scaledBy(x: scale, y: scale)
            }
            // 缩放完成后重置
            sender?.scale = 1
        }
    }
    // 移动画布
    @objc private func move(sender: UIPanGestureRecognizer? ) {
        if let transation = sender?.translation(in: self.view), let oldCenter = sender?.view?.center {
            let newCenter = CGPoint(x: oldCenter.x + transation.x, y: oldCenter.y + transation.y)
            let canvansH = self.canvas?.frame.height ?? 0
            var maxY:CGFloat = 0
            if canvansH >= self.view.frame.height {
                maxY = (canvansH - self.view.frame.height) / 2
            }
            // let maxY = (canvansH / 2) +  self.view.frame.height
            var newCenterY = CGFloat.minimum(newCenter.y, maxY + (self.view.frame.height / 2))
            newCenterY = CGFloat.maximum((self.view.frame.height / 2) - maxY, newCenterY)
            let canvansW = self.canvas?.frame.width ?? 0
            var maxX:CGFloat = 0
            if canvansW > self.view.frame.width {
                maxX = (canvansW - self.view.frame.width) / 2
            }
            // let maxX = (canvansW / 2) +  self.view.frame.width
            var newCenterX = CGFloat.minimum(newCenter.x, maxX + (self.view.frame.width / 2))
            newCenterX = CGFloat.maximum((self.view.frame.width / 2) - maxX , newCenterX)
            sender?.view?.center = CGPoint(x: newCenterX, y: newCenterY)
            // 移动完成后归零
            sender?.setTranslation(CGPoint.zero, in: self.view)
        }
    }
    
    @objc private func clickCanvas(sender: UITapGestureRecognizer?) {
        if let point = sender?.location(in: sender?.view) {
            self.selectedNode = self.canvas?.clickCanvasWithPoint(point: point)
            // 当前脑图是否可编辑
            if self.mindMapItem?.editable == true {
                if self.selectedNode != nil {
                    self.bottomBar?.show(isRoot: self.selectedNode?.isRoot() ?? false)
                } else {
                    self.bottomBar?.hide()
                }
            } else {
                DDLogError("当前用户不可编辑")
            }
        }
    }
    
    
    // MARK: - 画布相关处理
    
    ///
    /// 绘画脑图
    private func painMindMap() {
        DDLogDebug("开始绘画脑图。。。\(SCREEN_WIDTH) \(SCREEN_HEIGHT)")
        if let root = root {
            self.canvas = O2MindMapCanvasView() // 这里直接new ？？
            if let paint = self.canvas!.resolveData(json: root) {
                let size = paint.1
                DDLogDebug("canvas size \(size)")
                var x: CGFloat = 0
                var y: CGFloat = 0
                if size.width > SCREEN_WIDTH {
                    x = 1 - ((size.width - SCREEN_WIDTH ) / 2)
                }
                if size.height > SCREEN_HEIGHT {
                    y = 1 - ((size.height - SCREEN_HEIGHT) / 2)
                }
                self.view.addSubview(canvas!)
                canvas!.backgroundColor = O2MindMapCanvasView.canvasBgColor // 背景色
                canvas!.frame = CGRect(x: x, y: y, width: size.width, height: size.height)
                canvas!.repaintContent(node: paint.0)
                let pinch = UIPinchGestureRecognizer(target: self, action: #selector(scale))
                canvas!.addGestureRecognizer(pinch)
                let move = UIPanGestureRecognizer(target: self, action: #selector(move))
                canvas!.addGestureRecognizer(move)
                canvas!.addTapGesture(target: self, action: #selector(clickCanvas))
            }
            // 添加底部工具栏
            self.bottomBar = O2MindMapCanvasBottomBar.newBar(y: self.view.frame.height)
            self.view.addSubview(self.bottomBar!)
            self.bottomBar?.delegate = self
        } else {
            DDLogError("脑图内容为空！！！！")
        }
    }
    // 数据变化 重新绘制
    private func notifyDataChanged() {
        if let root = root {
            // 重新计算大小
            if let paint = self.canvas!.resolveData(json: root) {
                let size = paint.1
                var x: CGFloat = 0
                var y: CGFloat = 0
                if size.width > SCREEN_WIDTH {
                    x = 1 - ((size.width - SCREEN_WIDTH ) / 2)
                }
                if size.height > SCREEN_HEIGHT {
                    y = 1 - ((size.height - SCREEN_HEIGHT) / 2)
                }
                // 修改画布大小
                canvas!.frame = CGRect(x: x, y: y, width: size.width, height: size.height)
                // 重新绘画脑图
                canvas!.repaintContent(node: paint.0)
                if self.selectedNode != nil {
                    self.moveSelectedNode2Center()
                }
            }
        }
    }
    
    // 移动画布 让选中的节点移动到中心
    private func moveSelectedNode2Center() {
        if self.selectedNode == nil {
            DDLogError("没有选中的节点，无法移动")
            return
        }
        if let selectP = self.canvas?.getSelectNodePosition(), let selectNodeP = selectP.0, let rootNodeP = selectP.1 {
            let selectPoint = CGPoint(x: (selectNodeP.nodeBoxRect.origin.x + selectNodeP.nodeBoxRect.width / 2), y: selectNodeP.nodeBoxRect.origin.y + selectNodeP.nodeBoxRect.height / 2)
            let selectViewPoint = self.canvas!.convert(selectPoint, to: self.view)
            let rootPoint = CGPoint(x: (rootNodeP.nodeBoxRect.origin.x + rootNodeP.nodeBoxRect.width / 2), y: rootNodeP.nodeBoxRect.origin.y + rootNodeP.nodeBoxRect.height / 2)
            let rootViewPoint = self.canvas!.convert(rootPoint, to: self.view)
            var newX = (2 * rootViewPoint.x - selectViewPoint.x)
            var newY = (2 * rootViewPoint.y - selectViewPoint.y)
            DDLogInfo("新的 x ： \(newX) y: \(newY)")
            let maxY = self.view.frame.height / 2 + (self.canvas!.frame.height - self.view.frame.height) / 2
            let minY = self.view.frame.height / 2 - (self.canvas!.frame.height - self.view.frame.height) / 2
            let maxX = self.view.frame.width / 2 + (self.canvas!.frame.width - self.view.frame.width) / 2
            let minX = self.view.frame.width / 2 - (self.canvas!.frame.width - self.view.frame.width) / 2
            if newX > maxX {
                newX = maxX
            }
            if newX < minX {
                newX = minX
            }
            if newY > maxY {
                newY = maxY
            }
            if newY < minY {
                newY = minY
            }
            let newCenter = CGPoint(x: newX, y: newY)
            DDLogInfo("新的 root节点的中心点 外部位置 ： \(newCenter)")
            self.canvas?.center = newCenter
        } else {
            DDLogError("没有选中的节点或root节点")
        }
    }
    
    
    // MARK: - 后端请求相关
    /// 请求脑图数据
    private func loadMindMap() {
        if let viewId = id, !viewId.isBlank {
            self.showLoading()
            self.viewModel.loadMindMapView(id: viewId).then { (item, node) in
                self.hideLoading()
                self.mindMapItem = item
                self.title = item.name // 修改标题
                self.root = node
                self.painMindMap()
                if self.mindMapItem?.editable == true {
                    self.addSavebtn()
                }
            }.catch { err in
                self.showError(title: "请求脑图数据错误！")
            }
        } else {
            DDLogError("错误，没有脑图id，无法获取数据！！！！")
        }
    }
    
    
    //  保存脑图 结束后更新预览图
    @objc private func saveMindMap() {
        if let root = self.root,let item = self.mindMapItem, let id = item.id {
            // 需要先保存缩略图 然后把id放入MindMapItem中 然后保存对象
            self.showLoading()
            if let image = self.canvas?.saveAsImage() {
                self.viewModel.saveMindMapThumb(image: image, id: id).then { imgId -> Promise<String> in
                    DDLogInfo("保存缩略图成功！\(imgId)")
                    let content = root.toJSONString() ?? ""
                    item.content = content
                    item.fileVersion = item.fileVersion ?? 0 + 1
                    item.icon = imgId
                    return self.viewModel.saveMindMap(mind: item)
                }.then { _ in
                    self.showSuccess(title: "保存成功！")
                    self.mindMapItem = item
                }.catch { err in
                    DDLogError(err.localizedDescription)
                    self.showError(title: "保存失败！")
                }
            }
        }
    }
    
    
  
    // MARK: - 节点工具栏操作
    
    // 创建子节点
    private func createSubNode() {
        DDLogDebug("创建子节点")
        if self.selectedNode == nil {
            DDLogError("请先选择节点！！")
            return
        }
        self.showPromptAlert(title: "创建子节点", message: "请输入节点内容", inputText: "") { action, result in
            if result == "" || result.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
                self.showError(title: "请输入节点内容！")
                return
            }
            if let node = self.root?.root {
                let newNode = self.createSubNodeWithTextRecursion(node: node, text: result)
                self.root?.root = newNode
                self.notifyDataChanged()
            } else {
                DDLogError("脑图数据对象不存在，无法创建。。。")
            }
        }
    }
    
    // 创建新的子节点到对象中
    private func createSubNodeWithTextRecursion(node: MindNode, text:String)-> MindNode {
        if node.data?.id != nil && node.data?.id == self.selectedNode?.id {
            let newNode = MindNode()
            let newData = MindNodeData()
            newData.text = text
            let time = Date().milliStamp
            newData.id = "mind_\(time)"
            newNode.data = newData
            newNode.children = []
            node.children?.append(newNode)
            self.selectedNode = newData
            self.canvas?.reSelected(newSelected: newData)
        } else {
            if let nChild = node.children {
                var children: [MindNode] = []
                for item in nChild {
                    let newChild = self.createSubNodeWithTextRecursion(node: item, text: text)
                    children.append(newChild)
                }
                node.children = children
            }
        }
        return node
    }
    
    // 创建同级节点
    private func createSameLevelNode() {
        DDLogDebug("创建同级节点")
        if self.selectedNode == nil {
            DDLogError("请先选择节点！！")
            return
        }
        self.showPromptAlert(title: "创建同级节点", message: "请输入节点内容", inputText: "") { action, result in
            if result == "" || result.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
                self.showError(title: "请输入节点内容！")
                return
            }
            if let node = self.root?.root {
                let newNode = self.createSameLevelNodeWithTextRecursion(node: node, text: result)
                self.root?.root = newNode
                self.notifyDataChanged()
            } else {
                DDLogError("脑图数据对象不存在，无法创建同级节点。。。")
            }
        }
    }
    
    // 创建新的同级节点到对象中
    private func createSameLevelNodeWithTextRecursion(node: MindNode, text:String)-> MindNode {
        if let nChild = node.children {
            var children: [MindNode] = []
            for item in nChild {
                if item.data?.id != nil && item.data?.id == self.selectedNode?.id {
                    let newNode = MindNode()
                    let newData = MindNodeData()
                    newData.text = text
                    let time = Date().milliStamp
                    newData.id = "mind_\(time)"
                    newNode.data = newData
                    newNode.children = []
                    children.append(newNode)
                    self.selectedNode = newData
                    self.canvas?.reSelected(newSelected: newData)
                    // 忘了添加兄弟节点
                    children.append(item)
                } else {
                    let newChild = self.createSubNodeWithTextRecursion(node: item, text: text)
                    children.append(newChild)
                }
            }
            node.children = children
        }
        return node
    }
    
    // 修改节点文字
    private func updateNodeText() {
        DDLogDebug("修改节点文字内容")
        if self.selectedNode == nil {
            DDLogError("请先选择节点！！")
            return
        }
        self.showPromptAlert(title: "修改节点内容", message: "请输入节点内容", inputText: self.selectedNode?.text ?? "") { action, result in
            if result == "" || result.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
                self.showError(title: "请输入节点内容！")
                return
            }
            if let node = self.root?.root {
                let newNode = self.updateNodeTextRecursion(node: node, text: result)
                self.root?.root = newNode
                self.notifyDataChanged()
            } else {
                DDLogError("脑图数据对象不存在，无法修改节点文字")
            }
        }
    }
    private func updateNodeTextRecursion(node: MindNode, text:String)-> MindNode {
        if node.data?.id != nil && node.data?.id == self.selectedNode?.id {
            let newData = node.data!
            newData.text = text
            node.data = newData
            self.selectedNode = newData
            self.canvas?.reSelected(newSelected: newData)
        } else {
            if let nChild = node.children {
                var children: [MindNode] = []
                for item in nChild {
                    let newChild = self.updateNodeTextRecursion(node: item, text: text)
                    children.append(newChild)
                }
                node.children = children
            }
        }
        return node
    }
    // 删除节点
    private func deleteNode() {
        DDLogDebug("删除选中的节点")
        if self.selectedNode == nil {
            DDLogError("请先选择节点！！")
            return
        }
        self.showDefaultConfirm(title: "提示", message: "确定要删除【\(self.selectedNode?.text ?? "")】这个节点吗") { action in
            if let node = self.root?.root {
                let newNode = self.deleteSelectNodeRecursion(node: node)
                self.root?.root = newNode
                self.notifyDataChanged()
            } else {
                DDLogError("脑图数据对象不存在，无法删除")
            }
        }
    }
    private func deleteSelectNodeRecursion(node: MindNode)-> MindNode {
        if let nChild = node.children {
            var children: [MindNode] = []
            for item in nChild {
                if item.data?.id != nil && item.data?.id == self.selectedNode?.id {
                    // 找到后清除选中的节点
                    self.selectedNode = nil
                    self.canvas?.reSelected(newSelected: nil)
                } else {
                    let newChild = self.deleteSelectNodeRecursion(node: item)
                    children.append(newChild)
                }
            }
            node.children = children
        }
        return node
    }
    // 节点设置超链接
    private func addLink() {
        DDLogDebug("添加超链接")
        if self.selectedNode == nil {
            DDLogError("请先选择节点！！")
            return
        }
        let dialog = O2MindMapAddLinkDialog.mindMapNodeLinkDialog(link: self.selectedNode?.hyperlink, linkTitle: self.selectedNode?.hyperlinkTitle, delegate: self)
        dialog.show()
    }
    private func updateNodeLink(link:String, linkTitle: String) {
        if let node = self.root?.root {
            let newNode = self.updateNodeLinkRecursion(node: node, link: link, linkTitle: linkTitle)
            self.root?.root = newNode
            self.notifyDataChanged()
        } else {
            DDLogError("脑图数据对象不存在，无法修改超链接")
        }
    }
    private func updateNodeLinkRecursion(node: MindNode, link:String, linkTitle: String)-> MindNode {
        if node.data?.id != nil && node.data?.id == self.selectedNode?.id {
            let newData = node.data!
            newData.hyperlink = link
            newData.hyperlinkTitle = linkTitle
            node.data = newData
            self.selectedNode = newData
            self.canvas?.reSelected(newSelected: newData)
        } else {
            if let nChild = node.children {
                var children: [MindNode] = []
                for item in nChild {
                    let newChild = self.updateNodeLinkRecursion(node: item, link: link, linkTitle: linkTitle)
                    children.append(newChild)
                }
                node.children = children
            }
        }
        return node
    }
    
    private func addIcon() {
        DDLogDebug("添加图标")
        if self.selectedNode == nil {
            DDLogError("请先选择节点！！")
            return
        }
        let dialog = O2MindMapAddIconDialog.mindMapNodeIconDialog(progress: self.selectedNode?.progress, priority: self.selectedNode?.priority, delegate: self)
        dialog.show()
    }
    private func updateNodeIcons(progress:Int?, priority:Int?) {
        if let node = self.root?.root {
            let newNode = self.updateNodeIconsRecursion(node: node, progress: progress, priority: priority)
            self.root?.root = newNode
            self.notifyDataChanged()
        } else {
            DDLogError("脑图数据对象不存在，无法修改Icons。")
        }
    }
    private func updateNodeIconsRecursion(node: MindNode, progress:Int?, priority:Int?)-> MindNode {
        if node.data?.id != nil && node.data?.id == self.selectedNode?.id {
            let newData = node.data!
            newData.progress = progress
            newData.priority = priority
            node.data = newData
            self.selectedNode = newData
            self.canvas?.reSelected(newSelected: newData)
        } else {
            if let nChild = node.children {
                var children: [MindNode] = []
                for item in nChild {
                    let newChild = self.updateNodeIconsRecursion(node: item, progress: progress, priority: priority)
                    children.append(newChild)
                }
                node.children = children
            }
        }
        return node
    }
    
    // 节点添加图片
    private func addImage() {
        DDLogDebug("添加图片")
        if self.selectedNode == nil {
            DDLogError("请先选择节点！！")
            return
        }
        var hasImage = false
        if let _ = self.selectedNode?.image {
            hasImage = true
        }
        var menus :[UIAlertAction] = []
        if hasImage {
            let deleteBtn = UIAlertAction(title: "删除图片", style: .destructive) { (ok) in
                 DDLogInfo("删除图片")
                self.deleteImage()
            }
            menus.append(deleteBtn)
        }
        let chooseImg = UIAlertAction(title: "选择图片", style: .default) { (ok) in
            DDLogInfo("选择图片")
            self.chooseImageForNode()
        }
        menus.append(chooseImg)
        let camera = UIAlertAction(title: "拍照", style: .default) { (ok) in
            DDLogInfo("拍照")
            self.takePhotoImageForNode()
        }
        menus.append(camera)
        
        self.showSheetAction(title: "添加图片", message: "", actions: menus)
    }
    // 删除节点上的图片
    private func deleteImage() {
        if let node = self.root?.root {
            let newNode = self.updateNodeImageRecursion(node: node, image: nil, imageId: nil, size: nil)
            self.root?.root = newNode
            self.notifyDataChanged()
        } else {
            DDLogError("脑图数据对象不存在，无法删除图片")
        }
    }
    // 选择图片加入节点
    private func chooseImageForNode() {
        self.choosePhotoWithImagePicker { fileName, data in
            DDLogDebug("图片：\(fileName)")
            var size:CGSize? = nil
            if let image: UIImage = UIImage(data: data) {
                DDLogDebug("图片：\(image.size)")
                size = image.size
            }
            self.uploadImage(fileName: fileName, data: data, size: size)
        }
    }
    // 拍照加入节点
    private func takePhotoImageForNode() {
        self.takePhoto(delegate: self)
    }
    // 上传图片到服务器
    private func uploadImage(fileName: String, data: Data, size: CGSize?) {
        self.showLoading()
        self.viewModel
            .saveMindMapNodeImage(filename: fileName, data: data, id: self.mindMapItem!.id!)
            .then { id in
                self.hideLoading()
                // 生成url 计算size对象
                let urlstr = O2AuthSDK.shared.getFileDownloadUrl(fileId: id)
                let imageSize = self.calcSize(size: size)
                if let node = self.root?.root {
                    let newNode = self.updateNodeImageRecursion(node: node, image: urlstr, imageId: id, size: imageSize)
                    self.root?.root = newNode
                    self.notifyDataChanged()
                } else {
                    DDLogError("脑图数据对象不存在，无法删除图片")
                }
            }.catch {  err in
                DDLogError(err.localizedDescription)
                self.showError(title: "图片上传失败！")
            }
    }
    // 计算图片大小，最大的尺寸400 等比例压缩
    private func calcSize(size:CGSize?)-> MindNodeImageSize? {
        if let s = size {
            let width = s.width
            let height = s.height
            
            var newH: CGFloat = 400
            if height <= 0 {
                newH = 400
            } else {
                newH = height
            }
            var newW: CGFloat = 400
            if width <= 0 {
                newW = 400
            }else {
                newW = width
            }
            
            if (height > width) {
              if (height > 400) {
                let scale = height / 400
                newH = 400
                newW = width / scale
              }
            } else {
              if (width > 400) {
                let scale = width / 400;
                newH = height / scale
                newW = 400
              }
            }
            let imageSize = MindNodeImageSize()
            imageSize.width = Int(newW)
            imageSize.height = Int(newH)
            return imageSize
        }
        return nil
    }
    // 更新图片对象到选中的节点
    private func updateNodeImageRecursion(node: MindNode, image:String?, imageId:String?, size: MindNodeImageSize?)-> MindNode {
        if node.data?.id != nil && node.data?.id == self.selectedNode?.id {
            let newData = node.data!
            newData.image = image
            if let _ = image {
            } else {
                newData.imageTitle = nil
            }
            newData.imageId = imageId
            newData.imageSize = size
            node.data = newData
            self.selectedNode = newData
            self.canvas?.reSelected(newSelected: newData)
        } else {
            if let nChild = node.children {
                var children: [MindNode] = []
                for item in nChild {
                    let newChild = self.updateNodeImageRecursion(node: item, image: image, imageId: imageId, size: size)
                    children.append(newChild)
                }
                node.children = children
            }
        }
        return node
    }
    
}

// MARK: - 点击底部工具栏按钮
extension O2MindMapCanvasController: O2MindMapCanvasBottomBtnDelegate {
    
    func clickBtn(type: O2MindMapCanvasBottomBtnType) {
        switch type {
        case .createSubNode:
            self.createSubNode()
            break
        case .createSameLevelNode:
            self.createSameLevelNode()
            break
        case .editNode:
            self.updateNodeText()
            break
        case .deleteNode:
            self.deleteNode()
            break
        case .addImg:
            self.addImage()
            break
        case .addLink:
            self.addLink()
            break
        case .addIcon:
            self.addIcon()
            break
        }
    }
}

// MARK: - 添加超链接的delegate
extension O2MindMapCanvasController: O2MindMapAddLinkDialogDelegate {
    func deleteLink() {
        DDLogInfo("删除超链接")
        self.updateNodeLink(link: "", linkTitle: "")
    }
    
    func saveLink(link: String, linkTitle: String) {
        DDLogInfo("保存超链接 link: \(link) linkTitle: \(linkTitle)")
        self.updateNodeLink(link: link, linkTitle: linkTitle)
    }
    
}

// MARK: - 添加图标delegate
extension O2MindMapCanvasController: O2MindMapAddIconDialogDelegate {
    func saveIcons(progress: Int?, priority: Int?) {
        DDLogInfo("保存图标 progress: \(String(describing: progress)) priority: \(String(describing: priority))")
        self.updateNodeIcons(progress: progress, priority: priority)
    }
}

// MARK: - 拍照返回
extension O2MindMapCanvasController: UIImagePickerControllerDelegate & UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        if let image = info[.editedImage] as? UIImage, let newData = image.pngData() {
            let fileName = "\(UUID().uuidString).png"
            let size = image.size
            self.uploadImage(fileName: fileName, data: newData, size: size)
        } else {
            DDLogError("没有选择到图片！")
        }
        picker.dismiss(animated: true, completion: nil)
    }
}
