import SwiftUI
import SwiftData

// MARK: - Schema V1 (Originalschema – Moment ohne sourceRaw)
//
// Diese Typen spiegeln exakt das ursprüngliche Schema wider, bevor
// Moment.sourceRaw hinzugefügt wurde. SwiftData vergleicht das
// gespeicherte Schema-Hash mit dieser Definition und führt bei
// Übereinstimmung die Lightweight-Migration zu V2 durch.

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 (aktuell – Moment mit sourceRaw)

enum NahbarSchemaV2: VersionedSchema {
    static var versionIdentifier = Schema.Version(2, 0, 0)
    static var models: [any PersistentModel.Type] {
        // Verweist auf die aktuellen Top-Level-Modeltypen in Models.swift
        [nahbar.Person.self, nahbar.Moment.self, nahbar.LogEntry.self]
    }
}

// MARK: - Migrationsplan V1 → V2

enum NahbarMigrationPlan: SchemaMigrationPlan {
    static var schemas: [any VersionedSchema.Type] {
        [NahbarSchemaV1.self, NahbarSchemaV2.self]
    }

    /// Lightweight: SwiftData ergänzt sourceRaw mit nil für alle bestehenden Momente.
    static var stages: [MigrationStage] {
        [.lightweight(fromVersion: NahbarSchemaV1.self, toVersion: NahbarSchemaV2.self)]
    }
}

// MARK: - Container-Erstellung (nur Hauptapp, nicht Share Extension)

extension AppGroup {
    /// Erstellt den ModelContainer mit automatischer Schemamigration.
    /// Bei Nutzern, die bereits Daten haben, ergänzt SwiftData das neue
    /// Feld sourceRaw = nil für alle vorhandenen Momente – kein Datenverlust.
    static func makeMainContainerWithMigration() -> ModelContainer {
        let schema = Schema([nahbar.Person.self, nahbar.Moment.self, nahbar.LogEntry.self])
        let icloudEnabled = UserDefaults.standard.bool(forKey: icloudSyncKey)
        let cloudKit: ModelConfiguration.CloudKitDatabase = icloudEnabled ? .automatic : .none

        // Versuch 1: gewünschte Konfiguration mit Migrationsplan
        let config = ModelConfiguration(schema: schema, cloudKitDatabase: cloudKit)
        if let container = try? ModelContainer(
            for: schema,
            migrationPlan: NahbarMigrationPlan.self,
            configurations: [config]
        ) { return container }

        // Versuch 2: lokal ohne CloudKit mit Migrationsplan
        let localConfig = ModelConfiguration(schema: schema, cloudKitDatabase: .none)
        if let container = try? ModelContainer(
            for: schema,
            migrationPlan: NahbarMigrationPlan.self,
            configurations: [localConfig]
        ) { return container }

        // Letzter Ausweg: nur im Speicher (sollte nie eintreten)
        return try! ModelContainer(for: schema, configurations: [ModelConfiguration(isStoredInMemoryOnly: true)])
    }
}
