//
//  SearchResultViewController.swift
//  ColorfulWallpaper
//
//  Created by nkl on 2024/9/11.
//
//import ADManager
import Combine
import Foundation
import GoogleMobileAds
import Kingfisher
import MJRefresh
import TSVideoKit
import UIKit

class SearchResultViewController: LWBGViewController {
    var viewModel: SearchResultViewModel = .init()
    private var cancellables = [AnyCancellable]()

    lazy var listView: UITableView = {
        let tabView = UITableView()
        tabView.dataSource = viewModel
        tabView.delegate = self
        tabView.mj_header = defaultHeadr
        tabView.mj_footer = defaultFooter
        tabView.separatorStyle = .none
        tabView.register(SongDownloadCell.self, forCellReuseIdentifier: "SongDownloadCell")
        tabView.backgroundColor = .clear
        return tabView
    }()

    var defaultHeadr: MJRefreshNormalHeader {
        let header = MJRefreshNormalHeader { [weak self] in
            self?.viewModel.reloadData()
        }
        header.lastUpdatedTimeLabel?.isHidden = true
        header.stateLabel?.isHidden = true
        header.setTitle("", for: .idle)
        header.loadingView?.color = .white
        return header
    }

    var defaultFooter: MJRefreshAutoNormalFooter {
        let footer = MJRefreshAutoNormalFooter { [weak self] in
            self?.viewModel.loadMoreData()
        }
        footer.loadingView?.color = .black
        footer.isRefreshingTitleHidden = true
        footer.setTitle("", for: .idle)
        return footer
    }

    lazy var loadingView: CWLoadingView = .init()

    lazy var stateView: SearchResultStateView = SearchResultStateView()

    lazy var searchBar: CWSearchTextBar = {
        let bar = CWSearchTextBar()
        bar.textFiled.delegate = self
        bar.customCornerRadius = 8
        return bar
    }()

    lazy var searchButton: UIButton = {
        let btn = UIButton()
        btn.setTitle("Search".localized(), for: .normal)
        btn.setTitleColor(.white, for: .normal)
        btn.titleLabel?.font = .systemFont(ofSize: 14)
        btn.addTarget(self, action: #selector(researchKeyword), for: .touchUpInside)
        return btn
    }()

    lazy var backButton: UIButton = {
        let btn = UIButton()
        btn.setImage(.naviBackWhite, for: .normal)
        btn.addTarget(self, action: #selector(popupCurrentVc), for: .touchUpInside)
        return btn
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        bgImageView.image = .viewMainBg
        view.backgroundColor = .hexColor("#121325")
        addChildren()
        makeConstraints()
        addNotifaction()
        loadData()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        PlayerManager.shared.miniBar.isHidden = false
        PlayerManager.shared.rootVc?.moveDownMiniBar()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    }

    override func addNotifaction() {
        super.addNotifaction()
        viewModel.$datas.receive(on: DispatchQueue.main).sink { [weak self] _ in
            self?.listView.reloadData()
            self?.endRefreshing()
        }.store(in: &cancellables)

        viewModel.$loadState.receive(on: DispatchQueue.main).sink { [weak self] states in

            switch states {
            case .loading:
                self?.loadingView.isHidden = false
                self?.listView.scrollToTop()
                break
            case .fail:
                self?.stateView.state = .nonet
                self?.stateView.isHidden = false
                self?.loadingView.isHidden = true
            case .empty:
                self?.stateView.state = .noMusic
                self?.stateView.isHidden = false
                self?.loadingView.isHidden = true
            default:
                self?.stateView.isHidden = true
                self?.loadingView.isHidden = true
            }

        }.store(in: &cancellables)

        NotificationCenter.default.addObserver(self, selector: #selector(reloadData), name: kDataChangedNotifactionName, object: nil)
    }

    @objc func researchKeyword() {
        if searchBar.textFiled.text?.isEmpty == true {
            return
        }
        searchBar.textFiled.resignFirstResponder()
        viewModel.searchModel = .init(query: searchBar.textFiled.text ?? "")
        recordHistory(keyword: searchBar.textFiled.text ?? "")
        viewModel.requestData()
    }

    @objc func reloadData() {
        listView.reloadData()
    }

    func endRefreshing() {
        listView.mj_header?.endRefreshing()
        listView.mj_footer?.endRefreshing()
    }

    @objc func loadData() {
        viewModel.requestData()
    }

    override func addChildren() {
        super.addChildren()
        view.addSubview(backButton)
        view.addSubview(searchBar)
        view.addSubview(searchButton)
        searchBar.textFiled.text = viewModel.searchModel.query
        stateView.reloadButton.addTarget(self, action: #selector(loadData), for: .touchUpInside)
        stateView.isHidden = true
        view.addSubview(listView)
        view.addSubview(stateView)
        view.addSubview(loadingView)
    }

    func makeConstraints() {
        backButton.snp.makeConstraints { make in
            make.width.height.equalTo(40)
            make.leading.equalToSuperview().offset(8)
            make.top.equalTo(view.safeAreaLayoutGuide.snp.top)
        }

        searchBar.snp.makeConstraints { make in
            make.leading.equalTo(backButton.snp.trailing)
            make.trailing.equalTo(searchButton.snp.leading).offset(-8)
            make.height.equalTo(40)
            make.centerY.equalTo(backButton)
        }

        searchButton.sizeToFit()
        searchButton.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-16)
            make.centerY.equalTo(searchBar)
            make.height.equalTo(40)
            make.width.equalTo(searchButton.width)
        }

        listView.snp.makeConstraints { make in
            make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-68)
            make.leading.trailing.equalToSuperview()
            make.top.equalTo(searchBar.snp.bottom)
        }

        stateView.snp.makeConstraints { make in
            make.edges.equalTo(listView)
        }

        loadingView.snp.makeConstraints { make in
            make.edges.equalTo(listView)
        }
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
        cancellables.removeAll()
    }
}

extension SearchResultViewController: UITableViewDelegate, UIScrollViewDelegate, UITextFieldDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.row >= viewModel.datas.count {
            return
        }

        let vModel = viewModel.datas[indexPath.row]
        if let video = vModel.dataModel {
            let datas = viewModel.datas.compactMap {
                $0.dataModel
            }
            PlayerManager.shared.playVideo(onlineVideo: video, recommendDatas: datas, scene: .online)
        }
        searchBar.textFiled.resignFirstResponder()
    }

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        guard let cell = cell as? SongDownloadCell else {
            return
        }

        let viewModel = viewModel.datas[indexPath.row]
        let videoModel = viewModel.dataModel
        cell.bindViewModel(viewModel: viewModel, isOnline: true)
        cell.downloadStateChangeBlock = { [weak self] state in
            guard let self = self else {
                return
            }
            switch state {
            case .idle(isAnimate: false), .idle(isAnimate: true):
                viewModel.startDownload()
//                if !PurchaseManager.default.isVip {
//                    ADManager.shared.showAd(scene: ADScene.downloadInsert, from: self)
//                }
                break
            case .pause:
                viewModel.resumeDownload()
                break
            case .done:
                if let videoId = videoModel?.videoId {
                    self.viewModel.showOperationViewController(videoId: videoId)
                }
                break
            case .downloading:
                viewModel.pauseDownload()
                break
            case .retry:
                viewModel.retryDownload()
                break
            case .loading:
                break
            }
        }
    }

    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        searchBar.textFiled.resignFirstResponder()
    }

    func textFieldDidBeginEditing(_ textField: UITextField) {
//        ADManager.shared.showAd(scene: ADScene.search, from: self) { state in
//            if state == .fail || state == .finished {
        textField.becomeFirstResponder()
//            }
//        }
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if textField.text?.isEmpty == false {
            viewModel.searchModel = .init(query: textField.text ?? "")
            recordHistory(keyword: textField.text ?? "")
            viewModel.requestData()
            textField.resignFirstResponder()
        }
        return true
    }

    func recordHistory(keyword: String) {
        let model = HistoryModel(keyword: keyword, id: UUID().uuidString, date: Date())
        let storage = CodableStorage()
        do {
            var history: [HistoryModel] = try storage.fetch(for: kStore_History_Key)
            history.removeAll {
                $0.keyword == keyword
            }
            history.insert(model, at: 0)
            try storage.save(history, for: kStore_History_Key)
        } catch {
            let history: [HistoryModel] = [model]
            try? storage.save(history, for: kStore_History_Key)
        }
    }
}
