import SwiftUI
import SafariServices
import SwiftData

struct SettingsView: View {
    @AppStorage("onboardingComplete") private var onboardingComplete = false
    @AppStorage("syncWiFiOnly") private var syncWiFiOnly = true
    @AppStorage("showComments") private var showComments = true
    @AppStorage("appTheme") private var appTheme = "system"
    @AppStorage("accentTheme") private var accentThemeRaw = AccentTheme.ocean.rawValue
    @AppStorage("loggingEnabled") private var loggingEnabled = false
    @Environment(ServerProfileStore.self) private var profileStore

    private var selectedTheme: AccentTheme {
        AccentTheme(rawValue: accentThemeRaw) ?? .ocean
    }
    @State private var showSignOutAlert = false
    @State private var isSyncing = false
    @State private var lastSynced = UserDefaults.standard.object(forKey: "lastSynced") as? Date
    @State private var showSafari: URL? = nil
    @State private var selectedLanguage: LanguageManager.Language = LanguageManager.shared.current
    @State private var showLogViewer = false
    @State private var shareItems: [Any]? = nil
    @Environment(\.modelContext) private var modelContext
    @State private var showAddServer = false
    @State private var profileToSwitch: ServerProfile? = nil
    @State private var profileToDelete: ServerProfile? = nil
    @State private var profileToEdit: ServerProfile? = nil

    private let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0"
    private let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "1"

    var body: some View {
        NavigationStack {
            Form {
                // Language section
                Section {
                    ForEach(LanguageManager.Language.allCases) { lang in
                        Button {
                            selectedLanguage = lang
                            LanguageManager.shared.set(lang)
                        } label: {
                            HStack {
                                Text(lang.flag)
                                Text(lang.displayName)
                                    .foregroundStyle(.primary)
                                Spacer()
                                if selectedLanguage == lang {
                                    Image(systemName: "checkmark")
                                        .foregroundStyle(.blue)
                                }
                            }
                        }
                    }
                } header: {
                    Text(L("settings.language.header"))
                }

                // Appearance section
                Section(L("settings.appearance")) {
                    Picker(L("settings.appearance.theme"), selection: $appTheme) {
                        Text(L("settings.appearance.theme.system")).tag("system")
                        Text(L("settings.appearance.theme.light")).tag("light")
                        Text(L("settings.appearance.theme.dark")).tag("dark")
                    }
                    .pickerStyle(.segmented)

                    // Accent colour swatches
                    VStack(alignment: .leading, spacing: 10) {
                        Text(L("settings.appearance.accent"))
                            .font(.subheadline)
                            .foregroundStyle(.secondary)

                        LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 10), count: 8), spacing: 10) {
                            ForEach(AccentTheme.allCases) { theme in
                                Button {
                                    accentThemeRaw = theme.rawValue
                                } label: {
                                    ZStack {
                                        Circle()
                                            .fill(theme.shelfColor)
                                            .frame(width: 32, height: 32)
                                        if selectedTheme == theme {
                                            Circle()
                                                .strokeBorder(.white, lineWidth: 2)
                                                .frame(width: 32, height: 32)
                                            Image(systemName: "checkmark")
                                                .font(.system(size: 11, weight: .bold))
                                                .foregroundStyle(.white)
                                        }
                                    }
                                }
                                .buttonStyle(.plain)
                                .accessibilityLabel(theme.displayName)
                                .accessibilityAddTraits(selectedTheme == theme ? .isSelected : [])
                            }
                        }
                    }
                    .padding(.vertical, 4)
                }

                // Servers section
                Section(L("settings.servers")) {
                    ForEach(profileStore.profiles) { profile in
                        Button {
                            if profile.id != profileStore.activeProfileId {
                                profileToSwitch = profile
                            }
                        } label: {
                            HStack(spacing: 12) {
                                Image(systemName: profile.id == profileStore.activeProfileId
                                      ? "checkmark.circle.fill" : "circle")
                                    .foregroundStyle(profile.id == profileStore.activeProfileId
                                                     ? Color.accentColor : .secondary)
                                VStack(alignment: .leading, spacing: 2) {
                                    Text(profile.name)
                                        .font(.body)
                                        .foregroundStyle(.primary)
                                    Text(profile.serverURL)
                                        .font(.footnote)
                                        .foregroundStyle(.secondary)
                                        .lineLimit(1)
                                }
                                Spacer()
                                if profile.id == profileStore.activeProfileId {
                                    Text(L("settings.servers.active"))
                                        .font(.caption)
                                        .foregroundStyle(.secondary)
                                }
                            }
                        }
                        .swipeActions(edge: .trailing, allowsFullSwipe: false) {
                            Button(role: .destructive) {
                                profileToDelete = profile
                            } label: {
                                Label(L("settings.servers.delete.confirm"), systemImage: "trash")
                            }
                            .tint(.red)
                            Button {
                                profileToEdit = profile
                            } label: {
                                Label(L("settings.servers.edit"), systemImage: "pencil")
                            }
                            .tint(.blue)
                        }
                    }

                    Button {
                        showAddServer = true
                    } label: {
                        Label(L("settings.servers.add"), systemImage: "plus.circle")
                    }
                }

                // Reader section
                Section(L("settings.reader")) {
                    Toggle(L("settings.reader.showcomments"), isOn: $showComments)
                }

                // Logging section
                Section(L("settings.log")) {
                    Toggle(L("settings.log.enabled"), isOn: $loggingEnabled)
                        .onChange(of: loggingEnabled) { _, newValue in
                            LogManager.shared.isEnabled = newValue
                        }

                    if loggingEnabled {
                        Button {
                            showLogViewer = true
                        } label: {
                            Label(L("settings.log.viewer.title"), systemImage: "list.bullet.rectangle")
                        }

                        Button {
                            let text = LogManager.shared.exportText()
                            shareItems = [text]
                        } label: {
                            Label(L("settings.log.share"), systemImage: "square.and.arrow.up")
                        }

                        Button(role: .destructive) {
                            LogManager.shared.clear()
                        } label: {
                            Label(L("settings.log.clear"), systemImage: "trash")
                        }
                    }
                }

                // Sync section
                Section(L("settings.sync")) {
                    Toggle(L("settings.sync.wifionly"), isOn: $syncWiFiOnly)

                    Button {
                        Task { await syncNow() }
                    } label: {
                        HStack {
                            Label(L("settings.sync.now"), systemImage: "arrow.clockwise")
                            if isSyncing {
                                Spacer()
                                ProgressView()
                            }
                        }
                    }
                    .disabled(isSyncing)

                    if let lastSynced {
                        LabeledContent(L("settings.sync.lastsynced")) {
                            Text(lastSynced.bookStackFormattedWithTime)
                                .foregroundStyle(.secondary)
                        }
                    }
                }

                // About section
                Section(L("settings.about")) {
                    LabeledContent(L("settings.about.version"), value: "\(appVersion) (\(buildNumber))")

                    Button {
                        showSafari = URL(string: "https://www.bookstackapp.com/docs")
                    } label: {
                        Label(L("settings.about.docs"), systemImage: "book.pages")
                    }

                    Button {
                        showSafari = URL(string: "https://github.com/BookStackApp/BookStack/issues")
                    } label: {
                        Label(L("settings.about.issue"), systemImage: "exclamationmark.bubble")
                    }

                    Text(L("settings.about.credit"))
                        .font(.footnote)
                        .foregroundStyle(.secondary)
                }
            }
            .navigationTitle(L("settings.title"))
            .onAppear {
                loggingEnabled = LogManager.shared.isEnabled
            }
            // Switch server confirmation
            .alert(L("settings.servers.switch.title"), isPresented: Binding(
                get: { profileToSwitch != nil },
                set: { if !$0 { profileToSwitch = nil } }
            )) {
                Button(L("settings.servers.switch.confirm")) {
                    if let p = profileToSwitch { profileStore.activate(p) }
                    profileToSwitch = nil
                }
                Button(L("settings.signout.alert.cancel"), role: .cancel) { profileToSwitch = nil }
            } message: {
                if let p = profileToSwitch {
                    Text(String(format: L("settings.servers.switch.message"), p.name))
                }
            }
            // Delete inactive server confirmation
            .alert(L("settings.servers.delete.title"), isPresented: Binding(
                get: { profileToDelete != nil && profileToDelete?.id != profileStore.activeProfileId },
                set: { if !$0 { profileToDelete = nil } }
            )) {
                Button(L("settings.servers.delete.confirm"), role: .destructive) {
                    if let p = profileToDelete { removeProfile(p) }
                    profileToDelete = nil
                }
                Button(L("settings.signout.alert.cancel"), role: .cancel) { profileToDelete = nil }
            } message: {
                if let p = profileToDelete {
                    Text(String(format: L("settings.servers.delete.message"), p.name))
                }
            }
            // Delete ACTIVE server — stronger warning
            .alert(L("settings.servers.delete.active.title"), isPresented: Binding(
                get: { profileToDelete != nil && profileToDelete?.id == profileStore.activeProfileId },
                set: { if !$0 { profileToDelete = nil } }
            )) {
                Button(L("settings.servers.delete.confirm"), role: .destructive) {
                    if let p = profileToDelete { removeProfile(p) }
                    profileToDelete = nil
                }
                Button(L("settings.signout.alert.cancel"), role: .cancel) { profileToDelete = nil }
            } message: {
                if let p = profileToDelete {
                    Text(String(format: L("settings.servers.delete.active.message"), p.name))
                }
            }
            // Add server sheet
            .sheet(isPresented: $showAddServer) {
                AddServerView()
            }
            // Edit server sheet
            .sheet(item: $profileToEdit) { profile in
                EditServerView(profile: profile)
            }
            .sheet(item: $showSafari) { url in
                SafariView(url: url)
                    .ignoresSafeArea()
            }
            .sheet(isPresented: $showLogViewer) {
                LogViewerView()
            }
            .sheet(isPresented: Binding(
                get: { shareItems != nil },
                set: { if !$0 { shareItems = nil } }
            )) {
                if let items = shareItems {
                    ShareSheet(items: items)
                }
            }
        }
    }

    // MARK: - Actions

    private func removeProfile(_ profile: ServerProfile) {
        profileStore.remove(profile)
        // Always clear the cache — it may contain content from this server
        try? SyncService.shared.clearAllCache(context: modelContext)
        lastSynced = nil
        // If no profiles remain, return to onboarding
        if profileStore.profiles.isEmpty {
            onboardingComplete = false
        }
    }

    private func syncNow() async {
        isSyncing = true
        // SyncService.shared.syncAll() requires ModelContext from environment
        // For now just update last synced date
        try? await Task.sleep(for: .seconds(1))
        let now = Date()
        UserDefaults.standard.set(now, forKey: "lastSynced")
        lastSynced = now
        isSyncing = false
    }
}

// MARK: - Safari View

struct SafariView: UIViewControllerRepresentable {
    let url: URL

    func makeUIViewController(context: Context) -> SFSafariViewController {
        SFSafariViewController(url: url)
    }

    func updateUIViewController(_ vc: SFSafariViewController, context: Context) {}
}

extension URL: @retroactive Identifiable {
    public var id: String { absoluteString }
}

// MARK: - Log Viewer

struct LogViewerView: View {
    @Environment(\.dismiss) private var dismiss
    @State private var logManager = LogManager.shared

    var body: some View {
        NavigationStack {
            Group {
                if logManager.entries.isEmpty {
                    ContentUnavailableView(
                        L("settings.log.viewer.title"),
                        systemImage: "list.bullet.rectangle",
                        description: Text("No log entries yet.")
                    )
                } else {
                    List(logManager.entries.reversed()) { entry in
                        VStack(alignment: .leading, spacing: 2) {
                            Text(entry.formatted)
                                .font(.system(.caption, design: .monospaced))
                                .foregroundStyle(colorFor(entry.level))
                        }
                        .listRowInsets(.init(top: 4, leading: 12, bottom: 4, trailing: 12))
                    }
                    .listStyle(.plain)
                }
            }
            .navigationTitle(L("settings.log.viewer.title"))
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .confirmationAction) {
                    Button(L("common.ok")) { dismiss() }
                }
            }
        }
    }

    private func colorFor(_ level: LogEntry.Level) -> Color {
        switch level {
        case .debug:   return .secondary
        case .info:    return .primary
        case .warning: return .orange
        case .error:   return .red
        }
    }
}

// MARK: - Share Sheet

struct ShareSheet: UIViewControllerRepresentable {
    let items: [Any]

    func makeUIViewController(context: Context) -> UIActivityViewController {
        UIActivityViewController(activityItems: items, applicationActivities: nil)
    }

    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {}
}

#Preview {
    SettingsView()
}
