//
//  NewStopwatchView.swift
//  LeCountdown
//
//  Created by Laurent Morvillier on 01/02/2023.
//

import SwiftUI
import CoreData
import WidgetKit

struct NewStopwatchView: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    
    @Binding var isPresented: Bool

    var body: some View {
        StopwatchEditView(isPresented: $isPresented)
            .environment(\.managedObjectContext, viewContext)
            .navigationTitle("New stopwatch")
    }

}

struct StopwatchEditView: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    @Environment(\.dismiss) private var dismiss
    
    @StateObject var model: TimerModel = TimerModel()
    
    var stopwatch: Stopwatch? = nil

    @Binding var isPresented: Bool
    
    @State var time: Date = Date()
    
    @State var nameString: String = ""

    @State var playSound: Bool = false

    @State var image: CoolPic = .pic1

    @State var deleteConfirmationShown: Bool = false
    @State var activityNameConfirmationShown: Bool = false
    @State fileprivate var _rename: Bool? = nil

    @State var errorShown: Bool = false
    @State var error: Error? = nil
        
    @State var _isAdding: Bool = false
    
    @Environment(\.isPresented) var envIsPresented

    @FetchRequest(sortDescriptors: [])
    private var timers: FetchedResults<AbstractTimer>

    var body: some View {
        NavigationStack {
            Rectangle()
                .frame(width: 0.0, height: 0.0)
                .onChange(of: envIsPresented) { newValue in
                    if !newValue && !self._isAdding {
                        self._save()
                    }
                }
            StopwatchFormView(nameBinding: self.$nameString,
                              imageBinding: self.$image,
                              playSoundBinding: self.$playSound).environmentObject(self.model)
            .onAppear {
                self._onAppear()
            }
            .confirmationDialog("", isPresented: $deleteConfirmationShown, actions: {
                Button("Yes", role: .destructive) {
                    withAnimation {
                        self._delete()
                    }
                }.keyboardShortcut(.defaultAction)
                Button("No", role: .cancel) {}
            }, message: {
                Text("Do you really want to delete?")
            })
            .confirmationDialog("", isPresented: $activityNameConfirmationShown, actions: {
                Button("Rename") {
                    self._rename = true
                    self._save()
                }
                Button("New activity") {
                    self._rename = false
                    self._save()
                }
            }, message: {
                Text("Do you wish to rename or create a new activity")
            })

            .alert("", isPresented: $errorShown, actions: { }, message: {
                Text(error?.localizedDescription ?? "error")
            })
            .toolbar {
                if self._isAdding {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button("Cancel") {
                            self._cancel()
                        }
                    }
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button("Save") {
                            self._save()
                        }
                    }
                } else {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button {
                            self.deleteConfirmationShown = true
                        } label: {
                            Image(systemName: "trash")
                        }
                    }
                }
            }
            .navigationTitle("Edit stopwatch")
        }
        
    }
    
    // MARK: - Bindings
    
//    func playlistBinding(playlist: Playlist) -> Binding<Bool> {
//        Binding<Bool>(
//            get: { self.playlists.contains(playlist) },
//            set: { self._playlistChange(playlist, selected: $0) }
//        )
//    }
//
//    fileprivate func _playlistChange(_ playlist: Playlist, selected: Bool) {
//
//        print("_playlistChange")
//
//        let sounds: [Sound] = SoundCatalog.main.sounds(for: playlist)
//        if selected {
//            self.playlists.insert(playlist)
//            self.sounds.formUnion(sounds)
//        } else {
//            self.playlists.remove(playlist)
//            self.sounds.formIntersection(sounds)
//        }
//    }
//
//    func soundBinding(sound: Sound) -> Binding<Bool> {
//        Binding<Bool>(
//            get: { self.sounds.contains(sound) },
//            set: { self._soundChange(sound, selected: $0) }
//        )
//    }
//
//    fileprivate func _soundChange(_ sound: Sound, selected: Bool) {
//
//        print("_soundChange")
//
//        if selected {
//            self.sounds.insert(sound)
//        } else {
//            self.sounds.remove(sound)
//        }
//
//        // toggle playlist if necessary
//        let playlist = sound.playlist
//        let playlistSounds: [Sound] = SoundCatalog.main.sounds(for: playlist)
//        if self.sounds.isSuperset(of: playlistSounds) {
//            self.playlists.insert(playlist)
//        } else {
//            self.playlists.remove(playlist)
//        }
//
//    }
    
    // MARK: - Business

    fileprivate func _onAppear() {
        
        self._isAdding = (self.stopwatch == nil)
        
        if let stopwatch {
            
            if let name = stopwatch.activity?.name, !name.isEmpty {
                self.nameString = name
            }
            
//            if let sound = Sound(rawValue: Int(stopwatch.sound)) {
//                self.sound = sound
//            }
            
            if let image = stopwatch.image, let coolpic = CoolPic(rawValue: image) {
                self.image = coolpic
            }
        }
        
    }
    
    fileprivate func _cancel() {
        viewContext.rollback()
        self.isPresented = false
    }
    
    fileprivate func _save() {
        
        let sw: Stopwatch
        if let stopwatch {
            sw = stopwatch
        } else {
            sw = Stopwatch(context: viewContext)
        }
        
        if self._isAdding {
            let max: Int16
            if let maxOrder = self.timers.map({ $0.order }).max() {
                max = maxOrder + 1
            } else {
                max = 0
            }
            sw.order = max
        }

        
//        if self._isAdding {
//            let max = self.countdowns.map { $0.order }.max() ?? 0
//            cd.order = max + 1
//        }
        
        sw.image = self.image.rawValue
        
//        if self.playSound {
//            sw.sound = Int16(self.sound.rawValue)
//        } else {
////            sw.sound = nil
//        }
        
        if !self.nameString.isEmpty {
            
            if let activity = sw.activity, let currentActivityName = activity.name, self.nameString != currentActivityName {
                
                switch self._rename {
                case .none:
                    self.activityNameConfirmationShown = true
                    return
                case .some(let rename):
                    if rename {
                        activity.name = self.nameString
                    } else {
                        sw.activity = CoreDataRequests.getOrCreateActivity(name: self.nameString)
                    }
                }
            } else {
                sw.activity = CoreDataRequests.getOrCreateActivity(name: self.nameString)
            }
            
        }
        
        self._saveContext()
        
        WidgetCenter.shared.reloadAllTimelines() // refreshes the visual of existing widgets
        
        self._popOrDismiss()
    }
    
    fileprivate func _popOrDismiss() {
        if self._isAdding {
            self.isPresented = false
        } else {
            dismiss()
        }
    }
    
    fileprivate func _delete() {
        
        guard let stopwatch else {
            return
        }
        
        viewContext.delete(stopwatch)
        self._saveContext()

        WidgetCenter.shared.reloadAllTimelines() // refreshes the visual of existing widgets

        self._popOrDismiss()
    }
    
    fileprivate func _saveContext() {
        do {
            try viewContext.save()
        } catch {
            Logger.error(error)
            self.errorShown = true
            self.error = error
        }
    }
    
}

struct NewStopwatchView_Previews: PreviewProvider {
    static var previews: some View {
        NewStopwatchView(isPresented: .constant(true))
            .environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}
