//
//  TextFormattingSettings.swift
//  damus
//
//  Created by William Casarin on 2023-04-05.
//

import SwiftUI

fileprivate let CACHE_CLEAR_BUTTON_RESET_TIME_IN_SECONDS: Double = 60
fileprivate let MINIMUM_CACHE_CLEAR_BUTTON_DELAY_IN_SECONDS: Double = 1

/// A simple type to keep track of the cache clearing state
fileprivate enum CacheClearingState {
    case not_cleared
    case clearing
    case cleared
}

struct ResizedEventPreview: View {
    let damus_state: DamusState
    @ObservedObject var settings: UserSettingsStore

    var body: some View {
        EventView(damus: damus_state, event: test_note, pubkey: test_note.pubkey, options: [.wide, .no_action_bar])
    }
}

struct AppearanceSettingsView: View {
    let damus_state: DamusState
    @ObservedObject var settings: UserSettingsStore
    @Environment(\.dismiss) var dismiss
    @State fileprivate var cache_clearing_state: CacheClearingState = .not_cleared
    @State var showing_cache_clear_alert: Bool = false
    
    @State var showing_enable_animation_alert: Bool = false
    @State var enable_animation_toggle_is_user_initiated: Bool = true

    var FontSize: some View {
        VStack(alignment: .leading) {
            Slider(value: $settings.font_size, in: 0.5...2.0, step: 0.1)
                .padding()

            // Sample text to show how the font size would look
            ResizedEventPreview(damus_state: damus_state, settings: settings)

        }
    }

    var body: some View {
        Form {
            Section(NSLocalizedString("Font Size", comment: "Section label for font size settings.")) {
                FontSize
            }

            // MARK: - Text Truncation
            Section(header: Text(NSLocalizedString("Text Truncation", comment: "Section header for damus text truncation user configuration"))) {
                Toggle(NSLocalizedString("Truncate timeline text", comment: "Setting to truncate text in timeline"), isOn: $settings.truncate_timeline_text)
                    .toggleStyle(.switch)
                Toggle(NSLocalizedString("Truncate notification mention text", comment: "Setting to truncate text in mention notifications"), isOn: $settings.truncate_mention_text)
                    .toggleStyle(.switch)
            }

            Section(header: Text("User Statuses", comment: "Section header for user profile status settings.")) {
                Toggle(NSLocalizedString("Show general statuses", comment: "Settings toggle for enabling general user statuses"), isOn: $settings.show_general_statuses)
                    .toggleStyle(.switch)

                Toggle(NSLocalizedString("Show music statuses", comment: "Settings toggle for enabling now playing music statuses"), isOn: $settings.show_music_statuses)
                    .toggleStyle(.switch)
            }

            // MARK: - Accessibility
            Section(header: Text(NSLocalizedString("Accessibility", comment: "Section header for accessibility settings"))) {
                Toggle(NSLocalizedString("Left Handed", comment: "Moves the post button to the left side of the screen"), isOn: $settings.left_handed)
                    .toggleStyle(.switch)
            }
            
            // MARK: - Images
            Section(NSLocalizedString("Images", comment: "Section title for images configuration.")) {
                self.EnableAnimationsToggle
                Toggle(NSLocalizedString("Always show images", comment: "Setting to always show and never blur images"), isOn: $settings.always_show_images)
                    .toggleStyle(.switch)
                
                Toggle(NSLocalizedString("Media previews", comment: "Setting to show media"), isOn: $settings.media_previews)
                    .toggleStyle(.switch)
                
                Picker(NSLocalizedString("Image uploader", comment: "Prompt selection of user's image uploader"),
                       selection: $settings.default_media_uploader) {
                    ForEach(MediaUploader.allCases, id: \.self) { uploader in
                        Text(uploader.model.displayName)
                            .tag(uploader.model.tag)
                    }
                }

                self.ClearCacheButton
            }
            
            // MARK: - Content filters and moderation
            Section(
                header: Text(NSLocalizedString("Content filters", comment: "Section title for content filtering/moderation configuration.")),
                footer: Text(NSLocalizedString("Notes with the #nsfw tag usually contains adult content or other \"Not safe for work\" content", comment: "Section footer clarifying what #nsfw (not safe for work) tags mean"))
            ) {
                Toggle(NSLocalizedString("Hide notes with #nsfw tags", comment: "Setting to hide notes with the #nsfw (not safe for work) tags"), isOn: $settings.hide_nsfw_tagged_content)
                    .toggleStyle(.switch)
            }
            
            // MARK: - Profiles
            Section(
                header: Text(NSLocalizedString("Profiles", comment: "Section title for profile view configuration.")),
                footer: Text(NSLocalizedString("Profile action sheets allow you to follow, zap, or DM profiles more quickly without having to view their full profile", comment: "Section footer clarifying what the profile action sheet feature does"))
            ) {
                Toggle(NSLocalizedString("Show profile action sheets", comment: "Setting to show profile action sheets when clicking on a user's profile picture"), isOn: $settings.show_profile_action_sheet_on_pfp_click)
                    .toggleStyle(.switch)
            }
                

        }
        .navigationTitle(NSLocalizedString("Appearance", comment: "Navigation title for text and appearance settings."))
        .onReceive(handle_notify(.switched_timeline)) { _ in
            dismiss()
        }
    }
    
    func clear_cache_button_action() {
        cache_clearing_state = .clearing
        
        let group = DispatchGroup()
        
        group.enter()
        DamusCacheManager.shared.clear_cache(damus_state: self.damus_state, completion: {
            group.leave()
        })
        
        // Make clear cache button take at least a second or so to avoid issues with labor perception bias (https://growth.design/case-studies/labor-perception-bias)
        group.enter()
        DispatchQueue.main.asyncAfter(deadline: .now() + MINIMUM_CACHE_CLEAR_BUTTON_DELAY_IN_SECONDS) {
            group.leave()
        }
        
        group.notify(queue: .main) {
            cache_clearing_state = .cleared
            DispatchQueue.main.asyncAfter(deadline: .now() + CACHE_CLEAR_BUTTON_RESET_TIME_IN_SECONDS) {
                cache_clearing_state = .not_cleared
            }
        }
    }
    
    var EnableAnimationsToggle: some View {
        Toggle(NSLocalizedString("Animations", comment: "Toggle to enable or disable image animation"), isOn: $settings.enable_animation)
            .toggleStyle(.switch)
            .onChange(of: settings.enable_animation) { _ in
                if self.enable_animation_toggle_is_user_initiated {
                    self.showing_enable_animation_alert = true
                }
                else {
                    self.enable_animation_toggle_is_user_initiated = true
                }
            }
            .alert(isPresented: $showing_enable_animation_alert) {
                Alert(title: Text(NSLocalizedString("Confirmation", comment: "Confirmation dialog title")),
                      message: Text(NSLocalizedString("Changing this setting will cause the cache to be cleared. This will free space, but images may take longer to load again. Are you sure you want to proceed?", comment: "Message explaining consequences of changing the 'enable animation' setting")),
                      primaryButton: .default(Text(NSLocalizedString("OK", comment: "Button label indicating user wants to proceed."))) {
                          self.clear_cache_button_action()
                      },
                      secondaryButton: .cancel() {
                          // Toggle back if user cancels action
                          self.enable_animation_toggle_is_user_initiated = false
                          settings.enable_animation.toggle()
                      }
                )
            }
    }
    
    var ClearCacheButton: some View {
        Button(action: { self.showing_cache_clear_alert = true }, label: {
            HStack(spacing: 6) {
                switch cache_clearing_state {
                    case .not_cleared:
                        Text(NSLocalizedString("Clear Cache", comment: "Button to clear image cache."))
                    case .clearing:
                        ProgressView()
                        Text(NSLocalizedString("Clearing Cache", comment: "Loading message indicating that the cache is being cleared."))
                    case .cleared:
                        Image(systemName: "checkmark.circle.fill")
                            .foregroundColor(.green)
                        Text(NSLocalizedString("Cache has been cleared", comment: "Message indicating that the cache was successfully cleared."))
                }
            }
        })
        .disabled(self.cache_clearing_state != .not_cleared)
        .alert(isPresented: $showing_cache_clear_alert) {
            Alert(title: Text(NSLocalizedString("Confirmation", comment: "Confirmation dialog title")),
                  message: Text(NSLocalizedString("Are you sure you want to clear the cache? This will free space, but images may take longer to load again.", comment: "Message explaining what it means to clear the cache, asking if user wants to proceed.")),
                  primaryButton: .default(Text(NSLocalizedString("OK", comment: "Button label indicating user wants to proceed."))) {
                      self.clear_cache_button_action()
                  },
                  secondaryButton: .cancel())
        }
    }
}


struct TextFormattingSettings_Previews: PreviewProvider {
    static var previews: some View {
        AppearanceSettingsView(damus_state: test_damus_state, settings: UserSettingsStore())
    }
}
