//
//  SettingsView.swift
//  Feels
//
//  Created by Trey Tartt on 1/8/22.
//

import SwiftUI
import CloudKitSyncMonitor
import UniformTypeIdentifiers

struct SettingsView: View {
    @Environment(\.dismiss) var dismiss
        
    @State private var showingExporter = false
    @State private var showingImporter = false
    @State private var importContent = ""
    
    @State private var showOnboarding = false
        
    @State private var showSpecialThanks = false
    @State private var showWhyBGMode = false
    @ObservedObject var syncMonitor = SyncMonitor.shared
    
    @AppStorage(UserDefaultsStore.Keys.useCloudKit.rawValue, store: GroupUserDefaults.groupDefaults) private var useCloudKit = false
    @AppStorage(UserDefaultsStore.Keys.deleteEnable.rawValue, store: GroupUserDefaults.groupDefaults) private var deleteEnabled = true
    @AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system
    @AppStorage(UserDefaultsStore.Keys.textColor.rawValue, store: GroupUserDefaults.groupDefaults) private var textColor: Color = DefaultTextColor.textColor

    var body: some View {
        ScrollView {
            VStack {
                Group {
                    closeButtonView
                        .padding()
                    
//                    cloudKitEnable
                    canDelete
                    showOnboardingButton
                    specialThanksCell
                }
                
                Group {
                    Divider()
                    Text("Test builds only")
                    addTestDataCell
                    clearDB
                    randomIcons
                    
                    if useCloudKit {
                        cloudKitStatus
                    }
                    
                    exportData
                    importData
                    Divider()
                }
                Spacer()
                
                Text("\(Bundle.main.appName) v \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))")
                    .font(.body)
            }
            .padding()
        }.sheet(isPresented: $showOnboarding) {
            OnboardingMain(onboardingData: UserDefaultsStore.getOnboarding(),
                           updateBoardingDataClosure: { onboardingData in
                OnboardingDataDataManager.shared.updateOnboardingData(onboardingData: onboardingData)
                showOnboarding = false
            })
        }
        .onAppear(perform: {
            EventLogger.log(event: "show_settings_view")
        })
        .background(
            theme.currentTheme.bg
                .edgesIgnoringSafeArea(.all)
        )
        .fileExporter(isPresented: $showingExporter,
                      documents: [
                        TextFile()
                      ],
                      contentType: .plainText,
                      onCompletion: { result in
            switch result {
            case .success(let url):
                EventLogger.log(event: "exported_file")
                print("Saved to \(url)")
            case .failure(let error):
                print(error.localizedDescription)
            }
        })
        .fileImporter(isPresented: $showingImporter, allowedContentTypes: [.text],
                      allowsMultipleSelection: false) { result in
            do {
                guard let selectedFile: URL = try result.get().first else { return }
                if selectedFile.startAccessingSecurityScopedResource() {
                    let dateFormatter = DateFormatter()
                    dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss +0000"
                    
                    guard let input = String(data: try Data(contentsOf: selectedFile), encoding: .utf8) else { return }
                    defer { selectedFile.stopAccessingSecurityScopedResource() }
                    
                    var rows = input.components(separatedBy: "\n")
                    rows.removeFirst()
                    for row in rows {
                        let columns = row.components(separatedBy: ",")
                        if columns.count != 7 {
                            continue
                        }
                        let moodEntry = MoodEntry(context: PersistenceController.shared.viewContext)
                        moodEntry.canDelete = Bool(columns[0])!
                        moodEntry.canEdit = Bool(columns[1])!
                        moodEntry.entryType = Int16(columns[2])!
                        moodEntry.forDate = dateFormatter.date(from: columns[3])
                        moodEntry.moodValue = Int16(columns[4])!
                        moodEntry.timestamp = dateFormatter.date(from: columns[5])
                        moodEntry.weekDay = Int16(columns[6])!
                        try! PersistenceController.shared.viewContext.save()
                    }
                    PersistenceController.shared.saveAndRunDataListerners()
                    EventLogger.log(event: "import_file")
                } else {
                    EventLogger.log(event: "error_import_file")
                }
            } catch {
                // Handle failure.
                EventLogger.log(event: "error_import_file", withData: ["error": error.localizedDescription])
                print("Unable to read file contents")
                print(error.localizedDescription)
            }
        }
    }
    
    private var closeButtonView: some View {
        HStack{
            Spacer()
            Button(action: {
                EventLogger.log(event: "tap_settings_close")
                dismiss()
            }, label: {
                Text(String(localized: "settings_view_exit"))
                    .font(.body)
                    .foregroundColor(Color(UIColor.systemBlue))
            })
        }
    }
    
    private var specialThanksCell: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            VStack {
                Button(action: {
                    EventLogger.log(event: "tap_show_special_thanks")
                    withAnimation{
                        showSpecialThanks.toggle()
                    }
                }, label: {
                    Text(String(localized: "settings_view_special_thanks_to_title"))
                        .foregroundColor(textColor)
                })
                    .padding()
                
                if showSpecialThanks {
                    Divider()
                    Link("Font Awesome", destination: URL(string: "https://fontawesome.com")!)
                        .accentColor(textColor)
                        .padding(.bottom)
                    
                    Divider()
                    
                    Link("Charts", destination: URL(string: "https://github.com/danielgindi/Charts")!)
                        .accentColor(textColor)
                        .padding(.bottom)
                }
            }
        }
        .frame(minWidth: 0, maxWidth: .infinity)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
    
    private var addTestDataCell: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            Button(action: {
                PersistenceController.shared.populateTestData()
            }, label: {
                Text("Add test data")
                    .foregroundColor(textColor)
            })
                .padding()
        }
        .fixedSize(horizontal: false, vertical: true)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
    
    private var clearDB: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            Button(action: {
                PersistenceController.shared.clearDB()
            }, label: {
                Text("Clear DB")
                    .foregroundColor(textColor)
            })
                .padding()
        }
        .fixedSize(horizontal: false, vertical: true)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
    
    private var whyBackgroundMode: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            VStack {
                Button(action: {
                    withAnimation{
                        showWhyBGMode.toggle()
                    }
                }, label: {
                    Text(String(localized: "settings_view_why_bg_mode_title"))
                        .foregroundColor(textColor)
                })
                    .padding()
                if showWhyBGMode {
                    Text(String(localized: "settings_view_why_bg_mode_body"))
                        .foregroundColor(textColor)
                        .padding()
                }
            }
        }
        .fixedSize(horizontal: false, vertical: true)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
    
    private var showOnboardingButton: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            Button(action: {
                EventLogger.log(event: "tap_show_onboarding")
                showOnboarding.toggle()
            }, label: {
                Text(String(localized: "settings_view_show_onboarding"))
                    .foregroundColor(textColor)
            })
                .padding()
        }
        .fixedSize(horizontal: false, vertical: true)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
    
    private var cloudKitEnable: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            VStack {
                Toggle(isOn: $useCloudKit, label: {
                    Text(String(localized: "settings_use_cloudkit_title"))
                        .foregroundColor(textColor)
                })
                    .onChange(of: useCloudKit) { newValue in
                        EventLogger.log(event: "toggle_use_cloudkit", withData: ["value": newValue])
                    }
                    .padding()
                Text(String(localized: "settings_use_cloudkit_body"))
                    .foregroundColor(textColor)
            }
            .padding(.bottom)
        }
        .fixedSize(horizontal: false, vertical: true)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
    
    private var cloudKitStatus: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            VStack {
                Image(systemName: syncMonitor.syncStateSummary.symbolName)
                    .foregroundColor(syncMonitor.syncStateSummary.symbolColor)
                Text( syncMonitor.syncStateSummary.isBroken ? "cloudkit is broken" : "cloudkit is good")
                    .foregroundColor(textColor)
            }
            .padding()
        }
        .fixedSize(horizontal: false, vertical: true)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
    
    private var canDelete: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            VStack {
                Toggle(String(localized: "settings_use_delete_enable"),
                       isOn: $deleteEnabled)
                    .onChange(of: deleteEnabled) { newValue in
                        EventLogger.log(event: "toggle_can_delete", withData: ["value": newValue])
                    }
                    .foregroundColor(textColor)
                    .padding()
            }
        }
        .fixedSize(horizontal: false, vertical: true)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
    
    private var exportData: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            Button(action: {
                showingExporter.toggle()
                EventLogger.log(event: "export_data", withData: ["title": "default"])
            }, label: {
                Text("Export")
                    .foregroundColor(textColor)
            })
                .padding()
        }
        .fixedSize(horizontal: false, vertical: true)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
       
    private var importData: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            Button(action: {
                showingImporter.toggle()
                EventLogger.log(event: "import_data", withData: ["title": "default"])
            }, label: {
                Text("Import")
                    .foregroundColor(textColor)
            })
                .padding()
        }
        .fixedSize(horizontal: false, vertical: true)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
    
    private var randomIcons: some View {
        ZStack {
            theme.currentTheme.secondaryBGColor
            Button(action: {
                var iconViews = [UIImage]()
               
//                for _ in 0...300 {
//                    iconViews.append(
//                        IconView(iconViewModel: IconViewModel(
//                            backgroundImage: MoodImages.FontAwesome.icon(forMood: .great),
//                            bgColor: Color.random(),
//                            bgOverlayColor: Color.random(),
//                            centerImage: MoodImages.FontAwesome.icon(forMood: .great),
//                            innerColor: Color.random())
//                                ).asImage(size:  CGSize(width: 1024, height: 1024)))
//                }
                
                iconViews.append(
                    IconView(iconViewModel: IconViewModel(
                        backgroundImage: MoodImages.FontAwesome.icon(forMood: .great),
                        bgColor: IconViewModel.great.bgColor,
                        bgOverlayColor: IconViewModel.great.bgOverlayColor,
                        centerImage: MoodImages.FontAwesome.icon(forMood: .great),
                        innerColor: IconViewModel.great.innerColor)
                            ).asImage(size:  CGSize(width: 1024, height: 1024))
                )
                
                iconViews.append(
                    IconView(iconViewModel: IconViewModel(
                        backgroundImage: MoodImages.FontAwesome.icon(forMood: .great),
                        bgColor: IconViewModel.good.bgColor,
                        bgOverlayColor: IconViewModel.good.bgOverlayColor,
                        centerImage: MoodImages.FontAwesome.icon(forMood: .great),
                        innerColor: IconViewModel.good.innerColor)
                            ).asImage(size:  CGSize(width: 1024, height: 1024))
                )
                
                iconViews.append(
                    IconView(iconViewModel: IconViewModel(
                        backgroundImage: MoodImages.FontAwesome.icon(forMood: .great),
                        bgColor: IconViewModel.average.bgColor,
                        bgOverlayColor: IconViewModel.average.bgOverlayColor,
                        centerImage: MoodImages.FontAwesome.icon(forMood: .great),
                        innerColor: IconViewModel.average.innerColor)
                            ).asImage(size:  CGSize(width: 1024, height: 1024))
                )
                
                iconViews.append(
                    IconView(iconViewModel: IconViewModel(
                        backgroundImage: MoodImages.FontAwesome.icon(forMood: .great),
                        bgColor: IconViewModel.bad.bgColor,
                        bgOverlayColor: IconViewModel.bad.bgOverlayColor,
                        centerImage: MoodImages.FontAwesome.icon(forMood: .great),
                        innerColor: IconViewModel.bad.innerColor)
                            ).asImage(size:  CGSize(width: 1024, height: 1024))
                )
                
                iconViews.append(
                    IconView(iconViewModel: IconViewModel(
                        backgroundImage: MoodImages.FontAwesome.icon(forMood: .great),
                        bgColor: IconViewModel.horrible.bgColor,
                        bgOverlayColor: IconViewModel.horrible.bgOverlayColor,
                        centerImage: MoodImages.FontAwesome.icon(forMood: .great),
                        innerColor: IconViewModel.horrible.innerColor)
                            ).asImage(size:  CGSize(width: 1024, height: 1024))
                )
                
                
//                iconViews.append(
//                    IconView(iconViewModel: IconViewModel(
//                        backgroundImage: MoodImages.FontAwesome.icon(forMood: .great),
//                        bgColor: Color(hex: "EF0CF3"),
//                        bgOverlayColor: Color(hex: "EF0CF3").darker(by: 40),
//                        centerImage: MoodImages.FontAwesome.icon(forMood: .great),
//                        innerColor: Color(hex: "EF0CF3"))
//                            ).asImage(size:  CGSize(width: 1024, height: 1024))
//                )
//
//                iconViews.append(
//                    IconView(iconViewModel: IconViewModel(
//                        backgroundImage: MoodImages.FontAwesome.icon(forMood: .great),
//                        bgColor: Color(hex: "1AE5D6"),
//                        bgOverlayColor: Color(hex: "1AE5D6").darker(by: 40),
//                        centerImage: MoodImages.FontAwesome.icon(forMood: .great),
//                        innerColor: Color(hex: "1AE5D6"))
//                            ).asImage(size:  CGSize(width: 1024, height: 1024))
//                )
//
//                iconViews.append(
//                    IconView(iconViewModel: IconViewModel(
//                        backgroundImage: MoodImages.FontAwesome.icon(forMood: .great),
//                        bgColor: Color(hex: "633EC1"),
//                        bgOverlayColor: Color(hex: "633EC1").darker(by: 40),
//                        centerImage: MoodImages.FontAwesome.icon(forMood: .great),
//                        innerColor: Color(hex: "633EC1"))
//                            ).asImage(size:  CGSize(width: 1024, height: 1024))
//                )
//
//                iconViews.append(
//                    IconView(iconViewModel: IconViewModel(
//                        backgroundImage: MoodImages.FontAwesome.icon(forMood: .great),
//                        bgColor: Color(hex: "10F30C"),
//                        bgOverlayColor: Color(hex: "10F30C").darker(by: 40),
//                        centerImage: MoodImages.FontAwesome.icon(forMood: .great),
//                        innerColor: Color(hex: "10F30C"))
//                            ).asImage(size:  CGSize(width: 1024, height: 1024))
//                )
                
                for (idx, image) in iconViews.enumerated() {
                    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
                    var path = paths[0].appendingPathComponent("icons").path
                    path = path.appending("\(idx).jpg")
                    let url = URL(fileURLWithPath: path)
                    do {
                        try image.jpegData(compressionQuality: 1.0)?.write(to: url, options: .atomic)
                        print(url)
                    } catch {
                        print(error.localizedDescription)
                    }
                }
                
            }, label: {
                Text("Create random icons")
                    .foregroundColor(textColor)
            })
                .padding()
        }
        .fixedSize(horizontal: false, vertical: true)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
    }
}

struct TextFile: FileDocument {
    // tell the system we support only plain text
    static var readableContentTypes = [UTType.plainText]

    // by default our document is empty
    var text = ""

    // a simple initializer that creates new, empty documents
    init() {
        let entries = PersistenceController.shared.getData(startDate: Date(timeIntervalSince1970: 0),
                                                           endDate: Date(),
                                                           includedDays: [])
        
        var csvString = "canDelete,canEdit,entryType,forDate,moodValue,timestamp,weekDay\n"
        for entry in entries {
            let canDelete = entry.canDelete
            let canEdit = entry.canEdit
            let entryType = entry.entryType
            let forDate = entry.forDate!
            let moodValue = entry.moodValue
            let timestamp = entry.timestamp!
            let weekDay = entry.weekDay
            
            let dataString = "\(canDelete),\(canEdit),\(entryType),\(String(describing: forDate)),\(moodValue),\(String(describing:timestamp)),\(weekDay)\n"
            print("DATA: \(dataString)")
            csvString = csvString.appending(dataString)
        }
        text = csvString
    }

    // this initializer loads data that has been saved previously
    init(configuration: ReadConfiguration) throws {
        if let data = configuration.file.regularFileContents {
            text = String(decoding: data, as: UTF8.self)
        }
    }

    // this will be called when the system wants to write our data to disk
    func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        let data = Data(text.utf8)
        return FileWrapper(regularFileWithContents: data)
    }
}

struct SettingsView_Previews: PreviewProvider {
    static var previews: some View {
        SettingsView()
        
        SettingsView()
            .preferredColorScheme(.dark)
    }
}
