import SwiftUI

/// Helper  class for making our SwiftUI view available to ObjectiveC
@objcMembers class WelcomeExperienceViewController: NSObject {

    class func makeViewController(completion: (() -> Void)?) -> UIViewController {
        let welcomeExperienceView = WelcomeExperienceView(completion: completion)
        
        return UIHostingController(rootView: welcomeExperienceView)
    }
}

struct WelcomeExperienceView: View {
    
    @State var completion: (() -> Void)?

    var body: some View {
        TabView {
            Page(image: "welcome_experience_1", title: BWIL10n.welcomeExperienceTitle1, description: BWIL10n.welcomeExperienceDescription1)
            Page(image: "welcome_experience_2", title: BWIL10n.welcomeExperienceTitle2, description: BWIL10n.welcomeExperienceDescription2)
            Page(image: "welcome_experience_3", title: BWIL10n.welcomeExperienceTitle3, description: BWIL10n.welcomeExperienceDescription3)
            Page(image: "welcome_experience_4", title: BWIL10n.welcomeExperienceTitle4, description: BWIL10n.welcomeExperienceDescription4)
            Page(image: "welcome_experience_5",  title: BWIL10n.welcomeExperienceTitle5, description: BWIL10n.welcomeExperienceDescription5, doneButton: BWIL10n.welcomeExperienceStart, buttonCallback: completion)
        }
        .tabViewStyle(.page)
        .indexViewStyle(.page(backgroundDisplayMode: .always))
        .background(Color.white.ignoresSafeArea())
    }
}

fileprivate struct Page: View {
    var image: String
    var title: String
    var description: String
    var doneButton: String?
    
    @State var buttonCallback: (() -> Void)?
    
    private let service = ServerDowntimeDefaultService()
    @State private var isFetchingDowntime = false
    @State private var showAlert = false
    @State private var activeAlert: ServerMaintenanceAlertType = .showInvalidAppVersionAlert
    
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .center, spacing: 40) {
                Image(image)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: geometry.size.height * 0.25)

                Text(title)
                    .foregroundColor(.black)
                    .font(.largeTitle.weight(.bold))
                    .multilineTextAlignment(.center)
                Text(description)
                    .foregroundColor(.black)
                    .font(.body)
                    .multilineTextAlignment(.center)
                Spacer()
                
                // bwi #3811: check for maintenance when the server selection is skipped
                if let doneButton = doneButton, let buttonCallback = buttonCallback {
                    Button(action: startButtonAction) {
                        Text(doneButton)
                            .foregroundColor(.white)
                            .padding(.vertical, 10)
                            .padding(.horizontal, 50)
                            .background(Color(ThemeService.shared().theme.tintColor))
                           .clipShape(RoundedRectangle(cornerRadius: 10))
                    }
                    .padding(.bottom, 100)
                    .alert(isPresented: $showAlert, content: {
                        service.alert(alertType: activeAlert) {
                            buttonCallback()
                        }
                    })
                }
            }
            .padding(.top, 100)
            .padding(.horizontal, 20)
            .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
    
    private func startButtonAction() {
        guard let buttonCallback = buttonCallback else {
            return
        }
        
        if BWIBuildSettings.shared.enableMaintenanceInfoOnLogin && BWIBuildSettings.shared.avoidServerSelectionOnAppConfig && AppConfigService.shared.isAppConfig {
            isFetchingDowntime = true   // show progresview
            
            if BWIBuildSettings.shared.useTestDataForDowntime {
                service.fetchDowntimes {
                    self.isFetchingDowntime = false // hide progressview
                    self.showAlertIfNeeded()
                }
            } else {
                service.fetchDowntimesWithDirectRequest { success in
                    DispatchQueue.main.async {
                        self.isFetchingDowntime = false   // hide progressview
                        if success {
                            self.showAlertIfNeeded()
                        } else {
                            buttonCallback()
                        }
                    }
                }
            }
        } else {
            buttonCallback()
        }
    }
    
    private func showAlertIfNeeded() {
        guard let buttonCallback = buttonCallback else {
            return
        }
        
        if service.showAlert() {
            activeAlert = service.alertType()
            showAlert = true
        } else {
            buttonCallback()
        }
    }
}

struct WelcomeExperienceView_Previews: PreviewProvider {
    static var previews: some View {
        WelcomeExperienceView()
    }
}
