//
//  ModelViewController.swift
//  VDSSample
//
//  Created by Matt Bruce on 8/15/22.
//

import Foundation
import UIKit
import Combine
import VDS

public class FormSection: UIStackView {
    public var title: String? {
        didSet {
            if let title {
                titleLabel.text = title
                titleLabel.isHidden = false
            } else {
                titleLabel.isHidden = true
            }
        }
    }
    
    private var titleLabel = Label().with { $0.isHidden = true; $0.textStyle = .boldBodyLarge }
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        translatesAutoresizingMaskIntoConstraints = false
        alignment = .fill
        distribution = .fill
        axis = .vertical
        spacing = 10
        addArrangedSubview(titleLabel)
    }

    public convenience init() {
        self.init(frame: .zero)
    }
    
    required init(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @discardableResult
    open func addFormRow(label: String, view: UIView) -> UIView {
        let formRow = UIStackView().with {
            $0.translatesAutoresizingMaskIntoConstraints = false
            $0.alignment = .fill
            $0.distribution = .fillEqually
            $0.axis = .horizontal
            $0.spacing = 5
        }
        
        let label = Label().with {
            $0.text = label
            $0.textStyle = .bodyLarge
        }
        
        formRow.addArrangedSubview(label)
        formRow.addArrangedSubview(view)

        addArrangedSubview(formRow)
        return formRow
    }
}

public class BaseViewController<Component: UIView>: UIViewController, Initable {
    deinit {
        print("\(Self.self) deinit")
    }
    
    private let edgeSpacing = 16.0

    //--------------------------------------------------
    // MARK: - Combine Properties
    //--------------------------------------------------
    public var subscribers = Set<AnyCancellable>()

    //--------------------------------------------------
    // MARK: - Properties
    //--------------------------------------------------
    private var initialSetupPerformed = false
    
    //--------------------------------------------------
    // MARK: - Initializers
    //--------------------------------------------------
    required public init() {
        super.init(nibName: nil, bundle: nil)
        initialSetup()
    }
        
    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nil, bundle: nil)
        initialSetup()
    }
    
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        initialSetup()
    }

    //--------------------------------------------------
    // MARK: - Setup
    //--------------------------------------------------
    
    public func initialSetup() {
        overrideUserInterfaceStyle = .light

        if !initialSetupPerformed {
            initialSetupPerformed = true
            setup()
            contentTopView.backgroundColor = Surface.light.color
        }
    }
    
    public lazy var surfacePickerSelectorView = {
        SurfacePickerSelectorView(picker: self.picker)
    }()
    
    public var picker: UIPickerView = {
        return UIPickerView().with {
            $0.backgroundColor = .white
            $0.translatesAutoresizingMaskIntoConstraints = false
        }
    }()

    public var component = Component()
    
    lazy var debugViewSwitch = Toggle().with{
        $0.onChange =  { [weak self] sender in
            self?.showDebug(show: sender.isOn)
        }
    }
    
    open func showDebug(show: Bool) {
        self.component.debugBorder(show: show, color: .blue)
    }
   
    public var formStackView = FormSection()
    
    lazy var stackView = UIStackView().with {
        $0.axis = .vertical
        $0.distribution = .fill
        $0.alignment = .fill
        $0.spacing = 0
        $0.translatesAutoresizingMaskIntoConstraints = false
    }
    
    let bottomScrollView = UIScrollView().with {
        $0.translatesAutoresizingMaskIntoConstraints = false
    }

    public var contentTopView = UIView().with {
        $0.translatesAutoresizingMaskIntoConstraints = false
    }

    public var contentBottomView = UIView().with {
        $0.translatesAutoresizingMaskIntoConstraints = false
    }

    open override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        
        
        let spacerView = UIView().with{
            $0.translatesAutoresizingMaskIntoConstraints = false
        }
        
        let top = UIView.makeWrapper(for: contentTopView, edgeSpacing: 16, isTrailing: false)
        
        // Add the top and bottom views to the stack view
        stackView.addArrangedSubview(top)
        stackView.addArrangedSubview(bottomScrollView)
       
        // Add the stack view to the view controller's view
        view.addSubview(stackView)
       
        // Pin the stack view to the edges of the view controller's view
        NSLayoutConstraint.activate([
            stackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
            stackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
            stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])

        bottomScrollView.addSubview(contentBottomView)
       
        // Pin the content view to the edges of the scroll view
        NSLayoutConstraint.activate([
            contentBottomView.leadingAnchor.constraint(equalTo: bottomScrollView.leadingAnchor),
            contentBottomView.trailingAnchor.constraint(equalTo: bottomScrollView.trailingAnchor),
            contentBottomView.topAnchor.constraint(equalTo: bottomScrollView.topAnchor),
            contentBottomView.bottomAnchor.constraint(equalTo: bottomScrollView.bottomAnchor),
            contentBottomView.widthAnchor.constraint(equalTo: bottomScrollView.widthAnchor)
        ])

        contentBottomView.addSubview(formStackView)
        formStackView.pinToSuperView(.init(top: 0, left: 16, bottom: 0, right: edgeSpacing))

        view.addSubview(picker)
        picker.pinBottom()
        picker.pinLeading()
        picker.pinTrailing()
        picker.isHidden = true
        
        setupForm()
    }

    public func setupForm() {
        addFormRow(label: "Show Bounds", view: .makeWrapper(for: debugViewSwitch))
    }
    
    public func scrollToBottom() {
        let bottomOffset = CGPoint(x: 0, y: bottomScrollView.contentSize.height - bottomScrollView.bounds.height + bottomScrollView.contentInset.bottom)
        bottomScrollView.setContentOffset(bottomOffset, animated: true)
    }
    
    private func embed(_ viewController: UIViewController) {
        addChild(viewController)
        view.addSubview(viewController.view)
        viewController.view.translatesAutoresizingMaskIntoConstraints = false
        viewController.view.pinToSuperView()
        viewController.didMove(toParent: self)
    }
    
    open func addContentTopView(view: UIView, edgeSpacing: CGFloat = 16.0) {
        view.translatesAutoresizingMaskIntoConstraints = false
        contentTopView.addSubview(view)
        view.pinToSuperView(.init(top: edgeSpacing, left: edgeSpacing, bottom: edgeSpacing, right: edgeSpacing))
    }

    open func append(section: FormSection) {
        formStackView.addArrangedSubview(section)
    }
       
    @discardableResult
    open func addFormRow(label: String, view: UIView) -> UIView {
        return formStackView.addFormRow(label: label, view: view)
    }

    open func setup() {
        
        if let textFields = allTextFields() {
            for textField in textFields {
                if textField.isNumeric {
                    let keypadToolbar: UIToolbar = UIToolbar()
                    
                    // add a done button to the numberpad
                    keypadToolbar.items=[
                        UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: self, action: nil),
                        UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: textField, action: #selector(UITextField.resignFirstResponder))
                    ]
                    keypadToolbar.sizeToFit()

                    // add a toolbar with a done button above the number pad
                    textField.inputAccessoryView = keypadToolbar
                    textField.keyboardType = .numberPad
                }
                textField.returnKeyType = .done
                textField
                    .publisher(for: .editingDidEndOnExit)
                    .sink { textField in
                        textField.resignFirstResponder()
                    }
                    .store(in: &subscribers)
            }
        }
    }
    
    open func updateView() {
        //print("\(Self.self) updateView()")
    }

    open func allTextFields() -> [TextField]? { nil }
}
