import ComponentLibrary
import ComposableArchitecture
import FeatureHooksGrid
import Localization
import SwiftUI
import Utilities

public struct MyHooksScreen: View {
    @Bindable var store: StoreOf<MyHooksReducer>
    @Namespace private var animation

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

    public var body: some View {
        content
            .background(Color.SemanticV1.backgroundPrimary)
            .navigationBarBackButtonHidden()
            .modifier(if: store.showBackButton) {
                $0.customBackButton(background: Color.SemanticV1.backgroundQuaternary) {
                    store.send(.backButtonTapped)
                }
            }
            .toolbar {
                ToolbarItem(placement: .principal) {
                    ToolbarTitle(L10n.FeatureCatalog.hooks)
                }

                ToolbarItem(placement: .navigationBarTrailing) {
                    ToolbarButton(.create, background: Color.SemanticV1.backgroundQuaternary, action: {
                        store.send(.myHooksGrid(.createHookTapped))
                    })
                }
            }
            .task {
                store.send(.task)
            }
    }

    private var content: some View {
        VStack(spacing: 0) {
            tabBar
            TabView(selection: Binding(
                get: { store.selectedTab },
                set: { store.send(.setSelectedTab($0)) }
            )) {
                HooksGridScreen(
                    store: store.scope(
                        state: \.myHooksGrid,
                        action: \.myHooksGrid
                    )
                )
                .tag(MyHooksReducer.State.Tab.madeByMe)

                HooksGridScreen(
                    store: store.scope(
                        state: \.likedHooksGrid,
                        action: \.likedHooksGrid
                    )
                )
                .tag(MyHooksReducer.State.Tab.liked)
            }
            .navigationSwipeEnabled()
            .tabViewStyle(.page(indexDisplayMode: .never))
            .indexViewStyle(.page(backgroundDisplayMode: .never))
        }
    }

    @ViewBuilder
    private var tabBar: some View {
        HStack(spacing: 0) {
            ForEach(MyHooksReducer.State.Tab.allCases, id: \.self) { tab in
                Button {
                    withAnimation(.spring(response: 0.3, dampingFraction: 0.7)) {
                        switch tab {
                        case .madeByMe:
                            store.send(.setSelectedTab(.madeByMe))
                        case .liked:
                            store.send(.setSelectedTab(.liked))
                        }
                    }
                } label: {
                    ZStack(alignment: .bottom) {
                        Text(tab.title)
                            .typographyV1(.tabText)
                            .foregroundColor(store.selectedTab == tab ? .SemanticV1.textPrimary : .SemanticV1.textSecondary)
                            .padding(.vertical, 12)

                        if store.selectedTab == tab {
                            Rectangle()
                                .fill(Color.SemanticV1.textPrimary)
                                .frame(height: 1)
                                .matchedGeometryEffect(id: "indicator", in: animation)
                        } else {
                            Rectangle()
                                .fill(Color.SemanticV1.textPrimary)
                                .frame(height: 1)
                                .opacity(0.2)
                        }
                    }
                    .frame(maxWidth: .infinity)
                    .padding(.top, 12)
                    .contentShape(Rectangle())
                }
                .buttonStyle(.plain)
            }
        }
    }
}

private extension TypographyV1 {
    static let tabText: TypographyV1 = .init(
        name: "Tab Text",
        size: 14,
        style: .body,
        weight: .ppNeueMontrealMedium,
        lineHeight: 24
    )
}
