HistoryViewController.swift 6.4 KB
//
//  HistoryViewController.swift
//  browser
//
//  Created by Artem Talko on 29.09.2023.
//
//MARK: Checked
import UIKit
import RealmSwift

final class HistoryViewController: UIViewController {
    private let mainView = HistoryView()
    private var objectNotificationToken: NotificationToken?
    
    private var historyData: [HistoryElement] = [] {
        didSet {
            filteredData = historyData
        }
    }
    
    private var filteredData: [HistoryElement] = [] {
        didSet {
            mainView.historyTabsTableView.reloadData()
        }
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        navigationController?.isNavigationBarHidden = false
        navigationItem.title = "History"
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        initViewController()
    }
    
    private func initViewController() {
        setupTableView()
        addTargets()
        setupSearchBar()
        historyChangesObserve()
    }
    
    override func loadView() {
        view = mainView
        view.backgroundColor = .white
        
        navigationController?.isNavigationBarHidden = false
        navigationItem.title = "History"
    }
    
    init() {
        super.init(nibName: nil, bundle: nil)
        
        historyData = HistoryDBManager.shared.getHistoryDataForTableView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

//MARK: - TableView Extention
extension HistoryViewController: UITableViewDelegate, UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return filteredData.count
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return filteredData[section].name
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return filteredData[section].stories.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: HistoryTableViewCell.tabID, for: indexPath) as? HistoryTableViewCell else {
            return UITableViewCell()
        }
        let row = indexPath.row
        let section = indexPath.section
        
        cell.model = filteredData[section].stories[row]
        
        return cell
    }
    
    private func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == .delete) {
            let row = indexPath.row
            let section = indexPath.section
            let historyCellData = filteredData[section].stories[row]
            let tabId = historyCellData.historyCellId
            
            HistoryDBManager.shared.deleteHistoryCell(tabId: tabId)
            filteredData[section].stories.remove(at: row)
            mainView.historyTabsTableView.reloadData()
        }
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let section = indexPath.section
        let index = indexPath.row
        let urlForFunc = historyData[section].stories[index].siteUrl
        
        if let navigationController = presentingViewController as? NavigationViewController {
            for viewController in navigationController.viewControllers {
                if let browserHomeViewController = viewController as? BrowserHomeViewController {
                    browserHomeViewController.urlManagment(urlForFunc)
                }
            }
            dismiss(animated: true)
        }
    }
}


//MARK: Helper
extension HistoryViewController {
    private func addTargets() {
        mainView.historySearchBar.searchTextFieldView.addTarget(self, action: #selector(searchBarTextChanged), for: .editingChanged)
        addToolbarTargets()
    }
    
    private func addToolbarTargets() {
        mainView.historyToolbarView.action = didTabButtonTapped
    }
    
    private func setupTableView() {
        mainView.historyTabsTableView.dataSource = self
        mainView.historyTabsTableView.delegate = self
        mainView.historyTabsTableView.register(HistoryTableViewCell.self, forCellReuseIdentifier: HistoryTableViewCell.tabID)
    }
}


//MARK: Targets
extension HistoryViewController {
    private func didTabButtonTapped(type: historyToolbarElementType) {
        if type == .clean {
            HistoryDBManager.shared.cleanHistory()
            historyData.removeAll()
            mainView.historyTabsTableView.reloadData()
        }
    }
}


//MARK: Action
extension HistoryViewController {
    @objc
    private func searchResultAction() {
        mainView.historySearchBar.searchTextFieldView.text = nil
        filteredData = historyData
    }
    
    @objc
    private func searchBarTextChanged() {
        if let text = mainView.historySearchBar.searchTextFieldView.text {
            if text.isEmpty {
                filteredData = historyData
            } else {
                filteredData = HistoryDBManager.shared.getFilteredHistory(filter: text)
            }
        }
    }
}


//MARK: SearchBar
extension HistoryViewController: UITextFieldDelegate {
    func textFieldDidBeginEditing(_ textField: UITextField) {
        mainView.historySearchBar.searchTextFieldView.text = nil
        mainView.historySearchBar.searchTextFieldView.textColor = .black
    }
    
    private func setupSearchBar() {
        mainView.historySearchBar.searchTextFieldView.delegate = self
    }
}

//MARK: History DB observe
extension HistoryViewController {
    private func historyChangesObserve() {
        let historyObjects = HistoryDBManager.shared.getHistory()
        for historyObject in historyObjects {
            objectNotificationToken = historyObject.observe { [self] changes in
                switch changes {
                case .error(let error):
                    print("Error observing changes in Realm: \(error)")
                case .change(_, _):
                    break
                case .deleted:
                    self.historyData = HistoryDBManager.shared.getHistoryDataForTableView()
                    self.mainView.historyTabsTableView.reloadData()
                }
            }
        }
    }
}