//
/*
 * Copyright (c) 2022 BWI GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import SwiftUI

struct MaintenanceView: View {
    @State var jsonStringFromServer = ""
    @State var jsonStringFromUserDefaults = ""
    @State var isFetching: Bool = false
    var session: MXSession?
    
    var body: some View {
        ScrollView {
            VStack(alignment: .leading) {
                ServerDataView

                Divider()
                
                UserDefaultDataView
            }
        }
        .navigationTitle(BWIL10n.bwiSettingsDeveloperMaintenance)
        .navigationBarTitleDisplayMode(.inline)
        .onAppear {
            Task {
                await fetchDataFromServer()
            }
            fetchDataFromUserDefaults()
        }
    }
    
    
    private var ServerDataView: some View {
        return VStack(alignment: .leading) {
            Text(BWIL10n.bwiSettingsDeveloperMaintenanceServerData)
                .font(.title3)
                .padding()
            
            if isFetching {
                HStack {
                    Spacer()
                    ProgressView()
                        .progressViewStyle(CircularProgressViewStyle())
                    Spacer()
                }
            }
            
            HStack {
                Text(jsonStringFromServer)
                    .font(.caption)
                    .padding()
                Spacer()
            }
            
            HStack {
                Spacer()
                Button {
                    Task {
                        await fetchDataFromServer()
                    }
                } label: {
                    Text(BWIL10n.bwiSettingsDeveloperMaintenanceReload)
                }
                Spacer()
            }
        }
    }
    
    private var UserDefaultDataView: some View {
        return VStack(alignment: .leading) {
            Text(BWIL10n.bwiSettingsDeveloperMaintenanceLocalData)
                .font(.title3)
                .padding()
            HStack {
                Text(jsonStringFromUserDefaults)
                    .font(.caption)
                    .padding()
                Spacer()
            }
            HStack {
                Spacer()
                Button {
                    fetchDataFromUserDefaults()
                } label: {
                    Text(BWIL10n.bwiSettingsDeveloperMaintenanceReload)
                }
                Spacer()
            }
        }
    }
    
    
    // MARK: sync functions
    private func fetchDataFromServer() async {
        isFetching = true
        
        ServerDowntimeDefaultService.shared.fetchDowntimesWithDirectRequest(localUrlString: nil) { _, response, data, error in
            isFetching = false
            guard let response = response, response.statusCode == 200 else {
                if let error = error {
                    jsonStringFromServer = error.localizedDescription
                } else {
                    jsonStringFromServer = ""
                }
                return
            }

            do {
                if let data = data, let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                    let jsonData = try JSONSerialization.data(withJSONObject: jsonObject as Any, options: [.prettyPrinted])
                    jsonStringFromServer = String(data: jsonData, encoding: .utf8) ?? ""
                } else {
                    jsonStringFromServer = ""
                }
            } catch {
                jsonStringFromServer = ""
            }
        }
    }
    
    private func fetchDataFromUserDefaults() {
        jsonStringFromUserDefaults = ""
        let encodedDowntimes = UserDefaults.standard.object(forKey: "BWI_ServerDowntimes") as? [Data] ?? [Data]()
        let encodedValidAppVersions = UserDefaults.standard.data(forKey: "BWI_ValidAppVersions") ?? Data()
        
        var jsonString = ""
        
        let serverDowntimes = encodedDowntimes
            .compactMap { try? JSONDecoder().decode(ServerDowntime.self, from: $0) }
        
        for serverDowntime in serverDowntimes {
            do {
                let data = try JSONEncoder().encode(serverDowntime)
                let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
                let newJsonData = try JSONSerialization.data(withJSONObject: jsonObject as Any, options: [.prettyPrinted])
                jsonString.append(contentsOf: String(data: newJsonData, encoding: .utf8) ?? "")
                jsonString.append(contentsOf: !jsonString.isEmpty ? ",\n" : "")
            } catch {}
        }
        do {
            let jsonObjectAppVersion = try JSONSerialization.jsonObject(with: encodedValidAppVersions, options: []) as? [String: Any]
            let jsonDataAppVersion = try JSONSerialization.data(withJSONObject: jsonObjectAppVersion as Any, options: [.prettyPrinted])
            jsonString.append(contentsOf: String(data: jsonDataAppVersion, encoding: .utf8) ?? "")
        } catch {}
        
        jsonStringFromUserDefaults = jsonString

    }
}

struct MaintenanceView_Previews: PreviewProvider {
    static var previews: some View {
        MaintenanceView()
    }
}
