import SwiftUI
import UserNotifications

struct Alarm: Identifiable, Codable, Equatable {
    let id: UUID
    var time: Date
    var isEnabled: Bool
    var soundName: String
    
    static func ==(lhs: Alarm, rhs: Alarm) -> Bool {
        lhs.id == rhs.id
    }
}

struct AlarmView: View {
    @State private var alarms: [Alarm] = []
    @State private var showAddAlarm = false
    @State private var newAlarmTime = Date()
    @State private var selectedSoundName = "default"
    
    let systemSounds = ["default", "bell", "chimes", "ding", "glass", "silence"]
    
    var body: some View {
        List {
            ForEach(alarms) { alarm in
                HStack {
                    VStack(alignment: .leading) {
                        Text(alarm.time, style: .time)
                            .font(.headline)
                        Text("Enabled: \(alarm.isEnabled ? "Yes" : "No")")
                            .font(.subheadline)
                        Text("Sound: \(alarm.soundName)")
                            .font(.caption)
                    }
                    Spacer()
                    Toggle("", isOn: binding(for: alarm))
                        .labelsHidden()
                }
            }
            .onDelete(perform: deleteAlarm)
        }
        .navigationTitle("Alarms")
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button(action: {
                    print("Tapped + button, showing Add Alarm sheet")
                    showAddAlarm = true
                    newAlarmTime = Date()
                    selectedSoundName = "default"
                }) {
                    Image(systemName: "plus")
                        .font(.title2)
                }
            }
        }
        .onAppear(perform: loadAlarms)
        .onChange(of: alarms) { _ in
            saveAlarms()
        }
        .sheet(isPresented: $showAddAlarm) {
            AddAlarmView(
                alarms: $alarms,
                systemSounds: systemSounds,
                newAlarmTime: $newAlarmTime,
                selectedSoundName: $selectedSoundName,
                showAddAlarm: $showAddAlarm
            )
        }
    }
    
    private func binding(for alarm: Alarm) -> Binding<Bool> {
        guard let index = alarms.firstIndex(where: { $0.id == alarm.id }) else {
            print("Binding error: Alarm \(alarm.id) not found")
            return .constant(false)
        }
        print("Binding created for alarm \(alarm.id) at index \(index), isEnabled: \(alarms[index].isEnabled)")
        return Binding(
            get: { alarms[index].isEnabled },
            set: { newValue in
                print("Setting isEnabled to \(newValue) for alarm \(alarm.id)")
                var updatedAlarm = alarms[index]
                updatedAlarm.isEnabled = newValue
                alarms[index] = updatedAlarm // Update array to trigger UI refresh
                updateAlarmNotification(alarm: updatedAlarm)
                saveAlarms()
            }
        )
    }
    
    private func deleteAlarm(at offsets: IndexSet) {
        print("Delete triggered for offsets: \(offsets)")
        let indices = offsets.map { $0 }
        guard !indices.isEmpty, indices.max()! < alarms.count else {
            print("Invalid delete offset")
            return
        }
        alarms.remove(atOffsets: offsets)
        updateAllNotifications()
        saveAlarms()
        print("Alarm(s) deleted")
    }
    
    private func updateAlarmNotification(alarm: Alarm) {
        UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [alarm.id.uuidString])
        if alarm.isEnabled {
            let content = UNMutableNotificationContent()
            content.title = "Wake Up!"
            content.body = "Your alarm is ringing."
            content.sound = alarm.soundName == "default" ? UNNotificationSound.default : UNNotificationSound(named: UNNotificationSoundName(rawValue: "\(alarm.soundName).caf"))
            
            let components = Calendar.current.dateComponents([.hour, .minute], from: alarm.time)
            let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
            let request = UNNotificationRequest(identifier: alarm.id.uuidString, content: content, trigger: trigger)
            UNUserNotificationCenter.current().add(request) { error in
                if let error = error {
                    print("Error scheduling notification: \(error)")
                } else {
                    print("Notification scheduled for \(alarm.id)")
                }
            }
        } else {
            print("Notification disabled for \(alarm.id)")
        }
    }
    
    private func updateAllNotifications() {
        UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
        for alarm in alarms where alarm.isEnabled {
            updateAlarmNotification(alarm: alarm)
        }
    }
    
    private func saveAlarms() {
        if let encoded = try? JSONEncoder().encode(alarms) {
            UserDefaults.standard.set(encoded, forKey: "SavedAlarms")
            print("Alarms saved: \(alarms.count)")
        } else {
            print("Failed to encode alarms")
        }
    }
    
    private func loadAlarms() {
        if let savedAlarms = UserDefaults.standard.data(forKey: "SavedAlarms"),
           let decodedAlarms = try? JSONDecoder().decode([Alarm].self, from: savedAlarms) {
            alarms = decodedAlarms
            updateAllNotifications()
            print("Alarms loaded: \(alarms.count)")
        } else {
            print("No saved alarms or decode failed")
        }
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { success, error in
            if let error = error {
                print("Authorization error: \(error)")
            } else {
                print("Authorization granted: \(success)")
            }
        }
    }
}

#Preview {
    AlarmView()
}
