import ComponentLibrary
import Localization
import SwiftUI

struct DataEntryScreen: View {
    @FocusState private var focusedState: Bool

    let title: String
    var subtitle: String? = .none
    let buttonTitle: String
    let placeholder: String
    let autofillContentType: UITextContentType?
    var isWorking: Bool = false

    @Binding var value: String
    @Binding var focused: Bool

    let action: () -> Void
    let cancel: () -> Void

    var showSkip: Bool = false
    var showBackButton: Bool = true
    var showClearButton: Bool = true

    var isDisabled: Bool = false
    var errorMessage: String? = nil

    var caption: AnyView = AnyView(EmptyView())

    var body: some View {
        content
            .padding([.leading, .trailing, .bottom], 24)
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .principal) {
                    Text(title)
                        .typographyV1(.headline4)
                        .foregroundStyle(Color.SemanticV1.textPrimary)
                }
                if showSkip {
                    ToolbarItem(placement: .topBarTrailing) {
                        Button {
                            UIImpactFeedbackGenerator(style: .light).impactOccurred()
                            action()
                        } label: {
                            Text(L10n.FeatureOnboarding.skip)
                                .typographyV1(.body2)
                                .foregroundStyle(Color.SemanticV1.textLink)
                                .padding(.vertical, 3)
                                .padding(.horizontal, 5)
                                .background(Rectangle().fill(Color.SemanticV1.backgroundPrimary))
                        }
                    }
                }
            }
            .modifier(if: showBackButton) {
                $0.customBackButton(background: Material.ultraThin) {
                    UIImpactFeedbackGenerator(style: .light).impactOccurred()
                    cancel()
                }
            }
            .bind($focused, to: $focusedState)
            .background(Color.SemanticV1.backgroundPrimary)
    }

    @ViewBuilder
    private var content: some View {
        ZStack(alignment: .top) {
            VStack {
                Spacer()

                TextField("", text: $value.limit(40))
                    .typographyV1(.headline2.neueMontrealMedium())
                    .textContentType(autofillContentType)
                    .foregroundStyle(Color.SemanticV1.textPrimary)
                    .placeholder(when: value.isEmpty) {
                        Text(placeholder)
                            .inlineTypographyV1(.headline2.neueMontrealMedium())
                            .foregroundStyle(Color.SemanticV1.textSecondary)
                    }
                    .multilineTextAlignment(.center)
                    .focused($focusedState)
                    .minimumScaleFactor(0.7)
                    .tint(Color.SemanticV1.textLink)
                    .modifier(if: showClearButton) {
                        $0.clearButton(value: $value)
                    }

                if let errorMessage {
                    Text(errorMessage)
                        .typographyV1(.caption.neueMontrealRegular())
                        .foregroundColor(Color.SemanticV1.textWarning)
                        .multilineTextAlignment(.center)
                        .padding(.horizontal, 40)
                        .padding(.top, 8)
                }

                Spacer()

                caption
                    .padding(.bottom, 12)

                PrimaryButtonV1(
                    title: buttonTitle,
                    isLoading: isWorking,
                    colorCombination: .dark,
                    preferredSize: .large,
                    action: action
                )
                .opacity(isDisabled ? 0.5 : 1)
                .disabled(isDisabled)
                .animation(.default, value: isDisabled)
            }

            if let subtitle {
                Text(subtitle)
                    .typographyV1(.body2thin)
                    .foregroundStyle(Color.SemanticV1.textSecondary)
                    .opacity(0.5)
                    .multilineTextAlignment(.center)
                    .padding(.horizontal, 40)
            }
        }
    }
}

extension View {
    func placeholder<T: View>(when predicate: Bool, @ViewBuilder content: () -> T) -> some View {
        ZStack {
            content().opacity(predicate ? 1 : 0)
            self
        }
        .animation(.default, value: predicate)
    }
}
