import { useMemo, useState, type ReactNode } from "react";
import { cn } from "./cn.js";

export interface InspectorSectionSpec {
  id: string;
  label: string;
  description?: string;
  group?: string;
  content: ReactNode;
  disabled?: boolean;
  tone?: "default" | "accent";
}

export interface InspectorProps {
  sections: InspectorSectionSpec[];
  defaultOpen?: string[];
  activeId?: string;
  singleOpen?: boolean;
  className?: string;
  onActiveChange?: (id: string) => void;
}

export function Inspector({
  sections,
  defaultOpen = [],
  activeId,
  singleOpen = false,
  className,
  onActiveChange,
}: InspectorProps) {
  const [openIds, setOpenIds] = useState(() => new Set(defaultOpen));
  const groups = useMemo(() => {
    const result: Array<{ label?: string; sections: InspectorSectionSpec[] }> = [];
    sections.forEach((section) => {
      const previous = result[result.length - 1];
      if (previous && previous.label === section.group) {
        previous.sections.push(section);
      } else {
        result.push({ label: section.group, sections: [section] });
      }
    });
    return result;
  }, [sections]);

  const toggle = (id: string) => {
    setOpenIds((current) => {
      const next = singleOpen ? new Set<string>() : new Set(current);
      if (current.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
    onActiveChange?.(id);
  };

  return (
    <div className={cn("nodedc-inspector", className)}>
      {groups.map((group, groupIndex) => (
        <div className="nodedc-inspector__group" key={`${group.label ?? "root"}-${groupIndex}`}>
          {group.sections.map((section) => {
            const isOpen = openIds.has(section.id);
            return (
              <section className="nodedc-inspector__section" key={section.id}>
                <button
                  type="button"
                  className="nodedc-inspector__section-trigger"
                  data-open={isOpen ? "true" : undefined}
                  data-active={activeId === section.id ? "true" : undefined}
                  data-tone={section.tone === "accent" ? "accent" : undefined}
                  aria-expanded={isOpen}
                  disabled={section.disabled}
                  onClick={() => toggle(section.id)}
                >
                  <span className="nodedc-inspector__section-label">{section.label}</span>
                  {section.description ? (
                    <span className="nodedc-inspector__section-description">{section.description}</span>
                  ) : null}
                </button>
                {isOpen ? <div className="nodedc-inspector__section-content">{section.content}</div> : null}
              </section>
            );
          })}
        </div>
      ))}
    </div>
  );
}

export interface ControlRowProps {
  label: ReactNode;
  children: ReactNode;
  layout?: "inline" | "stack";
  className?: string;
}

export function ControlRow({ label, children, layout = "inline", className }: ControlRowProps) {
  return (
    <div
      className={cn("nodedc-control-row", className)}
      data-layout={layout === "inline" ? undefined : layout}
    >
      <div className="nodedc-control-row__label">{label}</div>
      <div className="nodedc-control-row__control">{children}</div>
    </div>
  );
}
