import SwiftUI

public struct StatusPopoverView: View {
    @ObservedObject public var controller: MenuBarController
    @FocusState private var searchFocused: Bool
    
    public init(controller: MenuBarController) {
        self.controller = controller
    }
    
    public var body: some View {
        VStack(spacing: 0) {
            // Header with status
            headerSection
            
            Divider()

            searchSection

            Divider()
            
            // Quick actions
            actionsSection
            
            Divider()
            
            // Recent uploads preview (last 3)
            recentUploadsSection
            
            Divider()
            
            // Footer
            footerSection
        }
        .frame(width: 360)
        .padding(.vertical, 12)
        .onAppear {
            Task { @MainActor in
                searchFocused = true
            }
        }
        .onMoveCommand { direction in
            switch direction {
            case .up:
                controller.moveSearchSelection(by: -1)
            case .down:
                controller.moveSearchSelection(by: 1)
            default:
                break
            }
        }
    }
    
    // MARK: - Sections
    
    private var headerSection: some View {
        VStack(spacing: 8) {
            HStack {
                statusIndicator
                
                VStack(alignment: .leading, spacing: 2) {
                    Text(controller.syncStatus)
                        .font(.system(size: 13, weight: .medium))
                    
                    if let lastSync = controller.lastSyncTime {
                        Text("Last sync: \(timeAgo(lastSync))")
                            .font(.caption2)
                            .foregroundColor(.secondary)
                    } else {
                        Text("Never synced")
                            .font(.caption2)
                            .foregroundColor(.secondary)
                    }
                }
                
                Spacer()
                
                if controller.isSyncing {
                    ProgressView()
                        .scaleEffect(0.6)
                }
            }
            
            if controller.pendingChanges > 0 {
                Text("\(controller.pendingChanges) pending changes")
                    .font(.caption)
                    .foregroundColor(.orange)
                    .frame(maxWidth: .infinity, alignment: .leading)
            }
        }
        .padding(.horizontal, 16)
    }
    
    private var statusIndicator: some View {
        Circle()
            .fill(statusColor)
            .frame(width: 8, height: 8)
            .overlay(
                Circle()
                    .stroke(statusColor.opacity(0.3), lineWidth: 2)
                    .frame(width: 14, height: 14)
            )
    }
    
    private var statusColor: Color {
        if controller.isSyncing { return .blue }
        if controller.syncStatus.contains("fail") || controller.syncStatus.contains("error") {
            return .red
        }
        if controller.pendingChanges > 0 { return .orange }
        return .green
    }
    
    private var actionsSection: some View {
        HStack(spacing: 16) {
            ActionButton(
                icon: "arrow.clockwise",
                label: "Sync",
                color: .blue
            ) {
                Task {
                    await controller.performSync()
                }
            }
            
            ActionButton(
                icon: "arrow.up.doc",
                label: "Upload",
                color: .purple
            ) {
                controller.quickUpload()
            }
            
            ActionButton(
                icon: "doc.badge.plus",
                label: "Note",
                color: .green
            ) {
                controller.createNote()
            }
            
            ActionButton(
                icon: "square.and.arrow.down",
                label: "Drop",
                color: .orange
            ) {
                controller.showDropZone()
            }
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 12)
    }

    @ViewBuilder
    private var searchSection: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack(spacing: 8) {
                Image(systemName: "magnifyingglass")
                    .font(.system(size: 13, weight: .medium))
                    .foregroundColor(.secondary)

                TextField(
                    "Search documents",
                    text: Binding(
                        get: { controller.searchQuery },
                        set: { controller.updateSearchQuery($0) }
                    )
                )
                .textFieldStyle(.plain)
                .focused($searchFocused)
                .onSubmit {
                    controller.openSelectedSearchResult()
                }

                if controller.isSearching {
                    ProgressView()
                        .controlSize(.small)
                        .scaleEffect(0.65)
                        .frame(width: 14, height: 14)
                }
            }
            .padding(.horizontal, 10)
            .padding(.vertical, 8)
            .background(Color(NSColor.controlBackgroundColor))
            .clipShape(RoundedRectangle(cornerRadius: 8))

            if controller.searchQuery.trimmingCharacters(in: .whitespacesAndNewlines).count >= MenuBarController.minimumSearchCharacters {
                searchResultsList
            }
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 10)
    }

    @ViewBuilder
    private var searchResultsList: some View {
        if controller.searchResults.isEmpty {
            Text(controller.isSearching ? "Searching..." : (controller.searchError == nil ? "No results" : "Search unavailable"))
                .font(.caption)
                .foregroundColor(.secondary)
                .frame(maxWidth: .infinity, alignment: .center)
                .padding(.vertical, 8)
        } else {
            VStack(spacing: 2) {
                ForEach(Array(controller.searchResults.enumerated()), id: \.element.id) { index, result in
                    SearchResultRow(
                        result: result,
                        isSelected: index == controller.selectedSearchIndex
                    ) {
                        controller.selectedSearchIndex = index
                        controller.openSearchResult(result)
                    }
                    .onHover { isHovered in
                        if isHovered {
                            controller.selectedSearchIndex = index
                        }
                    }
                }
            }
        }
    }
    
    @ViewBuilder
    private var recentUploadsSection: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Text("Recent Uploads")
                    .font(.caption)
                    .fontWeight(.semibold)
                    .foregroundColor(.secondary)
                
                Spacer()
                
                Button("View All") {
                    controller.showUploads()
                }
                .font(.caption)
                .buttonStyle(.plain)
                .foregroundColor(.accentColor)
            }
            
            if controller.isLoadingRecentUploads && controller.recentUploads.isEmpty {
                ProgressView()
                    .scaleEffect(0.6)
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding(.vertical, 8)
            } else if controller.recentUploads.isEmpty {
                Text(controller.recentUploadsError == nil ? "No recent uploads" : "Unable to load recent uploads")
                    .font(.caption2)
                    .foregroundColor(.secondary)
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding(.vertical, 8)
            } else {
                ForEach(controller.recentUploads) { upload in
                    RecentUploadRow(upload: upload, baseURL: controller.config.serverBaseURL)
                }
            }
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 8)
    }
    
    private var footerSection: some View {
        HStack(spacing: 12) {
            Button {
                controller.showSettings()
            } label: {
                HStack(spacing: 4) {
                    Image(systemName: "gear")
                    Text("Settings")
                }
                .font(.caption)
            }
            .buttonStyle(.plain)
            .foregroundColor(.secondary)
            
            Button {
                NSApp.terminate(nil)
            } label: {
                HStack(spacing: 4) {
                    Image(systemName: "power")
                        .font(.caption2)
                    Text("Quit")
                }
                .font(.caption)
            }
            .buttonStyle(.plain)
            .foregroundColor(.secondary)
            
            Spacer()
            
            if let url = controller.config.serverBaseURL {
                Button {
                    NSWorkspace.shared.open(url)
                } label: {
                    HStack(spacing: 4) {
                        Text("Open Server")
                        Image(systemName: "arrow.up.right.square")
                            .font(.caption2)
                    }
                    .font(.caption)
                }
                .buttonStyle(.plain)
                .foregroundColor(.accentColor)
            }
        }
        .padding(.horizontal, 16)
        .padding(.top, 8)
    }
    
    // MARK: - Helpers
    
    private func timeAgo(_ date: Date) -> String {
        let formatter = RelativeDateTimeFormatter()
        formatter.unitsStyle = .abbreviated
        return formatter.localizedString(for: date, relativeTo: Date())
    }
}

private struct RecentUploadRow: View {
    let upload: AttachmentRecord
    let baseURL: URL?

    var body: some View {
        Button(action: openUpload) {
            HStack(spacing: 8) {
                Image(systemName: upload.kind == "document" ? "doc.text" : "paperclip")
                    .foregroundColor(.accentColor)

                VStack(alignment: .leading, spacing: 2) {
                    Text(upload.originalName)
                        .font(.caption)
                        .lineLimit(1)
                    Text(timeAgo(upload.createdAt))
                        .font(.caption2)
                        .foregroundColor(.secondary)
                }

                Spacer()

                Image(systemName: "arrow.up.right.square")
                    .font(.caption2)
                    .foregroundColor(.secondary)
            }
        }
        .buttonStyle(.plain)
    }

    private func openUpload() {
        guard let baseURL,
              let url = URL(string: upload.url, relativeTo: baseURL)?.absoluteURL else {
            return
        }
        NSWorkspace.shared.open(url)
    }

    private func timeAgo(_ date: Date) -> String {
        let formatter = RelativeDateTimeFormatter()
        formatter.unitsStyle = .abbreviated
        return formatter.localizedString(for: date, relativeTo: Date())
    }
}

private struct SearchResultRow: View {
    let result: SearchResult
    let isSelected: Bool
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            HStack(spacing: 8) {
                Image(systemName: "doc.text")
                    .font(.system(size: 14, weight: .medium))
                    .foregroundColor(isSelected ? .white : .accentColor)
                    .frame(width: 18)

                VStack(alignment: .leading, spacing: 2) {
                    Text(result.title.isEmpty ? result.path : result.title)
                        .font(.caption)
                        .foregroundColor(isSelected ? .white : .primary)
                        .lineLimit(1)
                    Text(result.path)
                        .font(.caption2)
                        .foregroundColor(isSelected ? .white.opacity(0.82) : .secondary)
                        .lineLimit(1)
                }

                Spacer(minLength: 0)

                Image(systemName: "return")
                    .font(.caption2)
                    .foregroundColor(isSelected ? .white.opacity(0.75) : .secondary)
                    .opacity(isSelected ? 1 : 0)
            }
            .padding(.horizontal, 8)
            .padding(.vertical, 6)
            .frame(height: 44)
            .background(isSelected ? Color.accentColor : Color.clear)
            .clipShape(RoundedRectangle(cornerRadius: 6))
        }
        .buttonStyle(.plain)
    }
}

// MARK: - Action Button

struct ActionButton: View {
    let icon: String
    let label: String
    let color: Color
    let action: () -> Void
    
    var body: some View {
        Button(action: action) {
            VStack(spacing: 6) {
                Image(systemName: icon)
                    .font(.system(size: 20, weight: .medium))
                    .foregroundColor(color)
                    .frame(width: 40, height: 40)
                    .background(color.opacity(0.1))
                    .clipShape(RoundedRectangle(cornerRadius: 10))
                
                Text(label)
                    .font(.caption2)
                    .fontWeight(.medium)
                    .foregroundColor(.primary)
            }
        }
        .buttonStyle(.plain)
    }
}

#Preview {
    // Preview won't work without a real controller
    Text("StatusPopoverView Preview")
}
