import SwiftUI
import SwiftData

struct QuickNoteView: View {
    @Environment(\.modelContext) private var modelContext
    @Environment(ConnectivityMonitor.self) private var connectivity

    // Form fields
    @State private var title = ""
    @State private var content = ""
    @State private var tagsRaw = ""

    // Location selection
    @State private var shelves: [ShelfDTO] = []
    @State private var books: [BookDTO] = []
    @State private var selectedShelf: ShelfDTO? = nil
    @State private var selectedBook: BookDTO? = nil
    @State private var isLoadingShelves = false
    @State private var isLoadingBooks = false

    // Save state
    @State private var isSaving = false
    @State private var savedMessage: String? = nil
    @State private var error: String? = nil

    // Pending notes
    @Query(sort: \PendingNote.createdAt) private var pendingNotes: [PendingNote]
    @State private var isUploadingPending = false

    var body: some View {
        NavigationStack {
            Form {
                // Note content
                Section(L("quicknote.field.title")) {
                    TextField(L("quicknote.field.title"), text: $title)
                }

                Section(L("quicknote.field.content")) {
                    TextEditor(text: $content)
                        .frame(minHeight: 120)
                        .font(.system(.body, design: .monospaced))
                }

                Section(L("quicknote.field.tags")) {
                    TextField(L("quicknote.field.tags"), text: $tagsRaw)
                        .autocorrectionDisabled()
                        .textInputAutocapitalization(.never)
                }

                // Location: shelf → book
                Section(L("quicknote.section.location")) {
                    if isLoadingShelves {
                        HStack {
                            ProgressView().controlSize(.small)
                            Text(L("quicknote.shelf.loading"))
                                .foregroundStyle(.secondary)
                                .padding(.leading, 8)
                        }
                    } else {
                        Picker(L("create.shelf.title"), selection: $selectedShelf) {
                            Text(L("quicknote.shelf.none")).tag(ShelfDTO?.none)
                            ForEach(shelves) { shelf in
                                Text(shelf.name).tag(ShelfDTO?.some(shelf))
                            }
                        }
                        .onChange(of: selectedShelf) { _, shelf in
                            selectedBook = nil
                            if let shelf {
                                Task { await loadBooks(for: shelf) }
                            } else {
                                Task { await loadAllBooks() }
                            }
                        }
                    }

                    if isLoadingBooks {
                        HStack {
                            ProgressView().controlSize(.small)
                            Text(L("quicknote.book.loading"))
                                .foregroundStyle(.secondary)
                                .padding(.leading, 8)
                        }
                    } else {
                        Picker(L("create.book.title"), selection: $selectedBook) {
                            Text(L("quicknote.book.none")).tag(BookDTO?.none)
                            ForEach(books) { book in
                                Text(book.name).tag(BookDTO?.some(book))
                            }
                        }
                    }
                }

                // Feedback
                if let msg = savedMessage {
                    Section {
                        HStack {
                            Image(systemName: "checkmark.circle.fill").foregroundStyle(.green)
                            Text(msg).foregroundStyle(.secondary).font(.footnote)
                        }
                    }
                }
                if let err = error {
                    Section {
                        HStack {
                            Image(systemName: "exclamationmark.triangle.fill").foregroundStyle(.red)
                            Text(err).foregroundStyle(.red).font(.footnote)
                        }
                    }
                }

                // Pending notes section
                if !pendingNotes.isEmpty {
                    Section {
                        ForEach(pendingNotes) { note in
                            VStack(alignment: .leading, spacing: 2) {
                                Text(note.title).font(.body)
                                Text(note.bookName)
                                    .font(.caption)
                                    .foregroundStyle(.secondary)
                            }
                        }
                        .onDelete(perform: deletePending)

                        Button {
                            Task { await uploadPending() }
                        } label: {
                            if isUploadingPending {
                                HStack {
                                    ProgressView().controlSize(.small)
                                    Text(L("quicknote.pending.uploading"))
                                        .foregroundStyle(.secondary)
                                        .padding(.leading, 6)
                                }
                            } else {
                                Label(L("quicknote.pending.upload"), systemImage: "arrow.up.circle")
                            }
                        }
                        .disabled(isUploadingPending || !connectivity.isConnected)
                    } header: {
                        Text(L("quicknote.pending.title"))
                    }
                }
            }
            .navigationTitle(L("quicknote.title"))
            .toolbar {
                ToolbarItem(placement: .confirmationAction) {
                    if isSaving {
                        ProgressView().controlSize(.small)
                    } else {
                        Button(L("quicknote.save")) {
                            Task { await save() }
                        }
                        .disabled(title.isEmpty || selectedBook == nil)
                    }
                }
            }
            .task {
                await loadShelves()
            }
        }
    }

    // MARK: - Load shelves / books

    private func loadShelves() async {
        isLoadingShelves = true
        shelves = (try? await BookStackAPI.shared.fetchShelves()) ?? []
        isLoadingShelves = false
        await loadAllBooks()
    }

    private func loadAllBooks() async {
        isLoadingBooks = true
        books = (try? await BookStackAPI.shared.fetchBooks()) ?? []
        isLoadingBooks = false
    }

    private func loadBooks(for shelf: ShelfDTO) async {
        isLoadingBooks = true
        books = (try? await BookStackAPI.shared.fetchShelf(id: shelf.id))?.books ?? []
        isLoadingBooks = false
    }

    // MARK: - Save

    private func save() async {
        guard let book = selectedBook else {
            error = L("quicknote.error.nobook")
            return
        }
        error = nil
        savedMessage = nil
        isSaving = true

        let tagDTOs = parsedTags()

        if connectivity.isConnected {
            do {
                let page = try await BookStackAPI.shared.createPage(
                    bookId: book.id,
                    name: title,
                    markdown: content,
                    tags: tagDTOs
                )
                AppLog(.info, "Quick note '\(title)' created as page \(page.id)", category: "QuickNote")
                savedMessage = L("quicknote.saved.online")
                resetForm()
            } catch {
                self.error = error.localizedDescription
            }
        } else {
            let tagsString = tagDTOs.map { "\($0.name):\($0.value)" }.joined(separator: ",")
            let pending = PendingNote(
                title: title,
                markdown: content,
                tags: tagsString,
                bookId: book.id,
                bookName: book.name
            )
            modelContext.insert(pending)
            try? modelContext.save()
            savedMessage = L("quicknote.saved.offline")
            resetForm()
        }
        isSaving = false
    }

    // MARK: - Pending

    private func uploadPending() async {
        isUploadingPending = true
        await SyncService.shared.flushPendingNotes(context: modelContext)
        isUploadingPending = false
    }

    private func deletePending(at offsets: IndexSet) {
        for i in offsets {
            modelContext.delete(pendingNotes[i])
        }
        try? modelContext.save()
    }

    // MARK: - Helpers

    private func parsedTags() -> [TagDTO] {
        tagsRaw.split(separator: ",").compactMap { token -> TagDTO? in
            let parts = token.trimmingCharacters(in: .whitespaces)
                             .split(separator: ":", maxSplits: 1)
                             .map(String.init)
            guard parts.count == 2 else { return nil }
            return TagDTO(name: parts[0].trimmingCharacters(in: .whitespaces),
                          value: parts[1].trimmingCharacters(in: .whitespaces),
                          order: 0)
        }
    }

    private func resetForm() {
        title = ""
        content = ""
        tagsRaw = ""
    }
}
