import ComponentLibrary
import ComposableArchitecture
import Localization
import SwiftUI

@Reducer
public struct FilterOptions {
    @ObservableState
    public struct State: Equatable {
        let options: [Library.State.MenuFilter]
        var selection: Library.State.MenuFilter

        public init(options: [Library.State.MenuFilter], selection: Library.State.MenuFilter) {
            self.options = options
            self.selection = selection
        }
    }

    public enum Action {
        public enum Delegate {
            case filterSelected(Library.State.MenuFilter)
        }

        case changeSelection(Library.State.MenuFilter)
        case dismiss
        case delegate(Delegate)
    }

    @Dependency(\.dismiss) var dismiss

    public init() {}

    public var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .changeSelection(let filter):
                state.selection = filter
                return .send(.delegate(.filterSelected(state.selection)))

            case .dismiss:
                return .run { _ in await dismiss() }

            case .delegate:
                // Catch-all
                return .none
            }
        }
    }
}

public struct FilterOptionsMenu: View {
    let store: StoreOf<FilterOptions>
    @State private var detentHeight: CGFloat = 0

    public init(store: StoreOf<FilterOptions>) {
        self.store = store
    }

    public var body: some View {
        VStack {
            ForEach(store.options, id: \.self, content: row(for:))
        }
        .sensoryFeedbackIfEnabled(.selection, trigger: store.selection)
    }

    @ViewBuilder
    private func row(for option: Library.State.MenuFilter) -> some View {
        Toggle(isOn: .init(get: {
            store.selection == option
        }, set: { value in
            if value {
                store.send(.changeSelection(option), animation: .snappy)
            }
        })) {
            Label(title: {
                Text(option.subtitle)
                    .typographyV1(.body3)
            }, icon: {
                option.icon
            })
            .foregroundStyle(Color.SemanticV1.textBrand)
        }

        if option == .none {
            Divider()
        }
    }
}
