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 showingEditPerson = false
    @State private var nextStepText = ""
    @State private var isEditingNextStep = false
    @State private var showingReminderSheet = false
    @State private var reminderDate: Date = {
        let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: Date()) ?? Date()
        return Calendar.current.date(bySettingHour: 9, minute: 0, second: 0, of: tomorrow) ?? tomorrow
    }()

    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 28) {
                personHeader
                nextStepSection
                momentsSection
                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: $showingAddMoment) {
            AddMomentView(person: person)
        }
        .sheet(isPresented: $showingEditPerson) {
            AddPersonView(existingPerson: person)
        }
        .sheet(isPresented: $showingReminderSheet) {
            NextStepReminderSheet(person: person, reminderDate: $reminderDate)
        }
        .onAppear {
            nextStepText = person.nextStep ?? ""
        }
        // 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: - Next Step

    private var nextStepSection: some View {
        VStack(alignment: .leading, spacing: 10) {
            SectionHeader(title: "Nächster Schritt", icon: "arrow.right.circle")

            if isEditingNextStep {
                nextStepEditor
            } else if let step = person.nextStep, !person.nextStepCompleted {
                nextStepDisplay(step: step)
            } else {
                addNextStepButton
            }
        }
    }

    private var addNextStepButton: some View {
        Button {
            nextStepText = ""
            person.nextStep = nil
            person.nextStepCompleted = false
            isEditingNextStep = true
        } label: {
            HStack(spacing: 8) {
                Image(systemName: "plus")
                    .font(.system(size: 13))
                Text("Schritt definieren")
                    .font(.system(size: 15))
            }
            .foregroundStyle(theme.contentTertiary)
            .padding(.horizontal, 14)
            .padding(.vertical, 11)
            .frame(maxWidth: .infinity, alignment: .leading)
            .background(theme.surfaceCard)
            .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
            .overlay(
                RoundedRectangle(cornerRadius: theme.radiusCard)
                    .stroke(theme.borderSubtle, lineWidth: 1)
            )
        }
    }

    private var nextStepEditor: some View {
        HStack(alignment: .top, spacing: 10) {
            TextField("Was als Nächstes?", text: $nextStepText, axis: .vertical)
                .font(.system(size: 15, design: theme.displayDesign))
                .foregroundStyle(theme.contentPrimary)
                .tint(theme.accent)
                .lineLimit(1...4)

            Button {
                let trimmed = nextStepText.trimmingCharacters(in: .whitespaces)
                if !trimmed.isEmpty {
                    person.nextStep = trimmed
                    person.nextStepCompleted = false
                    cancelReminder(for: person)
                    person.nextStepReminderDate = nil
                    isEditingNextStep = false
                    // Erinnerungsdatum auf morgen 9 Uhr zurücksetzen
                    let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: Date()) ?? Date()
                    reminderDate = Calendar.current.date(bySettingHour: 9, minute: 0, second: 0, of: tomorrow) ?? tomorrow
                    showingReminderSheet = true
                } else {
                    isEditingNextStep = false
                }
            } label: {
                Text("Ok")
                    .font(.system(size: 14, weight: .semibold))
                    .foregroundStyle(theme.accent)
            }
            .padding(.top, 2)
        }
        .padding(14)
        .background(theme.surfaceCard)
        .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
        .overlay(
            RoundedRectangle(cornerRadius: theme.radiusCard)
                .stroke(theme.accent.opacity(0.25), lineWidth: 1)
        )
    }

    private func nextStepDisplay(step: String) -> some View {
        HStack(alignment: .top, spacing: 12) {
            Button {
                withAnimation(.spring(response: 0.3, dampingFraction: 0.75)) {
                    if let step = person.nextStep {
                        let entry = LogEntry(type: .nextStep, title: step, person: person)
                        modelContext.insert(entry)
                        person.logEntries?.append(entry)
                    }
                    person.nextStepCompleted = true
                    cancelReminder(for: person)
                    person.nextStepReminderDate = nil
                }
            } label: {
                Image(systemName: "circle")
                    .font(.system(size: 22))
                    .foregroundStyle(theme.contentTertiary)
            }

            VStack(alignment: .leading, spacing: 4) {
                Text(step)
                    .font(.system(size: 15, design: theme.displayDesign))
                    .foregroundStyle(theme.contentPrimary)
                    .fixedSize(horizontal: false, vertical: true)

                if let reminder = person.nextStepReminderDate {
                    Label(reminder.formatted(.dateTime.day().month().hour().minute().locale(Locale(identifier: "de_DE"))), systemImage: "bell")
                        .font(.system(size: 12))
                        .foregroundStyle(theme.accent.opacity(0.8))
                }
            }

            Spacer()

            Button {
                nextStepText = step
                isEditingNextStep = true
            } label: {
                Image(systemName: "pencil")
                    .font(.system(size: 13))
                    .foregroundStyle(theme.contentTertiary)
            }
        }
        .padding(.horizontal, 14)
        .padding(.vertical, 12)
        .background(theme.surfaceCard)
        .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
    }

    private func cancelReminder(for person: Person) {
        UNUserNotificationCenter.current()
            .removePendingNotificationRequests(withIdentifiers: ["nextstep-\(person.id)"])
    }

    // MARK: - Moments

    private var momentsSection: some View {
        VStack(alignment: .leading, spacing: 10) {
            HStack {
                SectionHeader(title: "Momente", icon: "clock")
                Spacer()
                NavigationLink {
                    LogbuchView(person: person)
                } label: {
                    Image(systemName: "book.closed")
                        .font(.system(size: 13, weight: .medium))
                        .foregroundStyle(theme.contentTertiary)
                        .padding(.horizontal, 8)
                        .padding(.vertical, 5)
                }
                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())
                }
            }

            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
                        MomentRowView(moment: moment)
                        if index < person.sortedMoments.count - 1 {
                            RowDivider()
                        }
                    }
                }
                .background(theme.surfaceCard)
                .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
            }
        }
    }

    // MARK: - Info

    private var hasInfoContent: Bool {
        person.birthday != nil
        || !(person.location ?? "").isEmpty
        || !(person.interests ?? "").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 notes = person.generalNotes, !notes.isEmpty {
                    InfoRowView(label: "Notizen", value: notes)
                }
            }
            .background(theme.surfaceCard)
            .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
        }
    }
}

// MARK: - Reminder Sheet

struct NextStepReminderSheet: View {
    @Environment(\.nahbarTheme) var theme
    @Environment(\.dismiss) var dismiss
    @Bindable var person: Person
    @Binding var reminderDate: Date

    var body: some View {
        VStack(spacing: 0) {
            // Handle
            RoundedRectangle(cornerRadius: 2)
                .fill(Color.secondary.opacity(0.3))
                .frame(width: 36, height: 4)
                .padding(.top, 12)

            VStack(spacing: 24) {
                // Header
                VStack(spacing: 6) {
                    Image(systemName: "bell")
                        .font(.system(size: 26, weight: .light))
                        .foregroundStyle(theme.accent)

                    Text("Erinnerung setzen?")
                        .font(.system(size: 20, weight: .light, design: theme.displayDesign))
                        .foregroundStyle(theme.contentPrimary)

                    if let step = person.nextStep {
                        Text(step)
                            .font(.system(size: 14))
                            .foregroundStyle(theme.contentSecondary)
                            .multilineTextAlignment(.center)
                            .lineLimit(2)
                    }
                }

                // Date picker
                DatePicker("", selection: $reminderDate, in: Date()..., displayedComponents: [.date, .hourAndMinute])
                    .datePickerStyle(.compact)
                    .labelsHidden()
                    .tint(theme.accent)

                // Buttons
                VStack(spacing: 10) {
                    Button {
                        scheduleReminder()
                        dismiss()
                    } label: {
                        Text("Erinnern")
                            .font(.system(size: 16, weight: .medium))
                            .foregroundStyle(.white)
                            .frame(maxWidth: .infinity)
                            .padding(.vertical, 14)
                            .background(theme.accent)
                            .clipShape(RoundedRectangle(cornerRadius: theme.radiusTag))
                    }

                    Button {
                        dismiss()
                    } label: {
                        Text("Überspringen")
                            .font(.system(size: 15))
                            .foregroundStyle(theme.contentSecondary)
                    }
                }
            }
            .padding(.horizontal, 24)
            .padding(.top, 20)
            .padding(.bottom, 32)
        }
        .background(theme.backgroundPrimary)
        .presentationDetents([.height(380)])
        .presentationDragIndicator(.hidden)
    }

    private func scheduleReminder() {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound]) { granted, _ in
            guard granted else { return }

            let content = UNMutableNotificationContent()
            content.title = person.firstName
            content.body = person.nextStep ?? ""
            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: "nextstep-\(person.id)",
                content: content,
                trigger: trigger
            )
            center.add(request)

            DispatchQueue.main.async {
                person.nextStepReminderDate = reminderDate
            }
        }
    }
}

// MARK: - Moment Row

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

    var body: some View {
        HStack(alignment: .top, spacing: 12) {
            // Type icon with optional source badge overlay
            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)

            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) {
                    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))
                    }
                }
            }

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

    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: - 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)
    }
}
