import Foundation
import Localization
import SwiftUI

public struct MenuRowV1<IconView: View>: View {
    let icon: IconView
    let title: String
    let subtitle: String?
    let isLoading: Bool
    let flagWarning: Bool
    let action: () -> Void
    let trailingView: AnyView?

    public init(
        title: String,
        subtitle: String? = nil,
        isLoading: Bool = false,
        flagWarning: Bool = false,
        @ViewBuilder icon: () -> IconView,
        @ViewBuilder trailingView: () -> AnyView? = { nil },
        action: @escaping () -> Void = {}
    ) {
        self.icon = icon()
        self.title = title
        self.subtitle = subtitle
        self.isLoading = isLoading
        self.action = action
        self.flagWarning = flagWarning
        self.trailingView = trailingView()
    }

    public var body: some View {
        Button {
            UIImpactFeedbackGenerator(style: .light).impactOccurred()
            action()
        } label: {
            HStack(spacing: 0) {
                icon
                    .foregroundStyle(flagWarning ? Color.SemanticV1.iconWarning : Color.SemanticV1.textBrand)
                    .opacity(isLoading ? 0.5 : 1)
                    .frame(width: 24, height: 24)
                    .padding([.leading, .vertical], 3)
                    .padding(.trailing, 24)
                VStack(alignment: .leading, spacing: 0) {
                    HStack(spacing: 0) {
                        Text(title)
                            .typographyV1(.body1)
                            .foregroundStyle(flagWarning ? Color.SemanticV1.textWarning : Color.SemanticV1.textBrand)

                        if let trailingView {
                            trailingView
                                .padding(.horizontal, 8)
                        }
                    }

                    if let subtitle {
                        Text(subtitle)
                            .typographyV1(.body3.size { _ in
                                12.0
                            })
                            .foregroundStyle(Color.SemanticV1.textSecondary)
                    }
                }
                .opacity(isLoading ? 0.5 : 1)

                Spacer()

                if isLoading {
                    ProgressView()
                        .progressViewStyle(.circular)
                }
            }
        }
        .padding(.vertical, subtitle == nil ? 16 : 8)
        .disabled(isLoading)
        .simultaneousGesture(TapGesture().onEnded {}) // Prevents accidental taps in a ScrollView
    }
}

public extension MenuRowV1 where IconView == EmptyView {
    init(
        title: String,
        isLoading: Bool = false,
        action: @escaping () -> Void
    ) {
        self.init(
            title: title,
            isLoading: isLoading,
            icon: { EmptyView() },
            action: action
        )
    }
}

public extension MenuRowV1 where IconView == Image {
    init(
        title: String,
        subtitle: String? = nil,
        isLoading: Bool = false,
        icon: Image,
        action: @escaping () -> Void
    ) {
        self.init(
            title: title,
            subtitle: subtitle,
            isLoading: isLoading,
            icon: { icon },
            action: action
        )
    }
}

struct MenuRowV1_Previews: PreviewProvider {
    static var previews: some View {
        MenuRowV1Sample()
    }
}

struct MenuRowV1Sample: View {
    var body: some View {
        VStack {
            MenuRowV1(
                title: "Rename Playlist",
                isLoading: false,
                icon: Image.Icon.penField,
                action: {}
            )

            MenuRowV1(
                title: "Make Private",
                isLoading: false,
                icon: Image.Icon.lockKeyhole,
                action: {}
            )

            MenuRowV1(
                title: "Share Song",
                isLoading: true,
                icon: Image.Icon.share,
                action: {}
            )

            MenuRowV1(
                title: "Share",
                isLoading: false,
                action: {}
            )

            MenuRowV1(
                title: "Share",
                isLoading: true,
                action: {}
            )
        }
        .padding()
    }
}
