import ComposableArchitecture
import Foundation
import SwiftUI

public struct VolumeSelectorView: View {
    let thumbnailImage: String?
    let title: String
    let subtitle: String
    @Binding var volumeLevel: Float

    public init(
        thumbnailImage: String? = nil,
        title: String,
        subtitle: String,
        volumeLevel: Binding<Float>
    ) {
        self.thumbnailImage = thumbnailImage
        self.title = title
        self.subtitle = subtitle
        self._volumeLevel = volumeLevel
    }

    public var body: some View {
        VStack(spacing: 12) {
            HStack(spacing: 10) {
                thumbnail
                VStack(alignment: .leading, spacing: 2) {
                    titleText
                    subtitleText
                }
                Spacer()
            }

            HStack(spacing: 12) {
                volumeIcon
                volumeSlider
                volumeLevelText
            }
        }
    }

    @ViewBuilder
    private var thumbnail: some View {
        if let thumbnailImageURL = thumbnailImage {
            RemoteImage(url: thumbnailImageURL, fallbackId: "1")
                .frame(width: 32, height: 35)
                .clipShape(.rect(cornerRadius: 8))
        }
    }

    @ViewBuilder
    private var titleText: some View {
        Text(title)
            .typographyV1(.titleFont)
            .foregroundStyle(Color.SemanticV1.textPrimary)
            .lineLimit(1)
    }

    @ViewBuilder
    private var subtitleText: some View {
        Text(subtitle)
            .typographyV1(.subtitleFont)
            .foregroundStyle(Color.SemanticV1.textSecondary)
            .lineLimit(1)
    }

    @ViewBuilder
    private var volumeIcon: some View {
        Image.Icon.volumeOn
            .resizable()
            .frame(width: 24, height: 24)
            .foregroundStyle(Color.SemanticV1.iconPrimary)
    }

    @ViewBuilder
    private var volumeSlider: some View {
        GeometryReader { geometry in
            ZStack(alignment: .leading) {
                Capsule()
                    .fill(Color.SemanticV2.backgroundFogThick)
                    .frame(height: 8)

                Capsule()
                    .fill(Color.SemanticV1.textPrimary)
                    .frame(
                        width: geometry.size.width * CGFloat(volumeLevel),
                        height: 8
                    )
            }
            .frame(maxHeight: .infinity, alignment: .center)
            .contentShape(Rectangle())
            .gesture(
                DragGesture(minimumDistance: 0)
                    .onChanged { value in
                        let percent = max(0, min(1, value.location.x / geometry.size.width))
                        volumeLevel = Float(percent)
                    }
            )
        }
        .frame(height: 24)
    }

    @ViewBuilder
    private var volumeLevelText: some View {
        ZStack(alignment: .trailing) {
            // width placeholder so that 2 and 3 digit numbers fit correctly in the view
            Text("000")
                .typographyV1(.volumeDisplayFont)
                .monospacedDigit()
                .hidden()

            Text("\(Int(volumeLevel * 100))")
                .typographyV1(.volumeDisplayFont)
                .foregroundStyle(Color.SemanticV1.textPrimary)
                .monospacedDigit()
                .contentTransition(.numericText())
                .animation(.easeInOut(duration: 0.2), value: volumeLevel)
        }
    }
}

private extension TypographyV1 {
    static let titleFont: TypographyV1 = .init(
        name: "Audio Title Font",
        size: 14,
        style: .body,
        weight: .ppNeueMontrealMedium
    )

    static let subtitleFont: TypographyV1 = .init(
        name: "Audio Subtitle Font",
        size: 12,
        style: .body,
        weight: .ppNeueMontrealRegular
    )

    static let volumeDisplayFont: TypographyV1 = .init(
        name: "Volume Display Font",
        size: 14,
        style: .body,
        weight: .inputSans
    )
}
