//
//  oAIApp.swift
//  oAI
//
//  Main app entry point
//
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2026 Rune Olsen
//
// This file is part of oAI.
//
// oAI is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// oAI is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
// Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with oAI. If not, see <https://www.gnu.org/licenses/>.


import SwiftUI
#if os(macOS)
import AppKit
#endif

@main
struct oAIApp: App {
    @State private var chatViewModel = ChatViewModel()
    @State private var showAbout = false

    init() {
        // Start email handler on app launch
        EmailHandlerService.shared.start()

        // Sync Git changes on app launch (pull + import)
        Task {
            await GitSyncService.shared.syncOnStartup()
        }

        // Check for updates in the background
        UpdateCheckService.shared.checkForUpdates()
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(chatViewModel)
                .preferredColorScheme(.dark)
                .sheet(isPresented: $showAbout) {
                    AboutView()
                }
                #if os(macOS)
                .onReceive(NotificationCenter.default.publisher(for: NSApplication.willTerminateNotification)) { _ in
                    // Trigger auto-save on app quit
                    Task {
                        await chatViewModel.onAppWillTerminate()
                    }
                }
                #endif
        }
        #if os(macOS)
        .windowStyle(.hiddenTitleBar)
        .windowToolbarStyle(.unified)
        .defaultSize(width: 1024, height: 800)
        .windowResizability(.contentMinSize)
        .commands {
            // ── Apple menu ────────────────────────────────────────────────
            CommandGroup(replacing: .appInfo) {
                Button("About oAI") { showAbout = true }
            }

            CommandGroup(replacing: .appSettings) {
                Button("Settings…") { chatViewModel.showSettings = true }
                    .keyboardShortcut(",", modifiers: .command)
            }

            // ── File menu ─────────────────────────────────────────────────
            // Replacing .newItem removes the auto-added "New Window" entry
            CommandGroup(replacing: .newItem) {
                Button("New Chat") { chatViewModel.newConversation() }
                    .keyboardShortcut("n", modifiers: .command)
                Button("Clear Chat") { chatViewModel.clearChat() }
                    .keyboardShortcut("k", modifiers: .command)
                    .disabled(chatViewModel.messages.filter { $0.role != .system }.isEmpty)
            }

            CommandGroup(after: .newItem) {
                Button("Open Chat…") { chatViewModel.showConversations = true }
                    .keyboardShortcut("o", modifiers: .command)
                Button("Search Conversations") { chatViewModel.showConversations = true }
                    .keyboardShortcut("l", modifiers: .command)
            }

            CommandGroup(replacing: .saveItem) {
                Button("Save Chat") { chatViewModel.saveFromMenu() }
                    .keyboardShortcut("s", modifiers: .command)
                    .disabled(chatViewModel.messages.filter { $0.role != .system }.isEmpty)
                Button("Save Chat As…") { chatViewModel.saveAsFromMenu() }
                    .disabled(chatViewModel.messages.filter { $0.role != .system }.isEmpty)
                Button("Stats") { chatViewModel.showStats = true }
                    .keyboardShortcut("s", modifiers: [.command, .shift])
            }

            CommandGroup(after: .importExport) {
                Button("Export as Markdown…") {
                    let name = chatViewModel.currentConversationName ?? "conversation"
                    let safe = name.components(separatedBy: .whitespacesAndNewlines).joined(separator: "-")
                    chatViewModel.exportConversation(format: "md", filename: "\(safe).md")
                }
                .disabled(chatViewModel.messages.filter { $0.role != .system }.isEmpty)
            }

            // ── View menu ─────────────────────────────────────────────────
            CommandMenu("View") {
                Button("Select Model") { chatViewModel.showModelSelector = true }
                    .keyboardShortcut("m", modifiers: .command)

                Button("Model Info") {
                    chatViewModel.modelInfoTarget = chatViewModel.selectedModel
                }
                .keyboardShortcut("i", modifiers: .command)
                .disabled(chatViewModel.selectedModel == nil)

                Divider()

                Button("Command History") { chatViewModel.showHistory = true }
                    .keyboardShortcut("h", modifiers: .command)

                Button("In-App Help") { chatViewModel.showHelp = true }
                    .keyboardShortcut("/", modifiers: .command)

                Button("Credits") { chatViewModel.showCredits = true }

                Divider()

                Button(chatViewModel.onlineMode ? "Online Mode: On" : "Online Mode: Off") {
                    chatViewModel.onlineMode.toggle()
                }
                .keyboardShortcut("o", modifiers: [.command, .shift])
            }

            // ── Help menu ─────────────────────────────────────────────────
            CommandGroup(replacing: .help) {
                Button("oAI Help") { openHelp() }
                    .keyboardShortcut("?", modifiers: .command)
                Divider()
                Button(UpdateCheckService.shared.isCheckingManually ? "Checking…" : "Check for Updates…") {
                    UpdateCheckService.shared.checkForUpdatesManually()
                }
                .disabled(UpdateCheckService.shared.isCheckingManually)
            }
        }
        #endif
    }

    #if os(macOS)
    private func openHelp() {
        if let helpBookURL = Bundle.main.url(forResource: "oAI.help", withExtension: nil) {
            NSWorkspace.shared.open(helpBookURL.appendingPathComponent("Contents/Resources/en.lproj/index.html"))
        } else {
            // Fallback to Apple Help if help book not found
            NSHelpManager.shared.openHelpAnchor("", inBook: Bundle.main.object(forInfoDictionaryKey: "CFBundleHelpBookName") as? String)
        }
    }
    #endif
}
