//
//  DiscoveryViewController.swift
//  Mastodon
//
//  Created by MainasuK on 2022-4-12.
//

import UIKit
import Combine
import Tabman
import Pageboy
import MastodonAsset
import MastodonCore
import MastodonUI

public class DiscoveryViewController: TabmanViewController, NeedsDependency {
    
    public static let containerViewMarginForRegularHorizontalSizeClass: CGFloat = 64
    public static let containerViewMarginForCompactHorizontalSizeClass: CGFloat = 16
    
    var disposeBag = Set<AnyCancellable>()
    
    weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
    weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
        
    var viewModel: DiscoveryViewModel!
    
    private(set) lazy var buttonBar: TMBar.ButtonBar = {
        let buttonBar = TMBar.ButtonBar()
        buttonBar.backgroundView.style = .custom(view: buttonBarBackgroundView)
        buttonBar.layout.interButtonSpacing = 0
        buttonBar.layout.contentInset = .zero
        buttonBar.indicator.backgroundColor = Asset.Colors.Label.primary.color
        buttonBar.indicator.weight = .custom(value: 2)
        return buttonBar
    }()
    
    let buttonBarBackgroundView: UIView = {
        let view = UIView()
        let barBottomLine = UIView.separatorLine
        barBottomLine.backgroundColor = Asset.Colors.Label.secondary.color.withAlphaComponent(0.5)
        barBottomLine.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(barBottomLine)
        NSLayoutConstraint.activate([
            barBottomLine.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            barBottomLine.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            barBottomLine.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            barBottomLine.heightAnchor.constraint(equalToConstant: 2).priority(.required - 1),
        ])
        return view
    }()
    
    func customizeButtonBarAppearance() {
        // The implmention use CATextlayer. Adapt for Dark Mode without dynamic colors
        // Needs trigger update when `userInterfaceStyle` chagnes
        let userInterfaceStyle = traitCollection.userInterfaceStyle
        buttonBar.buttons.customize { button in
            switch userInterfaceStyle {
            case .dark:
                // Asset.Colors.Label.primary.color
                button.selectedTintColor = UIColor(red: 238.0/255.0, green: 238.0/255.0, blue: 238.0/255.0, alpha: 1.0)
                // Asset.Colors.Label.secondary.color
                button.tintColor = UIColor(red: 151.0/255.0, green: 157.0/255.0, blue: 173.0/255.0, alpha: 1.0)
            default:
                // Asset.Colors.Label.primary.color
                button.selectedTintColor = UIColor(red: 40.0/255.0, green: 44.0/255.0, blue: 55.0/255.0, alpha: 1.0)
                // Asset.Colors.Label.secondary.color
                button.tintColor = UIColor(red: 60.0/255.0, green: 60.0/255.0, blue: 67.0/255.0, alpha: 0.6)
            }
            
            button.backgroundColor = .clear
            button.contentInset = UIEdgeInsets(top: 12, left: 26, bottom: 12, right: 26)
        }
    }
    
}

extension DiscoveryViewController {
    
    public override func viewDidLoad() {
        super.viewDidLoad()

        setupAppearance()
        
        dataSource = viewModel
        addBar(
            buttonBar,
            dataSource: viewModel,
            at: .top
        )
        customizeButtonBarAppearance()
    
        viewModel.$viewControllers
            .receive(on: DispatchQueue.main)
            .sink { [weak self] _ in
                guard let self = self else { return }
                self.reloadData()
            }
            .store(in: &disposeBag)
    }
    
    public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)

        customizeButtonBarAppearance()
    }

}

extension DiscoveryViewController {
    
    private func setupAppearance() {
        view.backgroundColor = .secondarySystemBackground
        buttonBarBackgroundView.backgroundColor = .systemBackground
    }
    
}

// MARK: - ScrollViewContainer
extension DiscoveryViewController: ScrollViewContainer {
    var scrollView: UIScrollView {
        return (currentViewController as? ScrollViewContainer)?.scrollView ?? UIScrollView()
    }
    func scrollToTop(animated: Bool) {
        if scrollView.contentOffset.y <= 0 {
            scrollToPage(.first, animated: animated)
        } else {
            scrollView.scrollToTop(animated: animated)
        }
    }
}

extension DiscoveryViewController {

    public override var keyCommands: [UIKeyCommand]? {
        return pageboyNavigateKeyCommands
    }

}

// MARK: - PageboyNavigateable
extension DiscoveryViewController: PageboyNavigateable {
    
    var navigateablePageViewController: PageboyViewController {
        return self
    }
    
    @objc func pageboyNavigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) {
        pageboyNavigateKeyCommandHandler(sender)
    }
    
}
