//
//  HistoryView.swift
//  oAI
//
//  Command history viewer with search
//
// 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 os
import SwiftUI

struct HistoryView: View {
    @Environment(\.dismiss) var dismiss
    @State private var searchText = ""
    @State private var historyEntries: [HistoryEntry] = []
    @State private var selectedIndex: Int = 0
    @FocusState private var isListFocused: Bool
    var onSelect: ((String) -> Void)?

    private var filteredHistory: [HistoryEntry] {
        if searchText.isEmpty {
            return historyEntries
        }
        return historyEntries.filter {
            $0.input.lowercased().contains(searchText.lowercased()) ||
            $0.formattedDate.contains(searchText)
        }
    }

    var body: some View {
        VStack(spacing: 0) {
            // Header
            HStack {
                Text("Command History")
                    .font(.system(size: 18, weight: .bold))
                Spacer()
                Button { dismiss() } label: {
                    Image(systemName: "xmark.circle.fill")
                        .font(.title2)
                        .foregroundStyle(.secondary)
                }
                .buttonStyle(.plain)
                .keyboardShortcut(.escape, modifiers: [])
            }
            .padding(.horizontal, 24)
            .padding(.top, 20)
            .padding(.bottom, 12)

            // Search bar
            HStack(spacing: 8) {
                Image(systemName: "magnifyingglass")
                    .foregroundStyle(.secondary)
                TextField("Search by text or date (dd.mm.yyyy)...", text: $searchText)
                    .textFieldStyle(.plain)
                if !searchText.isEmpty {
                    Button { searchText = "" } label: {
                        Image(systemName: "xmark.circle.fill")
                            .foregroundStyle(.tertiary)
                    }
                    .buttonStyle(.plain)
                }
            }
            .padding(10)
            .background(.quaternary.opacity(0.5), in: RoundedRectangle(cornerRadius: 8))
            .padding(.horizontal, 24)
            .padding(.bottom, 12)

            Divider()

            // Content
            if filteredHistory.isEmpty {
                Spacer()
                VStack(spacing: 8) {
                    Image(systemName: searchText.isEmpty ? "list.bullet" : "magnifyingglass")
                        .font(.largeTitle)
                        .foregroundStyle(.tertiary)
                    Text(searchText.isEmpty ? "No Command History" : "No Matches")
                        .font(.headline)
                        .foregroundStyle(.secondary)
                    Text(searchText.isEmpty ? "Your command history will appear here" : "Try a different search term or date")
                        .font(.caption)
                        .foregroundStyle(.tertiary)
                }
                Spacer()
            } else {
                ScrollViewReader { proxy in
                    List {
                        ForEach(Array(filteredHistory.enumerated()), id: \.element.id) { index, entry in
                            HistoryRow(
                                entry: entry,
                                isSelected: index == selectedIndex
                            )
                            .contentShape(Rectangle())
                            .onTapGesture {
                                selectedIndex = index
                                onSelect?(entry.input)
                                dismiss()
                            }
                            .id(entry.id)
                        }
                    }
                    .listStyle(.plain)
                    .focused($isListFocused)
                    .onChange(of: selectedIndex) {
                        withAnimation {
                            proxy.scrollTo(filteredHistory[selectedIndex].id, anchor: .center)
                        }
                    }
                    .onChange(of: searchText) {
                        selectedIndex = 0
                    }
                    #if os(macOS)
                    .onKeyPress(.upArrow) {
                        if selectedIndex > 0 {
                            selectedIndex -= 1
                        }
                        return .handled
                    }
                    .onKeyPress(.downArrow) {
                        if selectedIndex < filteredHistory.count - 1 {
                            selectedIndex += 1
                        }
                        return .handled
                    }
                    .onKeyPress(.return) {
                        if !filteredHistory.isEmpty && selectedIndex < filteredHistory.count {
                            onSelect?(filteredHistory[selectedIndex].input)
                            dismiss()
                        }
                        return .handled
                    }
                    #endif
                }
            }
        }
        .frame(minWidth: 600, minHeight: 400)
        .background(Color.oaiBackground)
        .task {
            loadHistory()
            isListFocused = true
        }
    }

    private func loadHistory() {
        do {
            let records = try DatabaseService.shared.loadCommandHistory()
            historyEntries = records.map { HistoryEntry(input: $0.input, timestamp: $0.timestamp) }
        } catch {
            Log.db.error("Failed to load command history: \(error.localizedDescription)")
        }
    }
}

struct HistoryRow: View {
    let entry: HistoryEntry
    let isSelected: Bool
    private let settings = SettingsService.shared

    var body: some View {
        VStack(alignment: .leading, spacing: 6) {
            // Input text
            Text(entry.input)
                .font(.system(size: settings.dialogTextSize))
                .foregroundStyle(.primary)
                .lineLimit(3)

            // Timestamp
            HStack(spacing: 4) {
                Image(systemName: "clock")
                    .font(.caption2)
                    .foregroundStyle(.secondary)
                Text(entry.formattedDate)
                    .font(.system(size: 11))
                    .foregroundStyle(.secondary)
            }
        }
        .padding(.vertical, 8)
        .padding(.horizontal, 4)
        .listRowBackground(isSelected ? Color.oaiAccent.opacity(0.2) : Color.clear)
    }
}

#Preview {
    HistoryView { input in
        print("Selected: \(input)")
    }
}

#Preview("History Row") {
    HistoryRow(
        entry: HistoryEntry(
            input: "Tell me about Swift concurrency",
            timestamp: Date()
        ),
        isSelected: true
    )
}
