import SwiftUI
import CoreData

// MARK: - Categories List View

struct CategoriesView: View {
    @StateObject private var categoryRepository = CategoryRepository()
    @State private var showingAddCategory = false
    @State private var editingCategory: Category?
    @State private var showingDeleteError = false

    var body: some View {
        List {
            if categoryRepository.categories.isEmpty {
                Text(String(localized: "categories_empty"))
                    .foregroundColor(.secondary)
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding(.vertical, 32)
            } else {
                ForEach(categoryRepository.categories) { category in
                    CategoryRow(category: category)
                        .swipeActions(edge: .leading, allowsFullSwipe: false) {
                            Button {
                                editingCategory = category
                            } label: {
                                Label("Edit", systemImage: "pencil")
                            }
                            .tint(.appSecondary)
                        }
                        .swipeActions(edge: .trailing, allowsFullSwipe: false) {
                            if category.sourceCount == 0 {
                                Button(role: .destructive) {
                                    categoryRepository.deleteCategory(category)
                                } label: {
                                    Label("Delete", systemImage: "trash")
                                }
                            } else {
                                Button {
                                    showingDeleteError = true
                                } label: {
                                    Label("Delete", systemImage: "trash")
                                }
                                .tint(.gray)
                            }
                        }
                }
                .onMove { from, to in
                    var reordered = categoryRepository.categories
                    reordered.move(fromOffsets: from, toOffset: to)
                    categoryRepository.updateSortOrder(reordered)
                }
            }
        }
        .navigationTitle("Categories")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button {
                    showingAddCategory = true
                } label: {
                    Image(systemName: "plus")
                }
            }
            ToolbarItem(placement: .navigationBarLeading) {
                EditButton()
            }
        }
        .sheet(isPresented: $showingAddCategory) {
            CategoryEditorView()
        }
        .sheet(item: $editingCategory) { category in
            CategoryEditorView(category: category)
        }
        .alert(
            "Cannot Delete",
            isPresented: $showingDeleteError
        ) {
            Button("OK", role: .cancel) { showingDeleteError = false }
        } message: {
            Text(String(localized: "category_has_sources_warning"))
        }
    }
}

// MARK: - Category Row

private struct CategoryRow: View {
    let category: Category

    var body: some View {
        Group {
            if category.isDeleted || category.isFault {
                EmptyView()
            } else {
                HStack(spacing: 12) {
                    ZStack {
                        Circle()
                            .fill(category.color.opacity(0.2))
                            .frame(width: 40, height: 40)
                        Image(systemName: category.icon)
                            .font(.system(size: 16))
                            .foregroundColor(category.color)
                    }

                    VStack(alignment: .leading, spacing: 2) {
                        Text(category.name)
                            .font(.body)
                        Text(category.sourceCount == 1 ? "1 source" : "\(category.sourceCount) sources")
                            .font(.caption)
                            .foregroundColor(.secondary)
                    }

                    Spacer()
                }
                .padding(.vertical, 2)
            }
        }
    }
}

// MARK: - Category Editor View

struct CategoryEditorView: View {
    let category: Category?

    @Environment(\.dismiss) private var dismiss
    @StateObject private var categoryRepository = CategoryRepository()

    @State private var name = ""
    @State private var selectedColor = "#10B981"
    @State private var selectedIcon = "chart.pie.fill"
    @State private var didLoad = false

    init(category: Category? = nil) {
        self.category = category
    }

    private let colors: [String] = [
        "#10B981", "#3B82F6", "#8B5CF6", "#F59E0B", "#EF4444", "#EC4899",
        "#14B8A6", "#6B7280", "#F97316", "#06B6D4", "#84CC16", "#64748B"
    ]

    private let icons: [String] = [
        "chart.line.uptrend.xyaxis", "chart.bar.fill", "chart.pie.fill",
        "banknote.fill", "building.columns.fill", "house.fill",
        "bitcoinsign.circle.fill", "person.fill", "briefcase.fill",
        "dollarsign.circle.fill", "creditcard.fill", "globe",
        "cart.fill", "star.fill", "heart.fill", "ellipsis.circle.fill",
        "folder.fill", "lock.fill", "leaf.fill", "flame.fill"
    ]

    var body: some View {
        NavigationStack {
            Form {
                Section("Category Name") {
                    TextField(String(localized: "category_name_placeholder"), text: $name)
                        .autocorrectionDisabled()
                }

                Section("Color") {
                    LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 8), count: 6), spacing: 8) {
                        ForEach(colors, id: \.self) { hex in
                            ColorSwatch(hex: hex, isSelected: selectedColor == hex)
                                .onTapGesture { selectedColor = hex }
                        }
                    }
                    .padding(.vertical, 4)
                }

                Section("Icon") {
                    LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 8), count: 5), spacing: 12) {
                        ForEach(icons, id: \.self) { icon in
                            IconSwatch(icon: icon, colorHex: selectedColor, isSelected: selectedIcon == icon)
                                .onTapGesture { selectedIcon = icon }
                        }
                    }
                    .padding(.vertical, 4)
                }

                // Preview
                Section("Preview") {
                    HStack(spacing: 12) {
                        ZStack {
                            Circle()
                                .fill((Color(hex: selectedColor) ?? .blue).opacity(0.2))
                                .frame(width: 44, height: 44)
                            Image(systemName: selectedIcon)
                                .font(.system(size: 18))
                                .foregroundColor(Color(hex: selectedColor) ?? .blue)
                        }
                        Text(name.isEmpty ? String(localized: "category_name_placeholder") : name)
                            .foregroundColor(name.isEmpty ? .secondary : .primary)
                    }
                }
            }
            .navigationTitle(category == nil ? "Add Category" : "Edit Category")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("Cancel") { dismiss() }
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Save") { save() }
                        .fontWeight(.semibold)
                        .disabled(name.trimmingCharacters(in: .whitespaces).isEmpty)
                }
            }
            .onAppear {
                guard let category, !didLoad else { return }
                name = category.name
                selectedColor = category.colorHex
                selectedIcon = category.icon
                didLoad = true
            }
        }
        .presentationDetents([.large])
    }

    private func save() {
        let trimmed = name.trimmingCharacters(in: .whitespaces)
        guard !trimmed.isEmpty else { return }

        if let category {
            categoryRepository.updateCategory(category, name: trimmed, colorHex: selectedColor, icon: selectedIcon)
        } else {
            categoryRepository.createCategory(name: trimmed, colorHex: selectedColor, icon: selectedIcon)
        }
        dismiss()
    }
}

// MARK: - Color Swatch

private struct ColorSwatch: View {
    let hex: String
    let isSelected: Bool

    var body: some View {
        let color = Color(hex: hex) ?? .blue
        Circle()
            .fill(color)
            .frame(width: 36, height: 36)
            .overlay(Circle().strokeBorder(isSelected ? Color.primary : Color.clear, lineWidth: 2))
    }
}

// MARK: - Icon Swatch

private struct IconSwatch: View {
    let icon: String
    let colorHex: String
    let isSelected: Bool

    var body: some View {
        let color = Color(hex: colorHex) ?? .blue
        ZStack {
            RoundedRectangle(cornerRadius: 8)
                .fill(isSelected ? color.opacity(0.2) : Color(.systemGray6))
                .frame(width: 44, height: 44)
            Image(systemName: icon)
                .font(.system(size: 18))
                .foregroundColor(isSelected ? color : .secondary)
        }
    }
}

#Preview {
    NavigationStack {
        CategoriesView()
    }
}
