//
//  LLQ_HomeWebControlView.swift
//  PrivateBrowser
//
//  Created by MAC on 2022/6/13.
//

import WebKit
import Foundation
import RxSwift
class LLQ_HomeWebControlView: UIView {
    private var viewModel: LLQ_HomeViewModel?
    private var webArray: [LLQ_HomeWebContainerView] = [LLQ_HomeWebContainerView]() {
        didSet {
            
        }
    }
    private var activeWebView: LLQ_HomeWebContainerView? 
    private var disposeBg = DisposeBag()
    var viewISApearing: Bool = false
    override func awakeFromNib() {
        super.awakeFromNib()
        
    }
    
    public func setViewModel(viweModel: LLQ_HomeViewModel) {
        self.viewModel = viweModel
        
        let binder = Binder<LLQ_HomeSinglePageViewModel>.init(self, scheduler: MainScheduler.asyncInstance) { view, singleVM in
            view.addWebView(vm: singleVM)
        }
        self.viewModel?.addPageStream.asObservable().bind(to: binder).disposed(by: disposeBg)
        
        // switch to page
        self.viewModel?.switchToWebPageStream.asObservable().bind(to: Binder<LLQ_HomeSinglePageViewModel>.init(self, scheduler: MainScheduler.asyncInstance) { view, singleVM in
            guard view.activeWebView?.tag != singleVM.webViewTag else {
                return
            }
            guard let webView = view.findHomeWebViewBy(vm: singleVM) else {return}
            view.activeWebView = webView
            view.updateWebs()
        }).disposed(by: disposeBg)
        
        // delete page
        self.viewModel?.deleteWebPageStream.asObservable().bind(to: Binder<LLQ_HomeSinglePageViewModel>.init(self, scheduler: MainScheduler.asyncInstance, binding: { view, singleViewModel in
            if let webView = self.webArray.filter({ $0.tag == singleViewModel.webViewTag
            }).first {
                webView.removeFromSuperview()
                self.webArray.removeAll { return $0.tag == singleViewModel.webViewTag }
                if self.activeWebView?.tag == singleViewModel.webViewTag {
                    self.activeWebView = nil
                }
            }
        })).disposed(by: disposeBg)
        
        self.viewModel?.styleStream.asObservable().bind(to: Binder<HomePageStyle>.init(self, scheduler: MainScheduler.asyncInstance, binding: { view, style in
            view.updateWebs()
        })).disposed(by: disposeBg)
    }
    
    private func findHomeWebViewBy(vm: LLQ_HomeSinglePageViewModel) -> LLQ_HomeWebContainerView? {
        for webView in self.webArray {
            if webView.tag == vm.webViewTag {
                return webView
            }
        }
        return nil
    }
    
    public func addWebView(vm: LLQ_HomeSinglePageViewModel){
        let webView = LLQ_HomeWebContainerView.init(frame: .zero, vm: vm, configuration: WKWebViewConfiguration.init())
        self.addSubview(webView)
        webView.superV = self
        webView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        webView.tag = vm.webViewTag
        self.activeWebView = webView
        self.webArray.append(webView)
        self.updateWebs()
        
        vm.deleteStream.asObservable().subscribe { [weak vm, weak self] _ in
            self?.deleteWeb(webTag: vm?.webViewTag)
        }.disposed(by: disposeBg)
        
        vm.goPreviouseStream.asObservable().subscribe {[weak self] _ in
            
        }.disposed(by: disposeBg)
        
        vm.goForwardStream.asObservable().subscribe {[weak self] _ in
            
        }.disposed(by: disposeBg)
        
        vm.mutiWindowsStream.asObservable().subscribe {[weak self] _ in
            self?.doSnapIfNeeded()
            self?.viewModel?.toListControllerStream.accept(true)
        }.disposed(by: disposeBg)
        
        vm.goHomeStream.asObservable().subscribe {[weak self] _ in
            self?.viewModel?.resetHomePage()
        }.disposed(by: disposeBg)
        
        vm.startLoadUrlStringStream.asObservable().subscribe {[weak self, weak vm] event in
            switch event {
            case .next(let urlString):
                if self?.viewModel?.activeWebViewTag == vm?.webViewTag {
                    self?.viewModel?.textFieldUpdateTextStream.accept(urlString)
                }
                break
            default:
                break
            }
        }.disposed(by: disposeBg)
    
        vm.openNewWebStream.asObservable().subscribe { [weak self] event in
            switch event {
            case .next(let string):
                self?.viewModel?.openWeb(urlString: string)
                break
            default:
                break
            }
        }.disposed(by: disposeBg)
        
        if let viewModel = viewModel {
            vm.textFieldUpdateTextStream.asObservable().bind(to: viewModel.textFieldUpdateTextStream).disposed(by: disposeBg)

        }
    }
    
    func doSnapIfNeeded(){
        guard let activeWebView = activeWebView else {
            return
        }
        if self.viewISApearing, activeWebView.superview != nil{
            activeWebView.webView.viewModel.snapShot()
        }
    }
    
    public func updateWebs(){
        NSLog("apere: \(self.viewISApearing) style:\(self.viewModel?.styleStream.value)  superView: \(activeWebView?.superview)")
        guard let activeWebView = activeWebView else {
            return
        }
        if self.viewISApearing, activeWebView.superview != nil{
            activeWebView.webView.viewModel.snapShot()
        }
        if self.viewModel?.styleStream.value == .searched {
            if activeWebView.superview == nil {
                self.addSubview(activeWebView)
                activeWebView.snp.makeConstraints { make in
                    make.edges.equalToSuperview()
                }
            }
        } else {
            activeWebView.removeFromSuperview()
        }
        for webView in self.webArray {
            if activeWebView.tag == webView.tag {continue}
            webView.removeFromSuperview()
        }
        
    }
    
    public func deleteWeb(webTag: Int?) {
        guard let webTag = webTag else {
            return
        }
        var deleteWeb: LLQ_HomeWebContainerView?
        for web in self.webArray {
            if web.tag == webTag {
                deleteWeb = web
                break
            }
        }
        if let web = deleteWeb {
            self.webArray.removeAll { w in
                return w.tag == web.tag
            }
            web.removeFromSuperview()
        }
    }

}
