import SwiftUI
import SwiftData
import OSLog

private let logger = Logger(subsystem: "nahbar", category: "Migration")

// MARK: - ContainerFallback
// Zeigt an, auf welche Stufe die Container-Erstellung zurückgefallen ist.
// InMemory bedeutet: Daten werden NICHT persistent gespeichert.

enum ContainerFallback: Equatable {
    case cloudKit   // Ideal: CloudKit aktiv
    case localOnly  // CloudKit deaktiviert oder nicht verfügbar
    case inMemory   // Letzter Ausweg – Daten gehen beim Beenden verloren
}

// MARK: - Schema V1
// Originalschema: Moment hatte noch kein sourceRaw-Feld.

enum NahbarSchemaV1: VersionedSchema {
    static var versionIdentifier = Schema.Version(1, 0, 0)
    static var models: [any PersistentModel.Type] {
        [Person.self, Moment.self, LogEntry.self]
    }

    @Model final class Person {
        var id: UUID = UUID()
        var name: String = ""
        var tagRaw: String = "Andere"
        var birthday: Date? = nil
        var occupation: String? = nil
        var location: String? = nil
        var interests: String? = nil
        var generalNotes: String? = nil
        var nudgeFrequencyRaw: String = "Monatlich"
        var photoData: Data? = nil
        var nextStep: String? = nil
        var nextStepCompleted: Bool = false
        var nextStepReminderDate: Date? = nil
        var lastSuggestedForCall: Date? = nil
        var createdAt: Date = Date()
        @Relationship(deleteRule: .cascade) var moments: [Moment]? = []
        @Relationship(deleteRule: .cascade) var logEntries: [LogEntry]? = []
        init() {}
    }

    @Model final class Moment {
        var id: UUID = UUID()
        var text: String = ""
        var typeRaw: String = "Gespräch"
        var createdAt: Date = Date()
        var person: Person? = nil
        init() {}
    }

    @Model final class LogEntry {
        var id: UUID = UUID()
        var typeRaw: String = "Schritt abgeschlossen"
        var title: String = ""
        var loggedAt: Date = Date()
        var person: Person? = nil
        init() {}
    }
}

// MARK: - Schema V2
// Eingefrorener Snapshot des Schemas zum Zeitpunkt des V2-Deployments.
// Moment bekam sourceRaw. Alle anderen Felder exakt wie in der Live-App vor V3.
// WICHTIG: Niemals nachträglich ändern – dieser Snapshot muss dem gespeicherten
// Schema-Hash von V2-Datenbanken auf Nutzers-Geräten entsprechen.

enum NahbarSchemaV2: VersionedSchema {
    static var versionIdentifier = Schema.Version(2, 0, 0)
    static var models: [any PersistentModel.Type] {
        [Person.self, Moment.self, LogEntry.self]
    }

    @Model final class Person {
        var id: UUID = UUID()
        var name: String = ""
        var tagRaw: String = "Andere"
        var birthday: Date? = nil
        var occupation: String? = nil
        var location: String? = nil
        var interests: String? = nil
        var generalNotes: String? = nil
        var nudgeFrequencyRaw: String = "Monatlich"
        var photoData: Data? = nil
        var nextStep: String? = nil
        var nextStepCompleted: Bool = false
        var nextStepReminderDate: Date? = nil
        var lastSuggestedForCall: Date? = nil
        var createdAt: Date = Date()
        @Relationship(deleteRule: .cascade) var moments: [Moment]? = []
        @Relationship(deleteRule: .cascade) var logEntries: [LogEntry]? = []
        init() {}
    }

    @Model final class Moment {
        var id: UUID = UUID()
        var text: String = ""
        var typeRaw: String = "Gespräch"
        var sourceRaw: String? = nil  // neu in V2
        var createdAt: Date = Date()
        var person: Person? = nil
        init() {}
    }

    @Model final class LogEntry {
        var id: UUID = UUID()
        var typeRaw: String = "Schritt abgeschlossen"
        var title: String = ""
        var loggedAt: Date = Date()
        var person: Person? = nil
        init() {}
    }
}

// MARK: - Schema V3 (eingefrorener Snapshot)
// WICHTIG: Niemals nachträglich ändern – dieser Snapshot muss dem gespeicherten
// Schema-Hash von V3-Datenbanken auf Nutzer-Geräten entsprechen.
//
// V3 fügte hinzu:
//   • Person:      updatedAt, isArchived, photo (PersonPhoto-Relationship)
//   • Moment:      updatedAt, isImportant
//   • LogEntry:    updatedAt
//   • PersonPhoto: neues Modell (Bilddaten ausgelagert)

enum NahbarSchemaV3: VersionedSchema {
    static var versionIdentifier = Schema.Version(3, 0, 0)
    static var models: [any PersistentModel.Type] {
        [Person.self, Moment.self, LogEntry.self, PersonPhoto.self]
    }

    @Model final class PersonPhoto {
        var id: UUID = UUID()
        @Attribute(.externalStorage) var imageData: Data = Data()
        var createdAt: Date = Date()
        init() {}
    }

    @Model final class Person {
        var id: UUID = UUID()
        var name: String = ""
        var tagRaw: String = "Andere"
        var birthday: Date? = nil
        var occupation: String? = nil
        var location: String? = nil
        var interests: String? = nil
        var generalNotes: String? = nil
        var nudgeFrequencyRaw: String = "Monatlich"
        var photoData: Data? = nil
        var nextStep: String? = nil
        var nextStepCompleted: Bool = false
        var nextStepReminderDate: Date? = nil
        var lastSuggestedForCall: Date? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()   // V3
        var isArchived: Bool = false   // V3
        @Relationship(deleteRule: .cascade) var photo: PersonPhoto? = nil  // V3
        @Relationship(deleteRule: .cascade) var moments: [Moment]? = []
        @Relationship(deleteRule: .cascade) var logEntries: [LogEntry]? = []
        init() {}
    }

    @Model final class Moment {
        var id: UUID = UUID()
        var text: String = ""
        var typeRaw: String = "Gespräch"
        var sourceRaw: String? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()    // V3
        var isImportant: Bool = false   // V3
        var person: Person? = nil
        init() {}
    }

    @Model final class LogEntry {
        var id: UUID = UUID()
        var typeRaw: String = "Schritt abgeschlossen"
        var title: String = ""
        var loggedAt: Date = Date()
        var updatedAt: Date = Date()    // V3
        var person: Person? = nil
        init() {}
    }
}

// MARK: - Schema V4 (eingefrorener Snapshot)
// WICHTIG: Niemals nachträglich ändern – dieser Snapshot muss dem gespeicherten
// Schema-Hash von V4-Datenbanken auf Nutzer-Geräten entsprechen.
//
// V4 fügte hinzu:
//   • Visit, Rating, HealthSnapshot: neue Modelle für Besuchs-Bewertungen
//   • Person: visits-Relationship

enum NahbarSchemaV4: VersionedSchema {
    static var versionIdentifier = Schema.Version(4, 0, 0)
    static var models: [any PersistentModel.Type] {
        [PersonPhoto.self, Person.self, Moment.self, LogEntry.self,
         Visit.self, Rating.self, HealthSnapshot.self]
    }

    @Model final class PersonPhoto {
        var id: UUID = UUID()
        @Attribute(.externalStorage) var imageData: Data = Data()
        var createdAt: Date = Date()
        init() {}
    }

    @Model final class Person {
        var id: UUID = UUID()
        var name: String = ""
        var tagRaw: String = "Andere"
        var birthday: Date? = nil
        var occupation: String? = nil
        var location: String? = nil
        var interests: String? = nil
        var generalNotes: String? = nil
        var nudgeFrequencyRaw: String = "Monatlich"
        var nextStep: String? = nil
        var nextStepCompleted: Bool = false
        var nextStepReminderDate: Date? = nil
        var lastSuggestedForCall: Date? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()
        var isArchived: Bool = false
        @Relationship(deleteRule: .cascade) var photo: PersonPhoto? = nil
        var photoData: Data? = nil
        @Relationship(deleteRule: .cascade) var moments: [Moment]? = []
        @Relationship(deleteRule: .cascade) var logEntries: [LogEntry]? = []
        @Relationship(deleteRule: .cascade) var visits: [Visit]? = []
        init() {}
    }

    @Model final class Moment {
        var id: UUID = UUID()
        var text: String = ""
        var typeRaw: String = "Gespräch"
        var sourceRaw: String? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()
        var isImportant: Bool = false
        var person: Person? = nil
        init() {}
    }

    @Model final class LogEntry {
        var id: UUID = UUID()
        var typeRaw: String = "Schritt abgeschlossen"
        var title: String = ""
        var loggedAt: Date = Date()
        var updatedAt: Date = Date()
        var person: Person? = nil
        init() {}
    }

    @Model final class Visit {
        var id: UUID = UUID()
        var visitDate: Date = Date()
        var statusRaw: String = "sofort_abgeschlossen"
        var note: String? = nil
        var aftermathNotificationScheduled: Bool = false
        var aftermathCompletedAt: Date? = nil
        var person: Person? = nil
        @Relationship(deleteRule: .cascade) var ratings: [Rating]? = []
        @Relationship(deleteRule: .cascade) var healthSnapshot: HealthSnapshot? = nil
        init() {}
    }

    @Model final class Rating {
        var id: UUID = UUID()
        var categoryRaw: String = "Selbst"
        var questionIndex: Int = 0
        var value: Int? = nil
        var isAftermath: Bool = false
        var visit: Visit? = nil
        init() {}
    }

    @Model final class HealthSnapshot {
        var id: UUID = UUID()
        var sleepHours: Double? = nil
        var hrvMs: Double? = nil
        var restingHR: Int? = nil
        var steps: Int? = nil
        var visit: Visit? = nil
        init() {}
    }
}

// MARK: - Schema V5 (eingefrorener Snapshot)
// WICHTIG: Niemals nachträglich ändern – dieser Snapshot muss dem gespeicherten
// Schema-Hash von V5-Datenbanken auf Nutzer-Geräten entsprechen.
//
// V5 fügte hinzu:
//   • Moment: ratings, healthSnapshot, statusRaw, aftermathNotificationScheduled,
//             aftermathCompletedAt, reminderDate, isCompleted
//   • Rating: moment-Relationship (neben legacy visit)
//   • HealthSnapshot: moment-Relationship (neben legacy visit)

enum NahbarSchemaV5: VersionedSchema {
    static var versionIdentifier = Schema.Version(5, 0, 0)
    static var models: [any PersistentModel.Type] {
        [PersonPhoto.self, Person.self, Moment.self, LogEntry.self,
         Visit.self, Rating.self, HealthSnapshot.self]
    }

    @Model final class PersonPhoto {
        var id: UUID = UUID()
        @Attribute(.externalStorage) var imageData: Data = Data()
        var createdAt: Date = Date()
        init() {}
    }

    @Model final class Person {
        var id: UUID = UUID()
        var name: String = ""
        var tagRaw: String = "Andere"
        var birthday: Date? = nil
        var occupation: String? = nil
        var location: String? = nil
        var interests: String? = nil
        var generalNotes: String? = nil
        var nudgeFrequencyRaw: String = "Monatlich"
        var nextStep: String? = nil
        var nextStepCompleted: Bool = false
        var nextStepReminderDate: Date? = nil
        var lastSuggestedForCall: Date? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()
        var isArchived: Bool = false
        @Relationship(deleteRule: .cascade) var photo: PersonPhoto? = nil
        var photoData: Data? = nil
        @Relationship(deleteRule: .cascade) var moments: [Moment]? = []
        @Relationship(deleteRule: .cascade) var logEntries: [LogEntry]? = []
        @Relationship(deleteRule: .cascade) var visits: [Visit]? = []
        init() {}
    }

    @Model final class Moment {
        var id: UUID = UUID()
        var text: String = ""
        var typeRaw: String = "Gespräch"
        var sourceRaw: String? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()
        var isImportant: Bool = false
        var person: Person? = nil
        @Relationship(deleteRule: .cascade) var ratings: [Rating]? = []
        @Relationship(deleteRule: .cascade) var healthSnapshot: HealthSnapshot? = nil
        var statusRaw: String? = nil
        var aftermathNotificationScheduled: Bool = false
        var aftermathCompletedAt: Date? = nil
        var reminderDate: Date? = nil
        var isCompleted: Bool = false
        init() {}
    }

    @Model final class LogEntry {
        var id: UUID = UUID()
        var typeRaw: String = "Schritt abgeschlossen"
        var title: String = ""
        var loggedAt: Date = Date()
        var updatedAt: Date = Date()
        var person: Person? = nil
        init() {}
    }

    @Model final class Visit {
        var id: UUID = UUID()
        var visitDate: Date = Date()
        var statusRaw: String = "sofort_abgeschlossen"
        var note: String? = nil
        var aftermathNotificationScheduled: Bool = false
        var aftermathCompletedAt: Date? = nil
        var person: Person? = nil
        @Relationship(deleteRule: .cascade) var ratings: [Rating]? = []
        @Relationship(deleteRule: .cascade) var healthSnapshot: HealthSnapshot? = nil
        init() {}
    }

    @Model final class Rating {
        var id: UUID = UUID()
        var categoryRaw: String = "Selbst"
        var questionIndex: Int = 0
        var value: Int? = nil
        var isAftermath: Bool = false
        var visit: Visit? = nil
        var moment: Moment? = nil
        init() {}
    }

    @Model final class HealthSnapshot {
        var id: UUID = UUID()
        var sleepHours: Double? = nil
        var hrvMs: Double? = nil
        var restingHR: Int? = nil
        var steps: Int? = nil
        var visit: Visit? = nil
        var moment: Moment? = nil
        init() {}
    }
}

// MARK: - Schema V6 (eingefrorener Snapshot)
// WICHTIG: Niemals nachträglich ändern – dieser Snapshot muss dem gespeicherten
// Schema-Hash von V6-Datenbanken auf Nutzer-Geräten entsprechen.
//
// V6 fügte hinzu:
//   • Person: culturalBackground (optionaler Freitext für kulturellen Hintergrund)

enum NahbarSchemaV6: VersionedSchema {
    static var versionIdentifier = Schema.Version(6, 0, 0)
    static var models: [any PersistentModel.Type] {
        [PersonPhoto.self, Person.self, Moment.self, LogEntry.self,
         Visit.self, Rating.self, HealthSnapshot.self]
    }

    @Model final class PersonPhoto {
        var id: UUID = UUID()
        @Attribute(.externalStorage) var imageData: Data = Data()
        var createdAt: Date = Date()
        init() {}
    }

    @Model final class Person {
        var id: UUID = UUID()
        var name: String = ""
        var tagRaw: String = "Andere"
        var birthday: Date? = nil
        var occupation: String? = nil
        var location: String? = nil
        var interests: String? = nil
        var generalNotes: String? = nil
        var culturalBackground: String? = nil  // V6
        var nudgeFrequencyRaw: String = "Monatlich"
        var nextStep: String? = nil
        var nextStepCompleted: Bool = false
        var nextStepReminderDate: Date? = nil
        var lastSuggestedForCall: Date? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()
        var isArchived: Bool = false
        @Relationship(deleteRule: .cascade) var photo: PersonPhoto? = nil
        var photoData: Data? = nil
        @Relationship(deleteRule: .cascade) var moments: [Moment]? = []
        @Relationship(deleteRule: .cascade) var logEntries: [LogEntry]? = []
        @Relationship(deleteRule: .cascade) var visits: [Visit]? = []
        init() {}
    }

    @Model final class Moment {
        var id: UUID = UUID()
        var text: String = ""
        var typeRaw: String = "Gespräch"
        var sourceRaw: String? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()
        var isImportant: Bool = false
        var person: Person? = nil
        @Relationship(deleteRule: .cascade) var ratings: [Rating]? = []
        @Relationship(deleteRule: .cascade) var healthSnapshot: HealthSnapshot? = nil
        var statusRaw: String? = nil
        var aftermathNotificationScheduled: Bool = false
        var aftermathCompletedAt: Date? = nil
        var reminderDate: Date? = nil
        var isCompleted: Bool = false
        init() {}
    }

    @Model final class LogEntry {
        var id: UUID = UUID()
        var typeRaw: String = "Schritt abgeschlossen"
        var title: String = ""
        var loggedAt: Date = Date()
        var updatedAt: Date = Date()
        var person: Person? = nil
        init() {}
    }

    @Model final class Visit {
        var id: UUID = UUID()
        var visitDate: Date = Date()
        var statusRaw: String = "sofort_abgeschlossen"
        var note: String? = nil
        var aftermathNotificationScheduled: Bool = false
        var aftermathCompletedAt: Date? = nil
        var person: Person? = nil
        @Relationship(deleteRule: .cascade) var ratings: [Rating]? = []
        @Relationship(deleteRule: .cascade) var healthSnapshot: HealthSnapshot? = nil
        init() {}
    }

    @Model final class Rating {
        var id: UUID = UUID()
        var categoryRaw: String = "Selbst"
        var questionIndex: Int = 0
        var value: Int? = nil
        var isAftermath: Bool = false
        var visit: Visit? = nil
        var moment: Moment? = nil
        init() {}
    }

    @Model final class HealthSnapshot {
        var id: UUID = UUID()
        var sleepHours: Double? = nil
        var hrvMs: Double? = nil
        var restingHR: Int? = nil
        var steps: Int? = nil
        var visit: Visit? = nil
        var moment: Moment? = nil
        init() {}
    }
}

// MARK: - Schema V7 (eingefrorener Snapshot)
// WICHTIG: Niemals nachträglich ändern – dieser Snapshot muss dem gespeicherten
// Schema-Hash von V7-Datenbanken auf Nutzer-Geräten entsprechen.
//
// V7 fügte hinzu:
//   • Todo: neues Modell (ohne reminderDate)
//   • Person: todos-Relationship

enum NahbarSchemaV7: VersionedSchema {
    static var versionIdentifier = Schema.Version(7, 0, 0)
    static var models: [any PersistentModel.Type] {
        [PersonPhoto.self, Person.self, Moment.self, LogEntry.self,
         Visit.self, Rating.self, HealthSnapshot.self, Todo.self]
    }

    @Model final class PersonPhoto {
        var id: UUID = UUID()
        @Attribute(.externalStorage) var imageData: Data = Data()
        var createdAt: Date = Date()
        init() {}
    }

    @Model final class Person {
        var id: UUID = UUID()
        var name: String = ""
        var tagRaw: String = "Andere"
        var birthday: Date? = nil
        var occupation: String? = nil
        var location: String? = nil
        var interests: String? = nil
        var generalNotes: String? = nil
        var culturalBackground: String? = nil
        var nudgeFrequencyRaw: String = "Monatlich"
        var nextStep: String? = nil
        var nextStepCompleted: Bool = false
        var nextStepReminderDate: Date? = nil
        var lastSuggestedForCall: Date? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()
        var isArchived: Bool = false
        @Relationship(deleteRule: .cascade) var photo: PersonPhoto? = nil
        var photoData: Data? = nil
        @Relationship(deleteRule: .cascade) var moments: [Moment]? = []
        @Relationship(deleteRule: .cascade) var logEntries: [LogEntry]? = []
        @Relationship(deleteRule: .cascade) var visits: [Visit]? = []
        @Relationship(deleteRule: .cascade) var todos: [Todo]? = []
        init() {}
    }

    @Model final class Moment {
        var id: UUID = UUID()
        var text: String = ""
        var typeRaw: String = "Gespräch"
        var sourceRaw: String? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()
        var isImportant: Bool = false
        var person: Person? = nil
        @Relationship(deleteRule: .cascade) var ratings: [Rating]? = []
        @Relationship(deleteRule: .cascade) var healthSnapshot: HealthSnapshot? = nil
        var statusRaw: String? = nil
        var aftermathNotificationScheduled: Bool = false
        var aftermathCompletedAt: Date? = nil
        var reminderDate: Date? = nil
        var isCompleted: Bool = false
        init() {}
    }

    @Model final class LogEntry {
        var id: UUID = UUID()
        var typeRaw: String = "Schritt abgeschlossen"
        var title: String = ""
        var loggedAt: Date = Date()
        var updatedAt: Date = Date()
        var person: Person? = nil
        init() {}
    }

    @Model final class Visit {
        var id: UUID = UUID()
        var visitDate: Date = Date()
        var statusRaw: String = "sofort_abgeschlossen"
        var note: String? = nil
        var aftermathNotificationScheduled: Bool = false
        var aftermathCompletedAt: Date? = nil
        var person: Person? = nil
        @Relationship(deleteRule: .cascade) var ratings: [Rating]? = []
        @Relationship(deleteRule: .cascade) var healthSnapshot: HealthSnapshot? = nil
        init() {}
    }

    @Model final class Rating {
        var id: UUID = UUID()
        var categoryRaw: String = "Selbst"
        var questionIndex: Int = 0
        var value: Int? = nil
        var isAftermath: Bool = false
        var visit: Visit? = nil
        var moment: Moment? = nil
        init() {}
    }

    @Model final class HealthSnapshot {
        var id: UUID = UUID()
        var sleepHours: Double? = nil
        var hrvMs: Double? = nil
        var restingHR: Int? = nil
        var steps: Int? = nil
        var visit: Visit? = nil
        var moment: Moment? = nil
        init() {}
    }

    @Model final class Todo {
        var id: UUID = UUID()
        var title: String = ""
        var dueDate: Date = Date()
        var isCompleted: Bool = false
        var completedAt: Date? = nil
        var person: Person? = nil
        var createdAt: Date = Date()
        init() {}
    }
}

// MARK: - Schema V8 (eingefrorener Snapshot)
// Exakter Zustand aller Modelle zum Zeitpunkt des V8-Deployments.
// WICHTIG: Niemals nachträglich ändern – dieser Snapshot muss dem gespeicherten
// Schema-Hash von V8-Datenbanken auf Nutzer-Geräten entsprechen.
//
// V8 fügte hinzu:
//   • Todo: reminderDate (optionale Push-Benachrichtigung)

enum NahbarSchemaV8: VersionedSchema {
    static var versionIdentifier = Schema.Version(8, 0, 0)
    static var models: [any PersistentModel.Type] {
        [PersonPhoto.self, Person.self, Moment.self, LogEntry.self,
         Visit.self, Rating.self, HealthSnapshot.self, Todo.self]
    }

    @Model final class PersonPhoto {
        var id: UUID = UUID()
        @Attribute(.externalStorage) var imageData: Data = Data()
        var createdAt: Date = Date()
        init() {}
    }

    @Model final class Person {
        var id: UUID = UUID()
        var name: String = ""
        var tagRaw: String = "Andere"
        var birthday: Date? = nil
        var occupation: String? = nil
        var location: String? = nil
        var interests: String? = nil
        var generalNotes: String? = nil
        var culturalBackground: String? = nil
        var nudgeFrequencyRaw: String = "Monatlich"
        var nextStep: String? = nil
        var nextStepCompleted: Bool = false
        var nextStepReminderDate: Date? = nil
        var lastSuggestedForCall: Date? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()
        var isArchived: Bool = false
        @Relationship(deleteRule: .cascade) var photo: PersonPhoto? = nil
        var photoData: Data? = nil
        @Relationship(deleteRule: .cascade) var moments: [Moment]? = []
        @Relationship(deleteRule: .cascade) var logEntries: [LogEntry]? = []
        @Relationship(deleteRule: .cascade) var visits: [Visit]? = []
        @Relationship(deleteRule: .cascade) var todos: [Todo]? = []
        init() {}
    }

    @Model final class Moment {
        var id: UUID = UUID()
        var text: String = ""
        var typeRaw: String = "Gespräch"
        var sourceRaw: String? = nil
        var createdAt: Date = Date()
        var updatedAt: Date = Date()
        var isImportant: Bool = false
        var person: Person? = nil
        @Relationship(deleteRule: .cascade) var ratings: [Rating]? = []
        @Relationship(deleteRule: .cascade) var healthSnapshot: HealthSnapshot? = nil
        var statusRaw: String? = nil
        var aftermathNotificationScheduled: Bool = false
        var aftermathCompletedAt: Date? = nil
        var reminderDate: Date? = nil
        var isCompleted: Bool = false
        init() {}
    }

    @Model final class LogEntry {
        var id: UUID = UUID()
        var typeRaw: String = "Schritt abgeschlossen"
        var title: String = ""
        var loggedAt: Date = Date()
        var updatedAt: Date = Date()
        var person: Person? = nil
        init() {}
    }

    @Model final class Visit {
        var id: UUID = UUID()
        var visitDate: Date = Date()
        var statusRaw: String = "sofort_abgeschlossen"
        var note: String? = nil
        var aftermathNotificationScheduled: Bool = false
        var aftermathCompletedAt: Date? = nil
        var person: Person? = nil
        @Relationship(deleteRule: .cascade) var ratings: [Rating]? = []
        @Relationship(deleteRule: .cascade) var healthSnapshot: HealthSnapshot? = nil
        init() {}
    }

    @Model final class Rating {
        var id: UUID = UUID()
        var categoryRaw: String = "Selbst"
        var questionIndex: Int = 0
        var value: Int? = nil
        var isAftermath: Bool = false
        var visit: Visit? = nil
        var moment: Moment? = nil
        init() {}
    }

    @Model final class HealthSnapshot {
        var id: UUID = UUID()
        var sleepHours: Double? = nil
        var hrvMs: Double? = nil
        var restingHR: Int? = nil
        var steps: Int? = nil
        var visit: Visit? = nil
        var moment: Moment? = nil
        init() {}
    }

    @Model final class Todo {
        var id: UUID = UUID()
        var title: String = ""
        var dueDate: Date = Date()
        var isCompleted: Bool = false
        var completedAt: Date? = nil
        var reminderDate: Date? = nil   // V8-Feld
        var person: Person? = nil
        var createdAt: Date = Date()
        init() {}
    }
}

// MARK: - Schema V9 (aktuelles Schema)
// Referenziert die Live-Typen aus Models.swift.
// Beim Hinzufügen von V10 muss V9 als eingefrorener Snapshot gesichert werden.
//
// V9 fügt hinzu:
//   • Person: phoneNumber, emailAddress, cnIdentifier (Kontaktdaten für direkte Aktionen)

enum NahbarSchemaV9: VersionedSchema {
    static var versionIdentifier = Schema.Version(9, 0, 0)
    static var models: [any PersistentModel.Type] {
        [nahbar.PersonPhoto.self, nahbar.Person.self, nahbar.Moment.self, nahbar.LogEntry.self,
         nahbar.Visit.self, nahbar.Rating.self, nahbar.HealthSnapshot.self, nahbar.Todo.self]
    }
}

// MARK: - Migrationsplan

enum NahbarMigrationPlan: SchemaMigrationPlan {
    static var schemas: [any VersionedSchema.Type] {
        [NahbarSchemaV1.self, NahbarSchemaV2.self, NahbarSchemaV3.self,
         NahbarSchemaV4.self, NahbarSchemaV5.self, NahbarSchemaV6.self,
         NahbarSchemaV7.self, NahbarSchemaV8.self, NahbarSchemaV9.self]
    }

    static var stages: [MigrationStage] {
        [
            // V1 → V2: Moment bekommt sourceRaw = nil (lightweight, kein Datenverlust)
            .lightweight(fromVersion: NahbarSchemaV1.self, toVersion: NahbarSchemaV2.self),

            // V2 → V3: updatedAt/isArchived mit Defaults, PersonPhoto als neues Modell,
            // photo-Relationship auf Person. Alle neuen Felder haben Default-Werte →
            // lightweight-Migration reicht aus.
            .lightweight(fromVersion: NahbarSchemaV2.self, toVersion: NahbarSchemaV3.self),

            // V3 → V4: Visit/Rating/HealthSnapshot neu, Person bekommt visits-Relationship.
            // Alle neuen Felder haben Default-Werte → lightweight-Migration reicht aus.
            .lightweight(fromVersion: NahbarSchemaV3.self, toVersion: NahbarSchemaV4.self),

            // V4 → V5: Moment bekommt rating/intention-Felder, Rating/HealthSnapshot
            // bekommen moment-Relationship. Visit/HealthSnapshot bleiben im Schema
            // (CloudKit-Sicherheit). Alle neuen Felder haben Default-Werte → lightweight.
            .lightweight(fromVersion: NahbarSchemaV4.self, toVersion: NahbarSchemaV5.self),

            // V5 → V6: Person bekommt culturalBackground = nil.
            // Optionales Feld mit nil-Default → lightweight-Migration reicht aus.
            .lightweight(fromVersion: NahbarSchemaV5.self, toVersion: NahbarSchemaV6.self),

            // V6 → V7: Todo als neues Modell (ohne reminderDate), Person.todos-Relationship.
            // Alle neuen Felder haben Default-Werte → lightweight-Migration reicht aus.
            .lightweight(fromVersion: NahbarSchemaV6.self, toVersion: NahbarSchemaV7.self),

            // V7 → V8: Todo bekommt reminderDate = nil.
            // Optionales Feld mit nil-Default → lightweight-Migration reicht aus.
            .lightweight(fromVersion: NahbarSchemaV7.self, toVersion: NahbarSchemaV8.self),

            // V8 → V9: Person bekommt phoneNumber, emailAddress, cnIdentifier = nil.
            // Alle drei Felder sind optional mit nil-Default → lightweight-Migration reicht aus.
            .lightweight(fromVersion: NahbarSchemaV8.self, toVersion: NahbarSchemaV9.self)
        ]
    }
}

// MARK: - Container-Erstellung

extension AppGroup {
    /// Erstellt den ModelContainer mit vollständiger Fehlerbehandlung.
    /// Gibt immer einen funktionsfähigen Container zurück – im schlimmsten Fall
    /// In-Memory. Der ContainerFallback informiert die App über den Zustand.
    ///
    /// Strategie:
    ///   1. CloudKit + Migration (ideal)
    ///   2. Lokal + Migration (iCloud aus oder nicht verfügbar)
    ///   3. Lokal OHNE Migrationsplan (falls Migration selbst fehlschlägt – Notfall)
    ///   4. In-Memory (letzter Ausweg – Daten werden NICHT gespeichert)
    static func makeMainContainerWithMigration() -> (ModelContainer, ContainerFallback) {
        let schema = Schema([
            nahbar.Person.self,
            nahbar.Moment.self,
            nahbar.LogEntry.self,
            nahbar.PersonPhoto.self,
            nahbar.Visit.self,
            nahbar.Rating.self,
            nahbar.HealthSnapshot.self,
            nahbar.Todo.self
        ])
        let icloudEnabled = UserDefaults.standard.bool(forKey: icloudSyncKey)

        // ── Stufe 1: CloudKit + Migration ────────────────────────────────────
        if icloudEnabled {
            let config = ModelConfiguration(schema: schema, cloudKitDatabase: .automatic)
            do {
                let container = try ModelContainer(
                    for: schema,
                    migrationPlan: NahbarMigrationPlan.self,
                    configurations: [config]
                )
                logger.info("Container erstellt: CloudKit + Migration ✓")
                AppEventLog.shared.record("Store: CloudKit + Migration ✓", level: .success, category: "Store")
                return (container, .cloudKit)
            } catch {
                logger.warning("CloudKit-Container fehlgeschlagen: \(error.localizedDescription). Versuche lokal.")
            }
        }

        // ── Stufe 2: Lokal + Migration ────────────────────────────────────────
        let localConfig = ModelConfiguration(schema: schema, cloudKitDatabase: .none)
        do {
            let container = try ModelContainer(
                for: schema,
                migrationPlan: NahbarMigrationPlan.self,
                configurations: [localConfig]
            )
            logger.info("Container erstellt: Lokal + Migration ✓")
            AppEventLog.shared.record("Store: Lokal + Migration ✓", level: .success, category: "Store")
            return (container, .localOnly)
        } catch {
            logger.error("Lokaler Container mit Migration fehlgeschlagen: \(error.localizedDescription). Versuche ohne Migrationsplan.")
        }

        // ── Stufe 3: Lokal OHNE Migrationsplan ───────────────────────────────
        // Notfall: Migration ist kaputt, aber Store ist lesbar.
        // Daten können inkonsistent sein; App läuft zumindest weiter.
        do {
            let container = try ModelContainer(for: schema, configurations: [localConfig])
            logger.error("Container erstellt: Lokal OHNE Migration – Schema möglicherweise inkonsistent!")
            AppEventLog.shared.record("Store: Lokal OHNE Migration – Schema möglicherweise inkonsistent!", level: .error, category: "Store")
            return (container, .localOnly)
        } catch {
            logger.critical("Auch lokaler Container ohne Migration fehlgeschlagen: \(error.localizedDescription). Fallback: In-Memory.")
            AppEventLog.shared.record("Store: In-Memory-Fallback! Daten werden nicht gespeichert.", level: .critical, category: "Store")
        }

        // ── Stufe 4: In-Memory ────────────────────────────────────────────────
        // Daten werden NICHT gespeichert. App zeigt Warnung.
        let inMemoryConfig = ModelConfiguration(isStoredInMemoryOnly: true)
        if let container = try? ModelContainer(for: schema, configurations: [inMemoryConfig]) {
            logger.critical("Container erstellt: In-Memory – Daten werden nicht gespeichert!")
            return (container, .inMemory)
        }

        // Absolut letzter Ausweg – sollte physisch nicht erreichbar sein.
        // try! ist hier vertretbar: Wenn sogar ein leerer In-Memory-Store nicht
        // erstellt werden kann, liegt ein fataler Swift/SwiftData-Laufzeitfehler vor.
        logger.critical("In-Memory-Erstellung fehlgeschlagen. try! – nicht behebbar.")
        let container = try! ModelContainer(for: schema, configurations: [inMemoryConfig])
        return (container, .inMemory)
    }
}
