import ComponentLibrary
import ComposableArchitecture
import FeatureBrandedAlert
import Localization
import StatsigClient
import SunoModelClient
import SwiftUI
import Utilities

@Reducer
public struct CreateClipSettings {
    @ObservableState
    public struct State: Equatable {
        @Shared(.inMemory(.selectedSunoModel)) var selectedSunoModel: SunoModelMetaData = .modelDefault
        @Shared(.inMemory(.sunoModelUserAccessCategory)) var sunoModelUserAccessCategory: SunoModelUserAccess = .defaultLimitedAccess
        @Shared(.inMemory(.availableModels)) var availableModels: [SunoModelMetaData] = []

        @Shared(.fileStorage(FilePathKeys.ApplicationSupport.selectedLyricsModel.url())) var selectedLyricsModel: LyricsModelMetadata = .remi
        let availableLyricsModels: [LyricsModelMetadata] = [.remi, .classic]

        public init() {}
    }

    public enum Action {
        case task
        case delegate(Delegate)
        case didTapBackButton
        case didTapModelToggle // Legacy
        case didSelectModel(SunoModelMetaData)
        case didSelectLyricsModel(LyricsModelMetadata)
        case brandedAlert(BrandedAlert.Action)

        public enum Delegate {
            case close
            case didPressModelForInformation
            case showUpgradeAlert(_ marketingLevelUnderstanding: SunoModelMetaData.MarketingLevelUnderstanding)
        }
    }

    public init() {}

    @Dependency(\.dismiss) var dismiss
    @Dependency(SunoModelClient.self) private var sunoModelClient

    public var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .task:
                return .none

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

            case .didTapModelToggle:
                return .run { _ in
                    await sunoModelClient.toggleModelOverride()
                }

            case .didSelectModel(let model):
                return .run { _ in
                    await sunoModelClient.setModel(model.id)
                }

            case .didSelectLyricsModel(let lyricsModel):
                state.$selectedLyricsModel.withLock {
                    $0 = lyricsModel
                }
                return .none

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

public struct CreateClipSettingsSheet: View {
    @Bindable var store: StoreOf<CreateClipSettings>

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

    public var body: some View {
        VStack(spacing: 10) {
            SettingsRow(
                icon: Image.Icon.create,
                title: L10n.FeatureCreateClip.model,
                trailingView: {
                    modelPicker
                }
            )

            SettingsRow(
                icon: Image.Icon.lyrics,
                title: L10n.FeatureCreateClip.lyricsModel,
                trailingView: {
                    lyricsModelPicker
                }
            )
        }
        .task { store.send(.task) }
        .padding(.leading, 30)
        .padding(.trailing, 30)
        .padding(.top, 10)
        .padding(.bottom, 24)
        .sheetNavigationBar(
            leading: {
                BlendedToolbarButtonView(image: Image.Icon.close, action: {
                    store.send(.didTapBackButton)
                })
                .frame(width: 44, height: 44)
            },
            center: {
                Text(L10n.FeatureCreateClip.settings)
                    .typographyV1(.headline4)
                    .foregroundStyle(Color.SemanticV1.textPrimary)
            },
            trailing: {
                EmptyView()
            }
        )
        .presentationBackground(Color.SemanticV2.backgroundTertiary)
        .presentationCornerRadius(40, conditional: true)
        .selfSizingPresentation()
    }

    @ViewBuilder
    private var modelPicker: some View {
        MusicModelSelectorV2(
            selectedModel: store.selectedSunoModel,
            models: store.availableModels,
            setSelectedModel: { model in
                if model.canUse == false {
                    store.send(.delegate(.showUpgradeAlert(model.marketingLevelUnderstanding)))
                } else {
                    store.send(.didSelectModel(model))
                }
            }
        )
    }

    @ViewBuilder
    private var lyricsModelPicker: some View {
        LyricsModelSelectorV2(
            selectedModel: store.selectedLyricsModel,
            models: store.availableLyricsModels,
            setSelectedModel: { model in
                store.send(.didSelectLyricsModel(model))
            }
        )
    }
}

struct SettingsRow<TrailingView: View>: View {
    let icon: Image
    let title: String
    let trailingView: TrailingView

    init(
        icon: Image,
        title: String,
        @ViewBuilder trailingView: () -> TrailingView
    ) {
        self.icon = icon
        self.title = title
        self.trailingView = trailingView()
    }

    var body: some View {
        HStack(spacing: 10) {
            icon
                .resizable()
                .frame(width: 18, height: 18)
                .foregroundStyle(Color.SemanticV2.foregroundPrimary)

            Text(title)
                .typographyV1(.subtitleMedium)
                .foregroundStyle(Color.SemanticV2.foregroundPrimary)

            Spacer()

            trailingView
        }
    }
}
