import APIClient
import ComponentLibrary
import ComposableArchitecture
import Errors
import FeatureBrandedAlert
import GenAPI
import Localization
import StatsigClient
import SwiftUI
import Utilities

public struct MoreOptionsView: View {
    @Bindable var store: StoreOf<MoreOptionsReducer>

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

    public var body: some View {
        VStack(spacing: .zero) {
            if FeatureFlag.hooks.isFeedEnabled && store.clip.isPublic && store.clip.videoCoverUrl != nil {
                showVideoCoverInHooksFeedRow
                Divider()
            }
            commentsRow
            Divider()
            if FeatureFlag.create.remixAndAttribution {
                // Hide remixing for now
                remixingRow
                Divider()
            }
            if false {
                // Hide downloads for now
                downloadsRow
                Divider()
            }
            if store.showPinToProfile {
                pinToProfileRow
                Divider()
            }
            Spacer()
        }
        .tint(Color.SemanticV1.auraPink)
        .padding(.top, 22)
        .padding(.horizontal, 12)
        .background(Color.SemanticV1.backgroundPrimary)
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .topBarLeading) {
                dismissButton
            }
            ToolbarItem(placement: .principal) {
                navigationTitle
            }
        }
        .brandedAlert(error: $store.error) {
            store.send(.clearError)
        }
        .task { store.send(.task) }
        .sensoryFeedbackIfEnabled(.success, trigger: store.toggleHapticSuccess)
        .sensoryFeedbackIfEnabled(.warning, trigger: store.toggleHapticError)
        .overlay {
            if let _ = store.brandedAlert.destination {
                Color.SemanticV1.backgroundQuaternary.opacity(0.4)
                BrandedAlertView(store.scope(state: \.brandedAlert, action: \.brandedAlert))
            }
        }
    }

    private var navigationTitle: some View {
        Text(L10n.FeatureManageClip.moreOptions)
            .typographyV1(.headline4.size { _ in 16.0 }.lineHeight(20.0))
            .foregroundStyle(Color.SemanticV2.foregroundPrimary)
    }

    @ViewBuilder
    private var dismissButton: some View {
        ToolbarButton(.chevronLeft, color: Color.SemanticV2.foregroundPrimary, background: Color.SemanticV1.backgroundQuaternary) {
            store.send(.dismissTapped)
        }
        .allowsHitTesting(true)
    }

    @ViewBuilder
    private func toggleRow<IconView: View>(
        icon: Image? = nil,
        iconView: IconView? = nil,
        title: String,
        toggleState: Binding<MoreOptionsState.ToggleState>,
        action: @escaping (Bool) -> Void
    ) -> some View {
        HStack(spacing: 12) {
            if let iconView = iconView {
                iconView
                    .frame(width: 24, height: 24)
                    .foregroundStyle(Color.SemanticV2.foregroundPrimary)
            } else if let icon = icon {
                icon
                    .resizable()
                    .frame(width: 24, height: 24)
                    .foregroundStyle(Color.SemanticV2.foregroundPrimary)
            }
            Text(title)
                .typographyV1(.body1.lineHeight(24.0))
                .foregroundStyle(Color.SemanticV2.foregroundPrimary)
            if case .updating = toggleState.wrappedValue {
                ProgressView()
                    .frame(width: 24, height: 24)
                    .foregroundStyle(Color.SemanticV2.foregroundSecondary)
            }
            Spacer()
            Toggle(isOn: Binding(get: { toggleState.wrappedValue.currentValue }, set: { newValue in
                action(newValue)
            })) {
                EmptyView()
            }
            .tint(Color.SemanticV2.accentBrand)
        }
        .padding(.vertical, 16)
    }

    // Overload for when only icon is provided (backward compatibility)
    @ViewBuilder
    private func toggleRow(
        icon: Image,
        title: String,
        toggleState: Binding<MoreOptionsState.ToggleState>,
        action: @escaping (Bool) -> Void
    ) -> some View {
        toggleRow(icon: icon, iconView: nil as EmptyView?, title: title, toggleState: toggleState, action: action)
    }

    @ViewBuilder
    private var commentsRow: some View {
        toggleRow(
            icon: Image.Icon.commentBubble,
            title: L10n.FeatureManageClip.allowCommentsToggle,
            toggleState: $store.commentsToggle,
            action: { store.send(.updateAllowComments($0)) }
        )
    }

    @ViewBuilder
    private var remixingRow: some View {
        toggleRow(
            icon: Image.Icon.remix,
            title: L10n.FeatureManageClip.allowRemixingToggle,
            toggleState: $store.remixingToggle,
            action: { store.send(.updateAllowRemixing($0)) }
        )
    }

    @ViewBuilder
    private var downloadsRow: some View {
        toggleRow(
            icon: Image.Icon.commentBubble,
            title: L10n.FeatureManageClip.allowDownloadsToggle,
            toggleState: $store.downloadsToggle,
            action: { store.send(.updateAllowDownloads($0)) }
        )
    }

    @ViewBuilder
    private var pinToProfileRow: some View {
        toggleRow(
            icon: Image.Icon.thumbtack,
            title: L10n.FeatureClipDetail.pin,
            toggleState: $store.pinningToggle,
            action: { store.send(.togglePinToProfile($0)) }
        )
    }

    @ViewBuilder
    private var showVideoCoverInHooksFeedRow: some View {
        toggleRow(
            iconView: Image.Icon.hooksTabIcon
                .resizable()
                .padding(.vertical, 2)
                .padding(.horizontal, 4),
            title: L10n.FeatureClipDetail.showVideoCoverInHooksFeed,
            toggleState: $store.videoCoverInHooksFeedToggle,
            action: { _ in store.send(.toggleShowVideoCoverInHooksFeed) }
        )
    }
}
