import Combine
import Foundation
import ReduxKit
import UIKit

final class UIKDViewController: ReduxUIViewController
<UIKDView, UIKDState, UIKDSelectors, UIKDActions> {

    override func provideInitialView() -> UIKDView {
        let view = UIKDView()
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapBackground)))
        return view
    }

    override func updates(selectors: UIKDSelectors) {

        providedView
            .addThingButton
            .addDispatcher(self,
                           action: .addThing,
                           for: .touchUpInside)

        selectors.backgroundColor.onChange { [self] color in
            providedView.backgroundColor = color
        }

        selectors
            .rows
            .onChange { [self] rows in
                rows.forEach { row in
                    if let rowView = providedView.rows
                        .first(where: { $0.uuid == row.uuid }) {
                        // The row exists, just update it.
                        rowView.countLabel.text = row.title
                        rowView.countLabel.text = "\(row.count)"
                    } else {
                        // The uuid doesn't match an existing row.
                        let rowView = createRow(row)
                        providedView.addRow(rowView)
                    }
                }
            }
    }
}

extension UIKDViewController {
    @objc final func didTapBackground() {
        dispatch(.setRandomBackgroundColor)
    }
}

extension UIKDViewController {

    func createRow(_ row: UIKDSelectors.RowViewModel) -> CountingRow {
        let rowView = CountingRow(title: row.title,
                                  uuid: row.uuid,
                                  count: row.count)
        rowView
            .incrementButton
            .addDispatcher(self,
                           action: .increment(uuid: row.uuid),
                           for: .touchUpInside)

        rowView
            .decrementButton
            .addDispatcher(self,
                           action: .decrement(uuid: row.uuid),
                           for: .touchUpInside)

        return rowView
    }

}
