//
//  LNImageUploadView.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/25.
//

import Foundation
import UIKit
import SnapKit


protocol LNImageUploadViewDelegate: AnyObject {
    func onImageUploadView(view: LNImageUploadView, didUploadImage url: String)
    func onImageUploadViewStartUpload(view: LNImageUploadView)
    func onImageUploadViewDidClickDelete(view: LNImageUploadView)
}
extension LNImageUploadViewDelegate {
    func onImageUploadView(view: LNImageUploadView, didUploadImage url: String) {}
    func onImageUploadViewStartUpload(view: LNImageUploadView) {}
    func onImageUploadViewDidClickDelete(view: LNImageUploadView) {}
}


class LNImageUploadView: UIImageView {
    private let defaultView = UIImageView()
    var showDefault: Bool = false {
        didSet {
            defaultView.isHidden = image != nil || !showDefault
        }
    }
    
    private let progressCover = UIView()
    let progressView = LNCircleProgressView()
    private let failedIc = UIImageView()
    
    private var curTask: String?
    private(set) var imageUrl: String?
    
    private let deleteButton = UIButton()
    var showClearButton: Bool = false {
        didSet {
            deleteButton.isHidden = !showClearButton || image == nil
        }
    }
    
    var uploadType: LNUploadFileType = .feedback
    weak var delegate: LNImageUploadViewDelegate?
    
    override var image: UIImage? {
        didSet {
            defaultView.isHidden = image != nil || !showDefault
        }
    }
    
    override init(image: UIImage? = nil) {
        super.init(image: image)
        
        setupViews()
    }
    
    func loadImage(url: String) {
        reset()
        
        imageUrl = url
        
        sd_setImage(with: URL(string: url))
        progressCover.isHidden = true
        
        if showClearButton {
            deleteButton.isHidden = false
        }
    }
    
    func uploadImage(image: UIImage) {
        reset()
        
        self.image = image
        
        progressCover.isHidden = false
        failedIc.isHidden = true
        progressView.isHidden = false
        
        if showClearButton {
            deleteButton.isHidden = false
        }
        
        let suffix = "\(Int(image.size.width))x\(Int(image.size.height)).jpeg"
        delegate?.onImageUploadViewStartUpload(view: self)
        curTask = LNFileUploader.shared.startUpload(
            type: uploadType, fileData: image.jpegData(compressionQuality: 1.0)!,
            suffix: suffix)
        { [weak self] progress in
            guard let self else { return }
            progressView.setProgress(CGFloat(progress), animated: true)
        } completionHandler: { [weak self] url, err in
            guard let self else { return }
            
            curTask = nil
            
            if let url, err == nil {
                imageUrl = url
                
                progressCover.isHidden = true
                
                let key = SDWebImageManager.shared.cacheKey(for: URL(string: url))
                SDWebImageManager.shared.imageCache.store?(image, imageData: nil, forKey: key, context: nil, cacheType: .all)
                delegate?.onImageUploadView(view: self, didUploadImage: url)
            } else if url == nil, let err {
                showToast(err)
                
                failedIc.isHidden = false
                progressView.isHidden = true
            }
        }
    }
    
    func cancelUpload() {
        if let curTask {
            LNFileUploader.shared.cancelUpload(taskID: curTask)
        }
    }
    
    func reset() {
        cancelUpload()
        
        image = nil
        imageUrl = nil
        curTask = nil
        deleteButton.isHidden = true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNImageUploadView {
    private func setupViews() {
        isUserInteractionEnabled = true
        contentMode = .scaleAspectFill
        
        let noneView = buildDefault()
        addSubview(noneView)
        noneView.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        
        let progress = buildProgress()
        addSubview(progress)
        progress.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        let clear = buildClearButton()
        addSubview(clear)
        clear.snp.makeConstraints { make in
            make.top.equalToSuperview()
            make.trailing.equalToSuperview()
        }
    }
    
    private func buildDefault() -> UIView {
        let config = UIImage.SymbolConfiguration(pointSize: 17)
        defaultView.image = .init(systemName: "plus", withConfiguration: config)
        defaultView.tintColor = .text_3
        defaultView.isHidden = true
        
        return defaultView
    }
    
    private func buildProgress() -> UIView {
        progressCover.isHidden = true
        progressCover.backgroundColor = .black.withAlphaComponent(0.3)
        
        progressCover.addSubview(progressView)
        progressView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.height.equalTo(30)
        }
        
        failedIc.isHidden = true
        failedIc.image = .init(named: "ic_im_chat_send_failed")
        failedIc.onTap { [weak self] in
            guard let self else { return }
            guard let image = self.image else { return }
            uploadImage(image: image)
        }
        progressCover.addSubview(failedIc)
        failedIc.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.height.equalTo(24)
        }
        
        return progressCover
    }
    
    private func buildClearButton() -> UIView {
        deleteButton.isHidden = true
        deleteButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            reset()
            
            delegate?.onImageUploadViewDidClickDelete(view: self)
        }), for: .touchUpInside)
        deleteButton.snp.makeConstraints { make in
            make.width.height.equalTo(28)
        }
        
        let config = UIImage.SymbolConfiguration(pointSize: 7)
        let icon = UIImageView()
        icon.image = .init(systemName: "xmark", withConfiguration: config)
        icon.contentMode = .center
        icon.tintColor = .white
        icon.backgroundColor = .black.withAlphaComponent(0.5)
        icon.layer.cornerRadius = 8
        deleteButton.addSubview(icon)
        icon.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.height.equalTo(16)
        }
        
        return deleteButton
    }
}
