/**
 * WidgetPicker — Dialog to browse available widgets and add them to the dashboard.
 */

import { useState, useCallback } from "react";
import type { ReactElement } from "react";
import type { WidgetPlacement } from "@mosaic/shared";
import { getAllWidgets, type WidgetDefinition } from "./WidgetRegistry";

export interface WidgetPickerProps {
  open: boolean;
  onClose: () => void;
  onAddWidget: (placement: WidgetPlacement) => void;
  currentLayout: WidgetPlacement[];
}

/** Generate a unique widget ID: "WidgetType-<random>" */
function generateWidgetId(widgetName: string): string {
  const suffix = Math.random().toString(36).slice(2, 8);
  return `${widgetName}-${suffix}`;
}

/** Find the first open Y position at x=0 that doesn't overlap */
function findNextY(layout: WidgetPlacement[]): number {
  if (layout.length === 0) return 0;
  let maxBottom = 0;
  for (const item of layout) {
    const bottom = item.y + item.h;
    if (bottom > maxBottom) maxBottom = bottom;
  }
  return maxBottom;
}

function WidgetPickerItem({
  widget,
  onAdd,
}: {
  widget: WidgetDefinition;
  onAdd: () => void;
}): ReactElement {
  const [hovered, setHovered] = useState(false);

  return (
    <div
      onMouseEnter={(): void => {
        setHovered(true);
      }}
      onMouseLeave={(): void => {
        setHovered(false);
      }}
      style={{
        display: "flex",
        alignItems: "center",
        gap: 12,
        padding: "12px 16px",
        borderRadius: "var(--r)",
        background: hovered ? "var(--surface-2)" : "transparent",
        transition: "background 0.12s ease",
      }}
    >
      <div style={{ flex: 1, minWidth: 0 }}>
        <div
          style={{
            fontSize: "0.9rem",
            fontWeight: 600,
            color: "var(--text)",
          }}
        >
          {widget.displayName}
        </div>
        <div
          style={{
            fontSize: "0.78rem",
            color: "var(--muted)",
            marginTop: 2,
            lineHeight: 1.4,
          }}
        >
          {widget.description}
        </div>
        <div
          style={{
            fontSize: "0.7rem",
            color: "var(--muted)",
            marginTop: 4,
            opacity: 0.7,
          }}
        >
          Default size: {widget.defaultWidth}&times;{widget.defaultHeight}
        </div>
      </div>
      <button
        onClick={onAdd}
        style={{
          padding: "6px 12px",
          borderRadius: "var(--r)",
          border: "1px solid var(--primary)",
          background: hovered ? "var(--primary)" : "transparent",
          color: hovered ? "#fff" : "var(--primary-l)",
          fontSize: "0.78rem",
          fontWeight: 500,
          cursor: "pointer",
          transition: "all 0.12s ease",
          whiteSpace: "nowrap",
        }}
      >
        Add
      </button>
    </div>
  );
}

export function WidgetPicker({
  open,
  onClose,
  onAddWidget,
  currentLayout,
}: WidgetPickerProps): ReactElement | null {
  const allWidgets = getAllWidgets();
  const [search, setSearch] = useState("");

  const filtered = search
    ? allWidgets.filter(
        (w) =>
          w.displayName.toLowerCase().includes(search.toLowerCase()) ||
          w.description.toLowerCase().includes(search.toLowerCase())
      )
    : allWidgets;

  const handleAdd = useCallback(
    (widget: WidgetDefinition) => {
      const placement: WidgetPlacement = {
        i: generateWidgetId(widget.name),
        x: 0,
        y: findNextY(currentLayout),
        w: widget.defaultWidth,
        h: widget.defaultHeight,
        minW: widget.minWidth,
        minH: widget.minHeight,
      };
      if (widget.maxWidth !== undefined) placement.maxW = widget.maxWidth;
      if (widget.maxHeight !== undefined) placement.maxH = widget.maxHeight;
      onAddWidget(placement);
    },
    [currentLayout, onAddWidget]
  );

  if (!open) return null;

  return (
    <>
      {/* Backdrop */}
      <div
        onClick={onClose}
        style={{
          position: "fixed",
          inset: 0,
          background: "rgba(0,0,0,0.4)",
          zIndex: 999,
        }}
        aria-hidden="true"
      />

      {/* Panel */}
      <div
        role="dialog"
        aria-label="Add Widget"
        style={{
          position: "fixed",
          top: 0,
          right: 0,
          bottom: 0,
          width: 380,
          maxWidth: "90vw",
          background: "var(--surface)",
          borderLeft: "1px solid var(--border)",
          boxShadow: "var(--shadow-lg)",
          zIndex: 1000,
          display: "flex",
          flexDirection: "column",
          overflow: "hidden",
        }}
      >
        {/* Header */}
        <div
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            padding: "16px 20px",
            borderBottom: "1px solid var(--border)",
          }}
        >
          <h2
            style={{
              fontSize: "1.1rem",
              fontWeight: 700,
              color: "var(--text)",
              margin: 0,
            }}
          >
            Add Widget
          </h2>
          <button
            onClick={onClose}
            aria-label="Close"
            style={{
              background: "none",
              border: "none",
              color: "var(--muted)",
              cursor: "pointer",
              padding: 4,
              fontSize: "1.2rem",
              lineHeight: 1,
            }}
          >
            &times;
          </button>
        </div>

        {/* Search */}
        <div style={{ padding: "12px 20px 0" }}>
          <input
            type="text"
            placeholder="Search widgets..."
            value={search}
            onChange={(e): void => {
              setSearch(e.target.value);
            }}
            style={{
              width: "100%",
              padding: "8px 12px",
              borderRadius: "var(--r)",
              border: "1px solid var(--border)",
              background: "var(--surface-2)",
              color: "var(--text)",
              fontSize: "0.85rem",
              outline: "none",
            }}
          />
        </div>

        {/* Widget list */}
        <div
          style={{
            flex: 1,
            overflowY: "auto",
            padding: "8px 12px",
          }}
        >
          {filtered.length === 0 ? (
            <div
              style={{
                padding: 20,
                textAlign: "center",
                color: "var(--muted)",
                fontSize: "0.85rem",
              }}
            >
              No widgets found
            </div>
          ) : (
            filtered.map((widget) => (
              <WidgetPickerItem
                key={widget.name}
                widget={widget}
                onAdd={(): void => {
                  handleAdd(widget);
                }}
              />
            ))
          )}
        </div>
      </div>
    </>
  );
}
