import APIClient
import AVFoundation
import ComponentLibrary
import ComposableArchitecture
import Foundation
import Localization
import SwiftUI
import Utilities

// swiftlint:disable trailing_whitespace

@Reducer
public struct HooksVolumeSelector {
    @ObservableState
    public struct State: Equatable {
        var videoVolumeLevel: Float
        var snippetVolumeLevel: Float
        var clip: Clip

        public init(
            videoVolumeLevel: Float = 0.5,
            snippetVolumeLevel: Float = 1.0,
            clip: Clip
        ) {
            self.videoVolumeLevel = videoVolumeLevel
            self.snippetVolumeLevel = snippetVolumeLevel
            self.clip = clip
        }
    }

    public enum Action {
        case videoVolumeLevelChanged(Float)
        case snippetVolumeLevelChanged(Float)
        case doneTapped
        case delegate(Delegate)

        public enum Delegate {
            case volumeLevelsUpdated(videoLevel: Float, snippetLevel: Float)
            case dismiss
        }
    }

    public init() {}

    public var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .videoVolumeLevelChanged(let level):
                state.videoVolumeLevel = level
                return .send(.delegate(.volumeLevelsUpdated(
                    videoLevel: level,
                    snippetLevel: state.snippetVolumeLevel
                )))

            case .snippetVolumeLevelChanged(let level):
                state.snippetVolumeLevel = level
                return .send(.delegate(.volumeLevelsUpdated(
                    videoLevel: state.videoVolumeLevel,
                    snippetLevel: level
                )))

            case .doneTapped:
                return .send(.delegate(.dismiss))

            case .delegate:
                return .none
            }
        }
    }
}

public struct HooksVolumeSelectorView: View {
    @Bindable var store: StoreOf<HooksVolumeSelector>
    let darkTrait = UITraitCollection(userInterfaceStyle: .dark)

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

    private func resolveColorForDarkTrait(_ color: Color) -> Color {
        Color(UIColor(color).resolvedColor(with: darkTrait))
    }

    private var backgroundColor: Color {
        return resolveColorForDarkTrait(resolveColorForDarkTrait(Color.SemanticV2.backgroundSmokeThin))
    }

    public var body: some View {
        VStack(spacing: 0) {
            sheetTitle
            videoAudioSection
            clipAudioSection
            doneButton
        }
        .padding(.horizontal, 16)
        .presentationBackground {
            Rectangle()
                .fill(.ultraThinMaterial)
                .overlay(backgroundColor)
        }
        .selfSizingPresentation()
        .preferredColorScheme(.dark)
    }

    @ViewBuilder
    private var sheetTitle: some View {
        Text(L10n.FeatureHooks.volumeSelectorSheetTitle)
            .typographyV1(.sheetTitleFont)
            .foregroundStyle(Color.SemanticV1.textPrimary)
            .frame(maxWidth: .infinity, alignment: .center)
            .padding(.top, 26)
            .padding(.bottom, 18)
    }

    @ViewBuilder
    private var videoAudioSection: some View {
        VolumeSelectorView(
            title: L10n.FeatureHooks.videoAudio,
            subtitle: L10n.FeatureHooks.videoVolume,
            volumeLevel: .init(
                get: { store.videoVolumeLevel },
                set: { store.send(.videoVolumeLevelChanged($0)) }
            )
        )
        .padding(16)
        .background(Color.SemanticV2.backgroundFogThin)
        .clipShape(.rect(cornerRadius: 16))
        .padding(.bottom, 12)
    }

    @ViewBuilder
    private var clipAudioSection: some View {
        VolumeSelectorView(
            thumbnailImage: store.clip.imageUrl,
            title: store.clip.title,
            subtitle: "\(L10n.FeatureHooks.by) \(store.clip.displayName)",
            volumeLevel: .init(
                get: { store.snippetVolumeLevel },
                set: { store.send(.snippetVolumeLevelChanged($0)) }
            )
        )
        .padding(16)
        .background(Color.SemanticV2.backgroundFogThin)
        .clipShape(.rect(cornerRadius: 16))
        .padding(.bottom, 16)
    }

    @ViewBuilder
    private var doneButton: some View {
        Button {
            store.send(.doneTapped)
        } label: {
            Text(L10n.FeatureHooks.done)
                .typographyV1(.doneButtonFont)
                .foregroundStyle(Color.SemanticV1.backgroundPrimary)
                .padding(.vertical, 12)
                .frame(maxWidth: .infinity)
                .background(Color.SemanticV1.textPrimary)
                .clipShape(.rect(cornerRadius: 50))
        }
    }
}

private extension TypographyV1 {
    static let sheetTitleFont: TypographyV1 = .init(
        name: "Audio Sheet Title Font",
        size: 16,
        style: .body,
        weight: .ppNeueMontrealMedium,
        lineHeight: 22
    )

    static let doneButtonFont: TypographyV1 = .init(
        name: "Done Button Font",
        size: 14,
        style: .body,
        weight: .ppNeueMontrealMedium,
        lineHeight: 24
    )
}
