import SwiftUI

/// The card editor's Attributes section: icon, icon colour, and background colour — the three
/// *typed* style fields a card carries (`FrontmatterFields.icon`/`.iconColor`/`.background`).
///
/// **Drafted, not written.** Every pick here mutates a `Binding<String?>` the caller owns —
/// `CardEditScreen`'s own `@State` drafts — rather than reaching for `BoardWriter` itself: the
/// transactional edit model commits title, body, and these three keys together in one `Save`, so
/// this section has no session, no card, and no write code of its own. It is a pure "edit these
/// three bindings" view; the icon picker sheet is unchanged mechanically, it just feeds a binding
/// instead of firing a write.
///
/// **There is no labels row.** `labels` is not a field either `BoardModel` or `FrontmatterDocument`
/// exposes as typed: `BoardModel.document`'s own doc comment names it as one of the reserved keys
/// that "ride along uninterpreted via `document.unknownFields`", alongside `assignees`, `due`,
/// `remote`. Rendering or editing it here would mean this screen parsing and rewriting a key the
/// model layer deliberately treats as opaque — exactly the unknown-field promise `updateIndex`'s
/// surgical edits exist to keep (agent-written or hand-written overlays round-trip untouched). If
/// a typed `labels` field is ever added to the storage schema, its editor belongs in this section.
struct CardAttributesSection: View {
    @Binding var icon: String?
    @Binding var iconColor: String?
    @Binding var background: String?

    @State private var isPresentingIconPicker = false

    var body: some View {
        Section("Attributes") {
            Button {
                isPresentingIconPicker = true
            } label: {
                LabeledContent("Icon") {
                    if let icon, !icon.isEmpty {
                        Image(systemName: icon)
                    } else {
                        Text("None").foregroundStyle(.secondary)
                    }
                }
            }
            .tint(.primary)

            swatchRow(title: "Icon Color", swatches: CardPalette.foregrounds, current: iconColor) { name in
                iconColor = name
            }

            swatchRow(title: "Background", swatches: CardPalette.backgrounds, current: background) { name in
                background = name
            }
        }
        .sheet(isPresented: $isPresentingIconPicker) {
            IconPickerSheet(current: icon) { name in
                icon = name
            }
        }
    }

    @ViewBuilder
    private func swatchRow(
        title: String,
        swatches: [CardPalette.Swatch],
        current: String?,
        onSelect: @escaping (String?) -> Void
    ) -> some View {
        VStack(alignment: .leading, spacing: 6) {
            Text(title)
                .font(.subheadline)
                .foregroundStyle(.secondary)
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 10) {
                    SwatchButton(isSelected: current == nil, color: nil) { onSelect(nil) }
                    ForEach(swatches) { swatch in
                        SwatchButton(
                            isSelected: current == swatch.name,
                            color: CardPalette.color(named: swatch.name, in: swatches)
                        ) {
                            onSelect(swatch.name)
                        }
                    }
                }
            }
        }
        .padding(.vertical, 4)
    }
}

/// One colour well: a filled circle, a slashed placeholder for "None", and a selection ring.
private struct SwatchButton: View {
    let isSelected: Bool
    let color: Color?
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            Circle()
                .fill(color ?? Color(.systemGray5))
                .frame(width: 28, height: 28)
                .overlay {
                    if color == nil {
                        Image(systemName: "slash.circle")
                            .font(.caption)
                            .foregroundStyle(.secondary)
                    }
                }
                .overlay {
                    Circle()
                        .strokeBorder(isSelected ? Color.accentColor : .clear, lineWidth: 2)
                        .padding(-3)
                }
        }
        .buttonStyle(.plain)
    }
}

/// The icon picker's grid — `CardPalette.icons` plus a "None" well that removes the key.
private struct IconPickerSheet: View {
    let current: String?
    let onSelect: (String?) -> Void

    @Environment(\.dismiss) private var dismiss

    private let columns = Array(repeating: GridItem(.flexible()), count: 6)

    var body: some View {
        NavigationStack {
            ScrollView {
                LazyVGrid(columns: columns, spacing: 20) {
                    Button {
                        onSelect(nil)
                        dismiss()
                    } label: {
                        Image(systemName: "slash.circle")
                            .font(.title2)
                            .foregroundStyle(current == nil ? Color.accentColor : .secondary)
                    }
                    ForEach(CardPalette.icons, id: \.self) { name in
                        Button {
                            onSelect(name)
                            dismiss()
                        } label: {
                            Image(systemName: name)
                                .font(.title2)
                                .foregroundStyle(current == name ? Color.accentColor : .primary)
                        }
                    }
                }
                .padding()
            }
            .navigationTitle("Icon")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") { dismiss() }
                }
            }
        }
    }
}
