//
//  DiyPaperTemplateBaseView.swift
//  ClockWidget
//
//  Created by fff on 2024/6/28.
//

import UIKit

// 按照固定比例(375 * 812)初始化, 针对不同屏幕进行缩放大小
struct DiyPaperConfig {
    static let renderSize = CGSize(width: 239, height: 515)
    static let whRatio = 375.0 / 812.0
}

/// LivePhoto模板时长配置
struct LivePhotoDuration {
    /// app内动画时长
    var innerDuration: TimeInterval
    /// 保持时, 动画时长
    var outDuration: TimeInterval
    /// 保存时, 视频录制时长
    var recordDuration: TimeInterval
}

protocol DiyPaperTemplateBaseProtocol {
    func initialTransform(at index: Int) -> DiyElementTransform
}

// 模板内容基类
class DiyPaperTemplateBaseView: UIView, DiyPaperTemplateBaseProtocol {
    weak var delegate: DiyPaperTemplateDelegate?
    
    lazy var imageView = UIImageView()
    
    lazy var currentElements: [DiyElement] = []
    
    lazy var scene = DiyElementScene.detail
    
    lazy var panGesture = UIPanGestureRecognizer(target: self, action: #selector(onPan(_:)))
    lazy var tapGesture = UITapGestureRecognizer(target: self, action: #selector(onTap(_:)))
    
    override init(frame: CGRect) {
        let frame = frame != .zero ? frame : CGRect(origin: .zero, size: DiyPaperConfig.renderSize)
        super.init(frame: frame)
        self.semanticContentAttribute = .forceLeftToRight
        imageView.contentMode = .scaleAspectFill
        imageView.frame = bounds
        addSubview(imageView)
        
        panGesture.isEnabled = false
        addGestureRecognizer(panGesture)
        addGestureRecognizer(tapGesture)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 初始化模板
    func initialUI(with model: DiyPaperTemplateModel) {
        for (idx, element) in model.elements.compactMap({ $0.element }).enumerated() {
            if let element = element as? DiyElement {
                setup(element: element, config: initialTransform(at: idx))
                didFinishedInitialElement(element, at: idx)
            }
        }
        
        updateBackground(model.background)
    }
    
    // 修改背景
    func updateBackground(_ background: Any?) {
        imageView.backgroundColor = .clear
        imageView.image = nil
        
        guard let background = background else {
            return
        }
        if let color = background as? UIColor {
            imageView.backgroundColor = color
        } else if let image = background as? UIImage {
            imageView.image = image
        } else if let string = background as? String {
            if string.hasPrefix("http") {
                // 网络图片
                imageView.setAsyncImage(urlString: string)
            } else if string.hasPrefix("#") {
                // 颜色
                imageView.backgroundColor = string.uiColor
            } else if let image = UIImage(named: string) {
                imageView.image = image
            }
        }
    }
    
    // 手动添加元素时, 元素对应的位置
    func defaultTransform(for element: DiyElement) -> DiyElementTransform {
        if let _ = element as? DiyTextElement {
            return DiyElementTransform(maxWidth: UIScreen.width-80, position: CGPoint(x: width/2.0, y: 174))
        }else if let _ = element as? DiyStickerModel {
            return DiyElementTransform(size: CGSize(width: 60, height: 60), position: CGPoint(x: width/2.0, y: 174))
        }
        return DiyElementTransform(size: CGSize(width: 120, height: 120), position: CGPoint(x: width/2.0, y: 174))
    }
    
    // 初始模版, 元素的位置
    func initialTransform(at index: Int) -> DiyElementTransform {
        return DiyElementTransform(size: .zero, position: .zero)
    }
    
    /// 添加元素完成, 子类可重写, 实现添加完成后的操作
    func didFinishedInitialElement(_ element: DiyElement, at index: Int) {}
    
    // 添加元素
    @discardableResult
    func setup(element: DiyElement, config: DiyElementTransform) -> DiyElementView {
        currentElements.append(element)
        
        let elementView = element.elementView
        addSubview(elementView)
        
        if let view = elementView as? DiyElementBaseView {
            view.setupLayout(with: config)
            view.scene = scene
            if let corRadius = config.corRadius {
                view.setContentView(corRadius: corRadius)
            }
            
            view.setEditBlock = { [weak self] in
                guard let self = self else { return }
                self.cleanSubviewsEditStatus()
                if element.supportEditActions.contains(.move) {
                    self.panGesture.isEnabled = true
                }
                self.delegate?.template(self, didOparate: .selected, for: element)
            }
            view.removeViewBlock = { [weak self] in
                guard let self = self else { return }
                self.removeElementView(element)
                self.delegate?.template(self, didOparate: .delete, for: element)
            }
            view.beginMovingBlock = { [weak self] in
                guard let self = self else { return }
                self.delegate?.template(self, didOparate: .beginMoving, for: element)
            }
            view.endMovingBlock = { [weak self] in
                guard let self = self else { return }
                self.delegate?.template(self, didOparate: .endMoving, for: element)
            }
        }
        
        return elementView
    }
    
    // 新增元素
    func add(element: DiyElement) {
        cleanSubviewsEditStatus()//清除之前的活跃
        panGesture.isEnabled = true
        let elementView = setup(element: element, config: defaultTransform(for: element))
        // 选中
        (elementView as? DiyElementBaseView)?.isEditing = true
        
        UIImpactFeedbackGenerator(style: .soft).impactOccurred()
    }
    
    // 获取model对应的view
    func elementView(for element: DiyElement) -> DiyElementView? {
        if let other = element as? NSObject {
            for view in subviews {
                if let elementView = view as? DiyElementView, let element = elementView.element as? NSObject, element == other {
                    return elementView
                }
            }
        }
        return nil
    }
    
    // 选中model对应的view
    func selected(for element: DiyElement) {
        if let view = elementView(for: element) as? DiyElementBaseView {
            view.setEditBlock()
            view.isEditing = true
        }
    }
    
    /// 当前选中编辑的view
    var currentEditView: DiyElementBaseView? {
        return subviews.first(where: { ($0 as? DiyElementBaseView)?.isEditing ?? false }) as? DiyElementBaseView
    }
    
    // 移动手势事件
    @objc func onPan(_ gesture: UIPanGestureRecognizer) {
        guard let editView = currentEditView else {
            return
        }
        switch gesture.state {
        case .began:
            self.delegate?.template(self, didOparate: .beginMoving, for: editView.element)
            
        case .changed:
            let translation = gesture.translation(in: self)
            let center = CGPoint(x: editView.center.x + translation.x, y: editView.center.y + translation.y)
            editView.snp.updateConstraints { make in
                make.center.equalTo(center)
            }
            gesture.setTranslation(.zero, in: self)
            
        case .ended, .cancelled, .failed:
            self.delegate?.template(self, didOparate: .endMoving, for: editView.element)
        default:
            break
        }
    }
    // 移动手势事件
    @objc func onTap(_ gesture: UIPanGestureRecognizer) {
        //点击空白,清除所有活跃
        cleanSubviewsEditStatus()
    }
    
    
    
    // MARK: 动画相关
    var livePhotoDuration: LivePhotoDuration? { return nil }
    
    func startAnimations(isRepeat: Bool, inApp: Bool = true) {}
    
    func stopAnimations() {
        subviews.filter({ $0 is DiyElementBaseView }).forEach { view in
            if let elementView = view as? DiyElementBaseView {
                elementView.layer.removeAllAnimations()
                elementView.setState(isPreview: false)
            }
        }
    }
    
    func setPreviewState(isOn: Bool) {
        if isOn {
            startAnimations(isRepeat: true)
        } else {
            stopAnimations()
        }
        switchChildElementsState(isPreview: isOn)
    }
    
    /// 切换到预览模式
    func startDownloading() {
        switchChildElementsState(isPreview: true)
    }
    
    func finishedDownload() {
        switchChildElementsState(isPreview: false)
    }
    
    func switchChildElementsState(isPreview: Bool) {
        subviews.filter({ $0 is DiyElementBaseView }).forEach { obj in
            (obj as? DiyElementBaseView)?.setState(isPreview: isPreview)
        }
    }
}

extension DiyPaperTemplateBaseView {
    /** 清除所有添加子视图活动状态 */
    func cleanSubviewsEditStatus() {
        panGesture.isEnabled = false
        subviews.forEach { sview in
            if let sview = sview as? DiyElementBaseView {
                sview.isEditing = false
            }
        }
    }
    
    /** 移除视图 */
    func removeElementView(_ element: DiyElement?) {
        guard let element = element else { return }
        if let elementView = elementView(for: element) {
            elementView.removeFromSuperview()
            currentElements.removeAll(where: { ($0 as? NSObject) == (elementView.element as? NSObject) })
        }
    }
}

extension DiyPaperTemplateBaseView: CAAnimationDelegate {
    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        if flag {
            finishedDownload()
        }
    }
}
