import SwiftUI
import SwiftData
import CoreData
import UserNotifications

struct PersonDetailView: View {
    @Environment(\.nahbarTheme) var theme
    @Environment(\.modelContext) var modelContext
    @Environment(\.dismiss) var dismiss
    @Bindable var person: Person

    @State private var showingAddMoment = false
    @State private var showingAddTodo = false
    @State private var showingEditPerson = false

    // Meeting-Rating-Flow (V5)
    @State private var momentForRating: Moment? = nil
    @State private var momentForAftermath: Moment? = nil
    @State private var momentForEdit: Moment? = nil
    @State private var momentForSummary: Moment? = nil

    // Moment-Bearbeiten
    @State private var momentForTextEdit: Moment? = nil

    // Todo-Bearbeiten
    @State private var todoForEdit: Todo? = nil
    @State private var fadingOutTodos: [Todo] = []

    // Kalender-Lösch-Bestätigung
    @State private var momentPendingDelete: Moment? = nil
    @State private var showCalendarDeleteDialog = false

    @StateObject private var personalityStore = PersonalityStore.shared
    @State private var activityHint: String = ""

    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 28) {
                personHeader
                momentsSection
                todosSection
                if !person.sortedMoments.isEmpty || !person.sortedLogEntries.isEmpty { logbuchSection }
                if hasInfoContent { infoSection }
            }
            .padding(.horizontal, 20)
            .padding(.top, 16)
            .padding(.bottom, 48)
        }
        .background(theme.backgroundPrimary.ignoresSafeArea())
        .navigationBarTitleDisplayMode(.inline)
        .themedNavBar()
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Button("Bearbeiten") { showingEditPerson = true }
                    .font(.system(size: 15))
                    .foregroundStyle(theme.accent)
            }
        }
        .sheet(isPresented: $showingAddTodo) {
            AddTodoView(person: person)
        }
        .sheet(isPresented: $showingAddMoment) {
            AddMomentView(person: person) { meetingMoment in
                // Rating-Flow nur für vergangene Treffen – zukünftige Termine überspringen
                guard meetingMoment.createdAt <= Date() else { return }
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.45) {
                    momentForRating = meetingMoment
                }
            }
        }
        .sheet(isPresented: $showingEditPerson) {
            AddPersonView(existingPerson: person)
        }
        .sheet(item: $momentForRating) { moment in
            MeetingRatingFlowView(
                moment: moment,
                aftermathDelay: AftermathDelayOption.loadFromDefaults().seconds
            )
        }
        .sheet(item: $momentForAftermath) { moment in
            AftermathRatingFlowView(moment: moment)
        }
        .sheet(item: $momentForEdit) { moment in
            MeetingEditFlowView(moment: moment)
        }
        .sheet(item: $momentForSummary) { moment in
            NavigationStack {
                MeetingSummaryView(moment: moment, onDismiss: { momentForSummary = nil })
                    .navigationTitle("Treffen")
                    .navigationBarTitleDisplayMode(.inline)
                    .toolbar {
                        ToolbarItem(placement: .cancellationAction) {
                            Button("Schließen") { momentForSummary = nil }
                        }
                    }
            }
        }
        .sheet(item: $momentForTextEdit) { moment in
            EditMomentView(moment: moment)
        }
        .sheet(item: $todoForEdit) { todo in
            EditTodoView(todo: todo)
        }
        .confirmationDialog(
            "Moment löschen",
            isPresented: $showCalendarDeleteDialog,
            presenting: momentPendingDelete
        ) { moment in
            Button("Moment + Kalendereintrag löschen", role: .destructive) {
                performDelete(moment, deleteCalendarEvent: true)
                momentPendingDelete = nil
            }
            Button("Nur Moment löschen", role: .destructive) {
                performDelete(moment, deleteCalendarEvent: false)
                momentPendingDelete = nil
            }
            Button("Abbrechen", role: .cancel) {
                momentPendingDelete = nil
            }
        } message: { _ in
            Text("Dieser Moment hat einen verknüpften Kalendereintrag. Soll dieser ebenfalls gelöscht werden?")
        }
        // Schützt vor Crash wenn der ModelContext durch Migration oder
        // CloudKit-Sync intern reset() aufruft und Person-Objekte ungültig werden.
        .onReceive(
            NotificationCenter.default.publisher(
                for: Notification.Name("NSManagedObjectContextObjectsDidChangeNotification")
            )
        ) { notification in
            guard notification.userInfo?[NSInvalidatedAllObjectsKey] != nil else { return }
            dismiss()
        }
    }

    // MARK: - Header

    private var personHeader: some View {
        HStack(spacing: 16) {
            PersonAvatar(person: person, size: 64)

            VStack(alignment: .leading, spacing: 5) {
                Text(person.name)
                    .font(.system(size: 26, weight: .light, design: theme.displayDesign))
                    .foregroundStyle(theme.contentPrimary)

                TagBadge(text: person.tag.rawValue)

                if let occ = person.occupation, !occ.isEmpty {
                    Text(occ)
                        .font(.system(size: 14))
                        .foregroundStyle(theme.contentSecondary)
                }
            }
            Spacer()
        }
    }

    // MARK: - Momente

    private var momentsSection: some View {
        VStack(alignment: .leading, spacing: 10) {
            HStack {
                SectionHeader(title: "Momente", icon: "clock")
                Spacer()
                Button {
                    showingAddMoment = true
                } label: {
                    HStack(spacing: 4) {
                        Image(systemName: "plus")
                            .font(.system(size: 11, weight: .medium))
                        Text("Moment")
                            .font(.system(size: 13, weight: .medium))
                    }
                    .foregroundStyle(theme.accent)
                    .padding(.horizontal, 10)
                    .padding(.vertical, 5)
                    .background(theme.accent.opacity(0.10))
                    .clipShape(Capsule())
                }
            }

            // Persönlichkeitsbasierte Vorhaben-Vorschläge (ersetzt nextStepSection)
            if person.openIntentions.isEmpty,
               let profile = personalityStore.profile, profile.isComplete {
                intentionSuggestionButton(profile: profile)
            }

            if person.sortedMoments.isEmpty {
                Text("Noch nichts festgehalten. Dein nächstes Gespräch kann hier beginnen.")
                    .font(.system(size: 14))
                    .foregroundStyle(theme.contentTertiary)
                    .padding(.vertical, 4)
            } else {
                VStack(spacing: 0) {
                    ForEach(Array(person.sortedMoments.enumerated()), id: \.element.id) { index, moment in
                        VStack(spacing: 0) {
                            MomentRowView(
                                moment: moment,
                                onRateMeeting: { momentForRating = moment },
                                onAftermathMeeting: { momentForAftermath = moment },
                                onViewSummary: { momentForSummary = moment },
                                onEditMeeting: { momentForEdit = moment },
                                onToggleIntention: { toggleIntention(moment) },
                                onEdit: { momentForTextEdit = moment },
                                onToggleImportant: { toggleImportant(moment) }
                            )
                            if index < person.sortedMoments.count - 1 { RowDivider() }
                        }
                    }
                }
                .background(theme.surfaceCard)
                .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
            }
        }
    }

    // MARK: - Vorhaben-Vorschlag

    private func intentionSuggestionButton(profile: PersonalityProfile) -> some View {
        let hint = activityHint.isEmpty ? refreshActivityHint(profile: profile) : activityHint

        return HStack(spacing: 0) {
            Button {
                showingAddMoment = true
            } label: {
                HStack(spacing: 6) {
                    Image(systemName: "brain")
                        .font(.system(size: 11))
                        .foregroundStyle(NahbarInsightStyle.accentPetrol)
                    Text("Idee: \(hint)")
                        .font(.system(size: 13))
                        .foregroundStyle(theme.contentSecondary)
                        .lineLimit(1)
                }
                .padding(.leading, 14)
                .padding(.vertical, 7)
                .frame(maxWidth: .infinity, alignment: .leading)
            }

            // Neue Idee würfeln
            Button {
                activityHint = refreshActivityHint(profile: profile)
            } label: {
                Image(systemName: "arrow.clockwise")
                    .font(.system(size: 12))
                    .foregroundStyle(theme.contentTertiary)
                    .padding(.horizontal, 12)
                    .padding(.vertical, 7)
            }
        }
    }

    @discardableResult
    private func refreshActivityHint(profile: PersonalityProfile) -> String {
        let suggestions = PersonalityEngine.suggestedActivities(
            for: profile, tag: person.tag, count: 2
        )
        let hint = suggestions.joined(separator: " oder ")
        activityHint = hint
        return hint
    }

    // MARK: - Logbuch Vorschau

    private let logbuchPreviewLimit = 5

    // Lokaler Hilfstyp für die gemischte Vorschau
    private struct LogPreviewItem: Identifiable {
        let id: String
        let icon: String
        let title: String
        let typeLabel: String
        let date: Date
    }

    private var mergedLogPreview: [LogPreviewItem] {
        let momentItems = person.sortedMoments.map {
            LogPreviewItem(id: "m-\($0.id)", icon: $0.type.icon, title: $0.text,
                           typeLabel: $0.type.displayName, date: $0.createdAt)
        }
        let entryItems = person.sortedLogEntries.map {
            LogPreviewItem(id: "e-\($0.id)", icon: $0.type.icon, title: $0.title,
                           typeLabel: $0.type.rawValue, date: $0.loggedAt)
        }
        return (momentItems + entryItems).sorted { $0.date > $1.date }
    }

    private var logbuchSection: some View {
        let allItems = mergedLogPreview
        let preview = Array(allItems.prefix(logbuchPreviewLimit))
        let hasMore = allItems.count > logbuchPreviewLimit

        return VStack(alignment: .leading, spacing: 10) {
            HStack {
                SectionHeader(title: "Verlauf & KI-Analyse", icon: "sparkles")
                Spacer()
                NavigationLink(destination: LogbuchView(person: person)) {
                    Text("Alle")
                        .font(.system(size: 13))
                        .foregroundStyle(theme.accent)
                }
            }

            VStack(spacing: 0) {
                ForEach(Array(preview.enumerated()), id: \.element.id) { index, item in
                    logPreviewRow(item)
                    if index < preview.count - 1 || hasMore { RowDivider() }
                }
                if hasMore {
                    NavigationLink(destination: LogbuchView(person: person)) {
                        HStack {
                            Text("Alle \(allItems.count) Einträge anzeigen")
                                .font(.system(size: 14))
                                .foregroundStyle(theme.accent)
                            Spacer()
                            Image(systemName: "chevron.right")
                                .font(.system(size: 12, weight: .medium))
                                .foregroundStyle(theme.contentTertiary)
                        }
                        .padding(.horizontal, 16)
                        .padding(.vertical, 12)
                    }
                }
            }
            .background(theme.surfaceCard)
            .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
        }
    }

    private func logPreviewRow(_ item: LogPreviewItem) -> some View {
        HStack(spacing: 12) {
            Image(systemName: item.icon)
                .font(.system(size: 14, weight: .light))
                .foregroundStyle(theme.accent)
                .frame(width: 20)

            VStack(alignment: .leading, spacing: 3) {
                Text(item.title)
                    .font(.system(size: 15, design: theme.displayDesign))
                    .foregroundStyle(theme.contentPrimary)
                    .lineLimit(2)
                    .fixedSize(horizontal: false, vertical: true)

                HStack(spacing: 6) {
                    Text(LocalizedStringKey(item.typeLabel))
                        .font(.system(size: 12))
                        .foregroundStyle(theme.contentTertiary)
                    Text("·")
                        .font(.system(size: 12))
                        .foregroundStyle(theme.contentTertiary)
                    Text(item.date.formatted(.dateTime.day().month(.abbreviated).year()))
                        .font(.system(size: 12))
                        .foregroundStyle(theme.contentTertiary)
                }
            }

            Spacer()
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 12)
    }

    // MARK: - Info

    private var hasInfoContent: Bool {
        person.birthday != nil
        || !(person.location ?? "").isEmpty
        || !(person.interests ?? "").isEmpty
        || !(person.culturalBackground ?? "").isEmpty
        || !(person.generalNotes ?? "").isEmpty
    }

    private var infoSection: some View {
        VStack(alignment: .leading, spacing: 10) {
            SectionHeader(title: "Über \(person.firstName)", icon: "person")

            VStack(spacing: 0) {
                if let birthday = person.birthday {
                    InfoRowView(
                        label: "Geburtstag",
                        value: birthday.formatted(.dateTime.day().month(.wide).year().locale(Locale(identifier: "de_DE")))
                    )
                    RowDivider()
                }
                if let loc = person.location, !loc.isEmpty {
                    InfoRowView(label: "Wohnort", value: loc)
                    RowDivider()
                }
                if let interests = person.interests, !interests.isEmpty {
                    InfoRowView(label: "Interessen", value: interests)
                    RowDivider()
                }
                if let bg = person.culturalBackground, !bg.isEmpty {
                    InfoRowView(label: "Herkunft", value: bg)
                    RowDivider()
                }
                if let notes = person.generalNotes, !notes.isEmpty {
                    InfoRowView(label: "Notizen", value: notes)
                }
            }
            .background(theme.surfaceCard)
            .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
        }
    }

    // MARK: - Aktionen

    private func deleteMoment(_ moment: Moment) {
        // Prüfen ob ein Kalendereintrag verknüpft ist → ggf. Bestätigung anfordern
        if CalendarEventStore.identifier(for: moment.id) != nil {
            momentPendingDelete = moment
            showCalendarDeleteDialog = true
        } else {
            performDelete(moment, deleteCalendarEvent: false)
        }
    }

    private func performDelete(_ moment: Moment, deleteCalendarEvent: Bool) {
        let momentID = moment.id
        if deleteCalendarEvent, let eventID = CalendarEventStore.identifier(for: momentID) {
            Task {
                _ = await CalendarManager.shared.deleteEvent(identifier: eventID)
                CalendarEventStore.remove(momentID: momentID)
            }
        } else {
            CalendarEventStore.remove(momentID: momentID)
        }
        modelContext.delete(moment)
        person.touch()
    }

    private func toggleImportant(_ moment: Moment) {
        moment.isImportant.toggle()
        moment.updatedAt = Date()
    }

    // MARK: - Todos

    /// Offene Todos + gerade abgehakte (noch ausblendend).
    private var visibleTodos: [Todo] {
        let fadingIDs = Set(fadingOutTodos.map(\.id))
        return person.openTodos.filter { !fadingIDs.contains($0.id) } + fadingOutTodos
    }

    private var todosSection: some View {
        VStack(alignment: .leading, spacing: 10) {
            HStack {
                SectionHeader(title: "Todos", icon: "checkmark.circle")
                Spacer()
                Button {
                    showingAddTodo = true
                } label: {
                    HStack(spacing: 4) {
                        Image(systemName: "plus")
                            .font(.system(size: 11, weight: .medium))
                        Text("Todo")
                            .font(.system(size: 13, weight: .medium))
                    }
                    .foregroundStyle(theme.accent)
                    .padding(.horizontal, 10)
                    .padding(.vertical, 5)
                    .background(theme.accent.opacity(0.10))
                    .clipShape(Capsule())
                }
            }

            if visibleTodos.isEmpty {
                Text("Noch keine Todos.")
                    .font(.system(size: 14))
                    .foregroundStyle(theme.contentTertiary)
                    .padding(.vertical, 4)
            } else {
                VStack(spacing: 0) {
                    ForEach(Array(visibleTodos.enumerated()), id: \.element.id) { index, todo in
                        TodoRowView(
                            todo: todo,
                            isLast: index == visibleTodos.count - 1,
                            onToggle: { toggleTodo(todo) },
                            onDelete: { deleteTodo(todo) },
                            onEdit: { todoForEdit = todo }
                        )
                    }
                }
                .background(theme.surfaceCard)
                .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
            }
        }
    }

    private func toggleTodo(_ todo: Todo) {
        if !todo.isCompleted {
            // Sofort in Fade-out-Liste aufnehmen, damit der Eintrag sichtbar bleibt
            fadingOutTodos.append(todo)

            withAnimation(.spring(response: 0.3, dampingFraction: 0.75)) {
                todo.isCompleted = true
                todo.completedAt = Date()
            }
            UNUserNotificationCenter.current()
                .removePendingNotificationRequests(withIdentifiers: ["todo-\(todo.id)"])

            // Logbuch-Eintrag erstellen
            let entry = LogEntry(type: .todoCompleted, title: todo.title, person: person)
            modelContext.insert(entry)
            person.logEntries?.append(entry)

            // Nach 5 Sek. sanft ausblenden
            DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
                withAnimation(.easeOut(duration: 0.35)) {
                    fadingOutTodos.removeAll { $0.id == todo.id }
                }
            }
        } else {
            withAnimation(.spring(response: 0.3, dampingFraction: 0.75)) {
                todo.isCompleted = false
                todo.completedAt = nil
            }
        }
        person.touch()
        do {
            try modelContext.save()
        } catch {
            AppEventLog.shared.record(
                "Fehler beim Abhaken des Todos: \(error.localizedDescription)",
                level: .error, category: "Todo"
            )
        }
    }

    private func deleteTodo(_ todo: Todo) {
        UNUserNotificationCenter.current()
            .removePendingNotificationRequests(withIdentifiers: ["todo-\(todo.id)"])
        modelContext.delete(todo)
        person.touch()
    }

    private func toggleIntention(_ moment: Moment) {
        guard moment.isIntention else { return }
        withAnimation(.spring(response: 0.3, dampingFraction: 0.75)) {
            if !moment.isCompleted {
                // Vorhaben abhaken: LogEntry erstellen
                moment.isCompleted = true
                moment.updatedAt = Date()
                let entry = LogEntry(type: .nextStep, title: moment.text, person: person)
                modelContext.insert(entry)
                person.logEntries?.append(entry)
                // Erinnerung abbrechen falls vorhanden
                if moment.reminderDate != nil {
                    UNUserNotificationCenter.current()
                        .removePendingNotificationRequests(withIdentifiers: ["intention-\(moment.id)"])
                }
            } else {
                moment.isCompleted = false
                moment.updatedAt = Date()
            }
        }
        do {
            try modelContext.save()
        } catch {
            AppEventLog.shared.record(
                "Fehler beim Abhaken des Vorhabens: \(error.localizedDescription)",
                level: .error, category: "Intention"
            )
        }
    }
}

// MARK: - Deletable Moment Row
// Links wischen  → Löschen (rot)
// MARK: - Todo Row

private struct TodoRowView: View {
    @Environment(\.nahbarTheme) var theme
    let todo: Todo
    let isLast: Bool
    let onToggle: () -> Void
    let onDelete: () -> Void
    let onEdit: () -> Void

    var body: some View {
        VStack(spacing: 0) {
            HStack(alignment: .top, spacing: 12) {
                Button { onToggle() } label: {
                    Image(systemName: todo.isCompleted ? "checkmark.circle.fill" : "circle")
                        .font(.system(size: 20))
                        .foregroundStyle(todo.isCompleted ? Color.green : theme.contentTertiary)
                        .padding(.top, 1)
                }
                .buttonStyle(.plain)

                Button { onEdit() } label: {
                    VStack(alignment: .leading, spacing: 4) {
                        Text(todo.title)
                            .font(.system(size: 15, design: theme.displayDesign))
                            .foregroundStyle(todo.isCompleted ? theme.contentTertiary : theme.contentPrimary)
                            .strikethrough(todo.isCompleted, color: theme.contentTertiary)
                            .fixedSize(horizontal: false, vertical: true)

                        HStack(spacing: 6) {
                            Label(
                                todo.dueDate.formatted(.dateTime.day().month(.abbreviated).year().locale(Locale.current)),
                                systemImage: "calendar"
                            )
                            .font(.system(size: 12))
                            .foregroundStyle(isOverdue ? .red : theme.contentTertiary)

                            // Erinnerungs-Indikator
                            if let reminder = todo.reminderDate, !todo.isCompleted {
                                Label(
                                    reminder.formatted(.dateTime.day().month(.abbreviated).hour().minute().locale(Locale.current)),
                                    systemImage: "bell"
                                )
                                .font(.system(size: 12))
                                .foregroundStyle(theme.accent.opacity(0.8))
                            }
                        }
                    }
                    .frame(maxWidth: .infinity, alignment: .leading)
                }
                .buttonStyle(.plain)
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 12)
            .opacity(todo.isCompleted ? 0.55 : 1.0)

            if !isLast { RowDivider() }
        }
        .swipeActions(edge: .leading) {
            Button { onEdit() } label: {
                Label("Bearbeiten", systemImage: "pencil")
            }
            .tint(theme.accent)
        }
        .swipeActions(edge: .trailing, allowsFullSwipe: true) {
            Button(role: .destructive) { onDelete() } label: {
                Label("Löschen", systemImage: "trash")
            }
        }
    }

    private var isOverdue: Bool {
        !todo.isCompleted && todo.dueDate < Calendar.current.startOfDay(for: Date())
    }
}

// MARK: - Moment Row

struct MomentRowView: View {
    @Environment(\.nahbarTheme) var theme
    let moment: Moment

    // Callbacks für typ-spezifische Aktionen (nur in PersonDetailView relevant)
    var onRateMeeting: (() -> Void)? = nil
    var onAftermathMeeting: (() -> Void)? = nil
    var onViewSummary: (() -> Void)? = nil
    var onEditMeeting: (() -> Void)? = nil
    var onToggleIntention: (() -> Void)? = nil
    var onEdit: (() -> Void)? = nil
    var onToggleImportant: (() -> Void)? = nil

    /// Wird lokal gecacht, damit die Ansicht auf CalendarEventStore-Änderungen reagieren kann.
    @State private var hasCalendarEvent = false

    var body: some View {
        Group {
            switch moment.type {
            case .meeting:   meetingRow
            case .intention: intentionRow
            default:         standardRow
            }
        }
        .onAppear {
            hasCalendarEvent = CalendarEventStore.identifier(for: moment.id) != nil
        }
        .onReceive(NotificationCenter.default.publisher(for: CalendarEventStore.didChangeNotification)) { n in
            guard (n.object as? UUID) == moment.id else { return }
            hasCalendarEvent = CalendarEventStore.identifier(for: moment.id) != nil
        }
    }

    // MARK: Standard-Zeile (Gespräch, Gedanke)

    private var standardRow: some View {
        HStack(alignment: .top, spacing: 12) {
            typeIcon
            Button { onEdit?() } label: {
                momentContent
                    .frame(maxWidth: .infinity, alignment: .leading)
            }
            .buttonStyle(.plain)
            starButton
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 12)
    }

    // MARK: Treffen-Zeile

    private var meetingRow: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack(alignment: .top, spacing: 12) {
                typeIcon
                Button { onEdit?() } label: {
                    momentContent
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
                .buttonStyle(.plain)
                starButton
                // Score-Badge oder Bearbeiten-Button
                if let avg = moment.immediateAverage {
                    Button { onViewSummary?() } label: {
                        scoreBadge(avg)
                    }
                    .buttonStyle(.plain)
                }
            }

            // Aktions-Zeile
            HStack(spacing: 8) {
                Spacer().frame(width: 30)  // Einrückung für Typ-Icon

                if moment.meetingStatus == nil || (moment.ratings ?? []).isEmpty {
                    // Noch nicht bewertet
                    Button { onRateMeeting?() } label: {
                        Label("Bewerten", systemImage: "star")
                            .font(.system(size: 12, weight: .medium))
                            .foregroundStyle(theme.accent)
                            .padding(.horizontal, 10)
                            .padding(.vertical, 5)
                            .background(theme.accent.opacity(0.1))
                            .clipShape(Capsule())
                    }
                } else if moment.meetingStatus == .awaitingAftermath {
                    // Nachwirkung ausstehend
                    Button { onAftermathMeeting?() } label: {
                        Label("Nachwirkung", systemImage: "moon.stars")
                            .font(.system(size: 12, weight: .medium))
                            .foregroundStyle(.purple)
                            .padding(.horizontal, 10)
                            .padding(.vertical, 5)
                            .background(Color.purple.opacity(0.1))
                            .clipShape(Capsule())
                    }
                    // Bewertung bearbeiten
                    Button { onEditMeeting?() } label: {
                        Image(systemName: "pencil")
                            .font(.system(size: 12))
                            .foregroundStyle(theme.contentTertiary)
                    }
                } else if moment.isMeetingComplete {
                    // Abgeschlossen – nur bearbeiten
                    Button { onEditMeeting?() } label: {
                        Label("Bearbeiten", systemImage: "pencil")
                            .font(.system(size: 12, weight: .medium))
                            .foregroundStyle(theme.contentTertiary)
                            .padding(.horizontal, 10)
                            .padding(.vertical, 5)
                            .background(theme.contentTertiary.opacity(0.08))
                            .clipShape(Capsule())
                    }
                }

                Spacer()
            }
            .padding(.bottom, 4)
        }
        .padding(.horizontal, 16)
        .padding(.top, 12)
        .padding(.bottom, 8)
    }

    // MARK: Vorhaben-Zeile

    private var intentionRow: some View {
        HStack(alignment: .top, spacing: 12) {
            // Checkbox
            Button { onToggleIntention?() } label: {
                Image(systemName: moment.isCompleted ? "checkmark.circle.fill" : "circle")
                    .font(.system(size: 20))
                    .foregroundStyle(moment.isCompleted ? Color.green : theme.contentTertiary)
                    .padding(.top, 1)
            }
            .buttonStyle(.plain)

            Button { onEdit?() } label: {
                VStack(alignment: .leading, spacing: 4) {
                    Text(moment.text)
                        .font(.system(size: 15, design: theme.displayDesign))
                        .foregroundStyle(moment.isCompleted ? theme.contentTertiary : theme.contentPrimary)
                        .strikethrough(moment.isCompleted, color: theme.contentTertiary)
                        .fixedSize(horizontal: false, vertical: true)

                    HStack(spacing: 6) {
                        if let reminder = moment.reminderDate, !moment.isCompleted {
                            Label(
                                reminder.formatted(.dateTime.day().month(.abbreviated).hour().minute().locale(Locale.current)),
                                systemImage: "bell"
                            )
                            .font(.system(size: 12))
                            .foregroundStyle(theme.accent.opacity(0.8))
                        } else {
                            Text(moment.createdAt, format: .dateTime.day().month(.abbreviated).year().locale(Locale(identifier: "de_DE")))
                                .font(.system(size: 12))
                                .foregroundStyle(theme.contentTertiary)
                        }
                    }
                }
                .frame(maxWidth: .infinity, alignment: .leading)
            }
            .buttonStyle(.plain)

            starButton
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 12)
        .opacity(moment.isCompleted ? 0.55 : 1.0)
    }

    // MARK: - Gemeinsame Elemente

    private var typeIcon: some View {
        ZStack(alignment: .bottomTrailing) {
            Image(systemName: moment.type.icon)
                .font(.system(size: 13, weight: .light))
                .foregroundStyle(theme.contentTertiary)
                .frame(width: 18)
                .padding(.top, 2)

            if let source = moment.source {
                Image(systemName: source.icon)
                    .font(.system(size: 8, weight: .semibold))
                    .foregroundStyle(.white)
                    .padding(2)
                    .background(sourceColor(source))
                    .clipShape(Circle())
                    .offset(x: 5, y: 4)
            }
        }
        .frame(width: 18)
        .padding(.top, 2)
    }

    private var starButton: some View {
        Button { onToggleImportant?() } label: {
            Image(systemName: moment.isImportant ? "star.fill" : "star")
                .font(.system(size: 15))
                .foregroundStyle(moment.isImportant ? Color.orange : theme.contentTertiary.opacity(0.4))
        }
        .buttonStyle(.plain)
        .padding(.top, 1)
    }

    private var momentContent: some View {
        VStack(alignment: .leading, spacing: 4) {
            Text(moment.text)
                .font(.system(size: 15, design: theme.displayDesign))
                .foregroundStyle(theme.contentPrimary)
                .fixedSize(horizontal: false, vertical: true)

            HStack(spacing: 6) {
                if hasCalendarEvent {
                    Image(systemName: "calendar")
                        .font(.system(size: 10))
                        .foregroundStyle(theme.contentTertiary)
                }
                Text(moment.createdAt, format: .dateTime.day().month(.abbreviated).year().locale(Locale(identifier: "de_DE")))
                    .font(.system(size: 12))
                    .foregroundStyle(theme.contentTertiary)

                if let source = moment.source {
                    Text("·")
                        .font(.system(size: 12))
                        .foregroundStyle(theme.contentTertiary)
                    Text(source.rawValue)
                        .font(.system(size: 12))
                        .foregroundStyle(sourceColor(source).opacity(0.8))
                }
            }
        }
    }

    private func scoreBadge(_ value: Double) -> some View {
        ZStack {
            Circle()
                .fill(scoreColor(value).opacity(0.15))
                .frame(width: 34, height: 34)
            Text(String(format: "%.1f", value))
                .font(.system(size: 10, weight: .bold))
                .foregroundStyle(scoreColor(value))
        }
    }

    private func scoreColor(_ value: Double) -> Color {
        switch value {
        case ..<(-0.5): return .red
        case (-0.5)..<(0.5): return Color(.systemGray3)
        case (0.5)...: return .green
        default: return .gray
        }
    }

    private func sourceColor(_ source: MomentSource) -> Color {
        switch source {
        case .whatsapp: return Color(red: 0.15, green: 0.80, blue: 0.33)
        case .imessage: return Color(red: 0.0,  green: 0.48, blue: 1.0)
        case .telegram: return Color(red: 0.17, green: 0.67, blue: 0.94)
        case .signal:   return Color(red: 0.23, green: 0.47, blue: 0.95)
        case .other:    return Color.gray
        }
    }
}

// MARK: - Edit Moment View

struct EditMomentView: View {
    @Environment(\.nahbarTheme) var theme
    @Environment(\.modelContext) var modelContext
    @Environment(\.dismiss) var dismiss

    let moment: Moment

    @State private var text: String
    @State private var createdAt: Date
    @State private var showDeleteConfirm = false
    @State private var showCalendarDeleteConfirm = false
    @FocusState private var isFocused: Bool

    init(moment: Moment) {
        self.moment = moment
        self._text      = State(initialValue: moment.text)
        self._createdAt = State(initialValue: moment.createdAt)
    }

    private var isValid: Bool { !text.trimmingCharacters(in: .whitespaces).isEmpty }

    var body: some View {
        NavigationStack {
            VStack(alignment: .leading, spacing: 16) {

                // Zeitpunkt
                VStack(spacing: 0) {
                    DatePicker(
                        "Zeitpunkt",
                        selection: $createdAt,
                        displayedComponents: [.date, .hourAndMinute]
                    )
                    .font(.system(size: 15))
                    .foregroundStyle(theme.contentPrimary)
                    .tint(theme.accent)
                    .environment(\.locale, Locale.current)
                    .padding(.horizontal, 16)
                    .padding(.vertical, 10)
                }
                .background(theme.surfaceCard)
                .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
                .padding(.horizontal, 20)

                // Text
                ZStack(alignment: .topLeading) {
                    if text.isEmpty {
                        Text("Moment…")
                            .font(.system(size: 16))
                            .foregroundStyle(theme.contentTertiary)
                            .padding(.horizontal, 16)
                            .padding(.vertical, 14)
                            .allowsHitTesting(false)
                    }
                    TextEditor(text: $text)
                        .font(.system(size: 16, design: theme.displayDesign))
                        .foregroundStyle(theme.contentPrimary)
                        .tint(theme.accent)
                        .scrollContentBackground(.hidden)
                        .padding(.horizontal, 12)
                        .padding(.vertical, 10)
                        .focused($isFocused)
                }
                .frame(minHeight: 180)
                .background(theme.surfaceCard)
                .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
                .padding(.horizontal, 20)

                // Löschen-Button
                Button {
                    if CalendarEventStore.identifier(for: moment.id) != nil {
                        showCalendarDeleteConfirm = true
                    } else {
                        showDeleteConfirm = true
                    }
                } label: {
                    Label("Moment löschen", systemImage: "trash")
                        .font(.system(size: 15))
                        .foregroundStyle(.red)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 14)
                        .background(Color.red.opacity(0.08))
                        .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
                }
                .padding(.horizontal, 20)

                Spacer()
            }
            .padding(.top, 16)
            .background(theme.backgroundPrimary.ignoresSafeArea())
            .navigationTitle("Moment bearbeiten")
            .navigationBarTitleDisplayMode(.inline)
            .themedNavBar()
            .toolbar {
                ToolbarItem(placement: .topBarLeading) {
                    Button("Abbrechen") { dismiss() }
                        .foregroundStyle(theme.contentSecondary)
                }
                ToolbarItem(placement: .topBarTrailing) {
                    Button("Fertig") { save() }
                        .font(.system(size: 15, weight: .semibold))
                        .foregroundStyle(isValid ? theme.accent : theme.contentTertiary)
                        .disabled(!isValid)
                }
            }
        }
        .onAppear { isFocused = true }
        .confirmationDialog("Moment löschen?", isPresented: $showDeleteConfirm, titleVisibility: .visible) {
            Button("Löschen", role: .destructive) { delete(deleteCalendarEvent: false) }
            Button("Abbrechen", role: .cancel) {}
        } message: {
            Text("Dieser Moment wird unwiderruflich gelöscht.")
        }
        .confirmationDialog("Moment mit Kalendereintrag löschen?", isPresented: $showCalendarDeleteConfirm, titleVisibility: .visible) {
            Button("Moment + Kalendereintrag löschen", role: .destructive) { delete(deleteCalendarEvent: true) }
            Button("Nur Moment löschen", role: .destructive) { delete(deleteCalendarEvent: false) }
            Button("Abbrechen", role: .cancel) {}
        }
    }

    private func delete(deleteCalendarEvent: Bool) {
        let momentID = moment.id
        if deleteCalendarEvent, let eventID = CalendarEventStore.identifier(for: momentID) {
            Task {
                _ = await CalendarManager.shared.deleteEvent(identifier: eventID)
                CalendarEventStore.remove(momentID: momentID)
            }
        } else {
            CalendarEventStore.remove(momentID: momentID)
        }
        moment.person?.touch()
        modelContext.delete(moment)
        do { try modelContext.save() } catch {
            AppEventLog.shared.record(
                "Fehler beim Löschen des Moments: \(error.localizedDescription)",
                level: .error, category: "Moment"
            )
        }
        dismiss()
    }

    private func save() {
        let trimmed = text.trimmingCharacters(in: .whitespaces)
        guard !trimmed.isEmpty else { return }
        moment.text      = trimmed
        moment.createdAt = createdAt
        moment.updatedAt = Date()
        moment.person?.touch()
        do {
            try modelContext.save()
        } catch {
            AppEventLog.shared.record(
                "Fehler beim Bearbeiten des Moments: \(error.localizedDescription)",
                level: .error, category: "Moment"
            )
        }
        // Verknüpften Kalendereintrag aktualisieren, falls vorhanden
        if let eventID = CalendarEventStore.identifier(for: moment.id) {
            let firstName = moment.person?.firstName ?? ""
            let title = String.localizedStringWithFormat(String(localized: "Treffen mit %@"), firstName)
            let savedDate = createdAt
            Task {
                await CalendarManager.shared.updateEvent(
                    identifier: eventID,
                    title: title,
                    notes: trimmed,
                    newStartDate: savedDate
                )
            }
        }
        dismiss()
    }
}

// MARK: - Edit Todo View

struct EditTodoView: View {
    @Environment(\.nahbarTheme) var theme
    @Environment(\.modelContext) var modelContext
    @Environment(\.dismiss) var dismiss

    let todo: Todo

    @State private var title: String
    @State private var dueDate: Date
    @State private var addReminder: Bool
    @State private var reminderDate: Date
    @FocusState private var isFocused: Bool

    init(todo: Todo) {
        self.todo = todo
        self._title      = State(initialValue: todo.title)
        self._dueDate    = State(initialValue: todo.dueDate)
        self._addReminder = State(initialValue: todo.reminderDate != nil)
        self._reminderDate = State(initialValue: todo.reminderDate ?? AddTodoView.defaultReminderDate(for: todo.dueDate))
    }

    private var isValid: Bool { !title.trimmingCharacters(in: .whitespaces).isEmpty }

    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(alignment: .leading, spacing: 16) {

                    // Titel-Eingabe
                    ZStack(alignment: .topLeading) {
                        if title.isEmpty {
                            Text("Was möchtest du erledigen?")
                                .font(.system(size: 16))
                                .foregroundStyle(theme.contentTertiary)
                                .padding(.horizontal, 16)
                                .padding(.vertical, 14)
                                .allowsHitTesting(false)
                        }
                        TextEditor(text: $title)
                            .font(.system(size: 16, design: theme.displayDesign))
                            .foregroundStyle(theme.contentPrimary)
                            .tint(theme.accent)
                            .scrollContentBackground(.hidden)
                            .padding(.horizontal, 12)
                            .padding(.vertical, 10)
                            .focused($isFocused)
                    }
                    .frame(minHeight: 100)
                    .background(theme.surfaceCard)
                    .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
                    .padding(.horizontal, 20)

                    // Fälligkeitsdatum + Erinnerung
                    VStack(spacing: 0) {
                        DatePicker(
                            "Fällig am",
                            selection: $dueDate,
                            displayedComponents: .date
                        )
                        .font(.system(size: 15))
                        .foregroundStyle(theme.contentPrimary)
                        .tint(theme.accent)
                        .environment(\.locale, Locale.current)
                        .padding(.horizontal, 16)
                        .padding(.vertical, 10)

                        RowDivider()

                        HStack {
                            Image(systemName: "bell")
                                .font(.system(size: 14))
                                .foregroundStyle(addReminder ? theme.accent : theme.contentTertiary)
                            Text("Erinnerung setzen")
                                .font(.system(size: 15))
                                .foregroundStyle(theme.contentPrimary)
                            Spacer()
                            Toggle("", isOn: $addReminder)
                                .tint(theme.accent)
                        }
                        .padding(.horizontal, 16)
                        .padding(.vertical, 12)

                        if addReminder {
                            RowDivider()
                            DatePicker(
                                "Wann?",
                                selection: $reminderDate,
                                in: Date()...,
                                displayedComponents: [.date, .hourAndMinute]
                            )
                            .font(.system(size: 15))
                            .foregroundStyle(theme.contentPrimary)
                            .tint(theme.accent)
                            .environment(\.locale, Locale.current)
                            .padding(.horizontal, 16)
                            .padding(.vertical, 10)
                        }
                    }
                    .background(theme.surfaceCard)
                    .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
                    .padding(.horizontal, 20)
                    .animation(.easeInOut(duration: 0.2), value: addReminder)

                    Spacer(minLength: 40)
                }
                .padding(.top, 16)
            }
            .background(theme.backgroundPrimary.ignoresSafeArea())
            .navigationTitle("Todo bearbeiten")
            .navigationBarTitleDisplayMode(.inline)
            .themedNavBar()
            .toolbar {
                ToolbarItem(placement: .topBarLeading) {
                    Button("Abbrechen") { dismiss() }
                        .foregroundStyle(theme.contentSecondary)
                }
                ToolbarItem(placement: .topBarTrailing) {
                    Button("Fertig") { save() }
                        .font(.system(size: 15, weight: .semibold))
                        .foregroundStyle(isValid ? theme.accent : theme.contentTertiary)
                        .disabled(!isValid)
                }
            }
        }
        .onChange(of: dueDate) { _, newDue in
            reminderDate = AddTodoView.defaultReminderDate(for: newDue)
        }
        .onAppear { isFocused = true }
    }

    private func save() {
        let trimmed = title.trimmingCharacters(in: .whitespaces)
        guard !trimmed.isEmpty else { return }

        // Alte Erinnerung immer zuerst entfernen
        UNUserNotificationCenter.current()
            .removePendingNotificationRequests(withIdentifiers: ["todo-\(todo.id)"])

        todo.title   = trimmed
        todo.dueDate = dueDate
        todo.reminderDate = addReminder ? reminderDate : nil
        todo.person?.touch()

        if addReminder {
            scheduleReminder()
        }

        do {
            try modelContext.save()
        } catch {
            AppEventLog.shared.record(
                "Fehler beim Bearbeiten des Todos: \(error.localizedDescription)",
                level: .error, category: "Todo"
            )
        }
        dismiss()
    }

    private func scheduleReminder() {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound]) { granted, _ in
            guard granted else { return }
            let content = UNMutableNotificationContent()
            content.title = todo.person?.firstName ?? ""
            content.body  = todo.title
            content.sound = .default
            let components = Calendar.current.dateComponents(
                [.year, .month, .day, .hour, .minute], from: reminderDate
            )
            let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
            let request = UNNotificationRequest(
                identifier: "todo-\(todo.id)",
                content: content,
                trigger: trigger
            )
            center.add(request)
        }
    }
}

// MARK: - Info Row

struct InfoRowView: View {
    @Environment(\.nahbarTheme) var theme
    let label: String
    let value: String

    var body: some View {
        HStack(alignment: .top, spacing: 12) {
            Text(label)
                .font(.system(size: 13))
                .foregroundStyle(theme.contentTertiary)
                .frame(width: 88, alignment: .leading)

            Text(value)
                .font(.system(size: 15))
                .foregroundStyle(theme.contentPrimary)
                .fixedSize(horizontal: false, vertical: true)

            Spacer()
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 12)
    }
}
