import SwiftUI

struct TagEditorPopover: View {
    let item: ClipboardItem
    var onAdd: (String) -> Void
    var onRemove: (String) -> Void

    @Environment(\.dismiss) private var dismiss
    @State private var draft: String = ""
    @FocusState private var fieldFocused: Bool

    var body: some View {
        VStack(alignment: .leading, spacing: 14) {
            HStack(spacing: 8) {
                Image(systemName: "tag.fill")
                    .foregroundStyle(Color.appAccent)
                Text(L("tags.title"))
                    .font(.system(size: 15, weight: .semibold))
                Spacer()
            }

            HStack(spacing: 8) {
                TextField(L("tags.placeholder"), text: $draft)
                    .focused($fieldFocused)
                    .onSubmit(commit)
                    .paperTextField(focused: fieldFocused)
                Button {
                    commit()
                } label: {
                    Image(systemName: "plus")
                        .font(.system(size: 12, weight: .bold))
                }
                .buttonStyle(PaperActionButtonStyle(role: .primary))
                .disabled(trimmedDraft.isEmpty)
            }

            Divider()

            if item.tags.isEmpty {
                Text(L("tags.empty"))
                    .font(.system(size: 12))
                    .foregroundStyle(.tertiary)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(.vertical, 6)
            } else {
                WrapLayout(spacing: 6, lineSpacing: 6) {
                    ForEach(item.tags, id: \.self) { tag in
                        chip(for: tag)
                    }
                }
                .frame(maxWidth: .infinity, alignment: .leading)
            }

            HStack {
                Spacer()
                Button(L("common.done")) {
                    dismiss()
                }
                .buttonStyle(PaperActionButtonStyle(role: .primary))
                .keyboardShortcut(.defaultAction)
            }
        }
        .padding(18)
        .frame(width: 340)
        .onAppear { fieldFocused = true }
    }

    private var trimmedDraft: String {
        draft.trimmingCharacters(in: .whitespacesAndNewlines)
    }

    private func commit() {
        let value = trimmedDraft
        guard !value.isEmpty else { return }
        onAdd(value)
        draft = ""
    }

    private func chip(for tag: String) -> some View {
        HStack(spacing: 4) {
            Image(systemName: "tag.fill")
                .font(.system(size: 9, weight: .semibold))
            Text(tag)
                .font(.system(size: 11, weight: .medium))
            Button {
                onRemove(tag)
            } label: {
                Image(systemName: "xmark")
                    .font(.system(size: 9, weight: .bold))
            }
            .buttonStyle(.plain)
            .foregroundStyle(.secondary)
        }
        .padding(.horizontal, 8)
        .padding(.vertical, 3)
        .background(
            Capsule(style: .continuous)
                .fill(Color.appAccent.opacity(0.18))
        )
        .overlay(
            Capsule(style: .continuous)
                .strokeBorder(Color.appAccent.opacity(0.35), lineWidth: 0.5)
        )
        .foregroundStyle(Color.appAccent)
    }
}

/// Simple flow layout — wraps child views to multiple lines when they exceed
/// the proposed width. Shared by the tag editor and the search bar's tag
/// suggestion panel.
struct WrapLayout: Layout {
    var spacing: CGFloat = 6
    var lineSpacing: CGFloat = 6

    func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
        let maxWidth = proposal.width ?? .infinity
        var x: CGFloat = 0
        var y: CGFloat = 0
        var lineHeight: CGFloat = 0
        var widest: CGFloat = 0

        for sub in subviews {
            let size = sub.sizeThatFits(.unspecified)
            if x + size.width > maxWidth, x > 0 {
                y += lineHeight + lineSpacing
                x = 0
                lineHeight = 0
            }
            x += size.width + spacing
            lineHeight = max(lineHeight, size.height)
            widest = max(widest, x - spacing)
        }
        return CGSize(width: min(widest, maxWidth), height: y + lineHeight)
    }

    func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
        let maxWidth = bounds.width
        var x: CGFloat = bounds.minX
        var y: CGFloat = bounds.minY
        var lineHeight: CGFloat = 0

        for sub in subviews {
            let size = sub.sizeThatFits(.unspecified)
            if x + size.width > bounds.minX + maxWidth, x > bounds.minX {
                y += lineHeight + lineSpacing
                x = bounds.minX
                lineHeight = 0
            }
            sub.place(at: CGPoint(x: x, y: y), proposal: ProposedViewSize(size))
            x += size.width + spacing
            lineHeight = max(lineHeight, size.height)
        }
    }
}
