import { logComplete } from "../logger";
/**
 * RefreshButton Component Generator
 *
 * Generates RefreshButton ComponentSet in Figma with properties:
 * - size: xs, sm, base, lg
 * - loading: true, false
 *
 * RefreshButton is a specialized square icon button with a refresh icon.
 * It uses shape="square" and variant="secondary" (default Button variant).
 *
 * Uses real icons from the Icon Library page.
 *
 * @see packages/kumo/src/components/button/button.tsx
 */

import {
  bindFillToVariable,
  bindStrokeToVariable,
  getVariableByName,
  createModeSection,
  createRowLabel,
  BORDER_RADIUS,
  SECTION_PADDING,
  SECTION_GAP,
  FALLBACK_VALUES,
  GRID_LAYOUT,
  SECTION_LAYOUT,
} from "./shared";
import { parseTailwindClasses } from "../parsers/tailwind-to-figma";
import {
  getButtonIcon,
  createLoader,
  DEFAULT_ICONS,
  bindIconColor,
} from "./icon-utils";

// Import variant data from the registry (generated by build:ai-metadata)
import registry from "@cloudflare/kumo/ai/component-registry.json";

// Extract props from registry
const buttonProps = registry.components.Button.props;

const variantProp = buttonProps.variant as {
  values: string[];
  classes: Record<string, string>;
  descriptions: Record<string, string>;
  default: string;
};

const sizeProp = buttonProps.size as {
  values: string[];
  classes: Record<string, string>;
  descriptions: Record<string, string>;
  default: string;
};

/**
 * Refresh icon size by button size
 * From RefreshButton component: size-4.5 (base), size-4 (sm), size-5 (lg)
 * Uses FALLBACK_VALUES.iconSize from shared.ts to prevent drift
 */
const REFRESH_ICON_SIZE: Record<string, number> = {
  xs: FALLBACK_VALUES.iconSize.xs, // size-3 = 12px
  sm: FALLBACK_VALUES.iconSize.sm, // size-4 = 16px
  base: FALLBACK_VALUES.iconSize.medium, // size-4.5 = 18px
  lg: FALLBACK_VALUES.iconSize.base, // size-5 = 20px
};

/**
 * Get border radius for size
 */
function getBorderRadiusForSize(size: string): number {
  const sizeClasses = sizeProp.classes[size] || "";
  const parsed = parseTailwindClasses(sizeClasses);
  return parsed.borderRadius !== undefined
    ? parsed.borderRadius
    : BORDER_RADIUS.lg;
}

/**
 * Create a single refresh button component
 */
function createRefreshButtonComponent(
  size: string,
  loading: boolean,
): ComponentNode {
  // RefreshButton uses secondary variant by default
  const variant = variantProp.default; // "secondary"
  const variantClasses = variantProp.classes[variant] || "";
  const variantStyles = parseTailwindClasses(variantClasses);

  const component = figma.createComponent();
  component.name = "size=" + size + ", loading=" + loading;
  component.description = "Refresh button for triggering data refresh";

  // Get dimensions from compact size (square button)
  // Uses FALLBACK_VALUES.buttonCompactSize from shared.ts (generated from theme-data.json)
  const buttonSize =
    FALLBACK_VALUES.buttonCompactSize[
      size as keyof typeof FALLBACK_VALUES.buttonCompactSize
    ] || FALLBACK_VALUES.height.base;

  // Configure auto-layout
  component.layoutMode = "HORIZONTAL";
  component.primaryAxisAlignItems = "CENTER";
  component.counterAxisAlignItems = "CENTER";
  component.primaryAxisSizingMode = "FIXED";
  component.counterAxisSizingMode = "FIXED";
  component.resize(buttonSize, buttonSize);

  // Square shape uses size-based border radius
  component.cornerRadius = getBorderRadiusForSize(size);

  // Apply fill from variant
  if (variantStyles.fillVariable) {
    const fillVar = getVariableByName(variantStyles.fillVariable);
    if (fillVar) {
      bindFillToVariable(component, fillVar.id);
    }
  }

  // Apply stroke for secondary variant
  if (variantStyles.hasBorder && variantStyles.strokeVariable) {
    const strokeVar = getVariableByName(variantStyles.strokeVariable);
    if (strokeVar) {
      bindStrokeToVariable(component, strokeVar.id, 1);
    }
  }

  // Add refresh icon or loader
  const iconSize = REFRESH_ICON_SIZE[size] || FALLBACK_VALUES.iconSize.medium;

  if (loading) {
    const loader = createLoader(iconSize);
    component.appendChild(loader);
  } else {
    // Use real refresh icon from Icon Library
    const icon = getButtonIcon(DEFAULT_ICONS.refresh, size);
    // Resize to match refresh button icon sizes
    if ("resize" in icon) {
      icon.resize(iconSize, iconSize);
    }

    // Bind icon color based on variant text color
    if (variantStyles.isWhiteText) {
      bindIconColor(icon, "text-white");
    } else if (variantStyles.textVariable) {
      bindIconColor(icon, variantStyles.textVariable);
    } else {
      bindIconColor(icon, "text-kumo-default");
    }

    component.appendChild(icon);
  }

  return component;
}

/**
 * Generate RefreshButton ComponentSet
 *
 * @param page - Target page for components
 * @param startY - Y position to start placing sections
 * @returns The Y position after all sections
 */
export async function generateRefreshButtonComponents(
  page: PageNode,
  startY: number,
): Promise<number> {
  if (startY === undefined) startY = 100;

  figma.currentPage = page;

  const sizes = sizeProp.values;
  const loadingOptions = [false, true];

  // Generate all combinations
  const components: ComponentNode[] = [];

  // Track row labels: { y, text }
  const rowLabels: { y: number; text: string }[] = [];

  const componentGap = 20;
  const rowGap = 60;
  const labelColumnWidth = 140; // Space for labels on the left

  // Layout vertically by loading state
  let currentY = 0;
  for (let lo = 0; lo < loadingOptions.length; lo++) {
    const loading = loadingOptions[lo];
    rowLabels.push({ y: currentY, text: "loading=" + loading });

    let currentX = labelColumnWidth;
    for (let sz = 0; sz < sizes.length; sz++) {
      const component = createRefreshButtonComponent(sizes[sz], loading);
      component.x = currentX;
      component.y = currentY;
      currentX = currentX + component.width + componentGap;
      components.push(component);
    }
    currentY += rowGap;
  }

  // Combine into ComponentSet
  // @ts-ignore
  const componentSet = figma.combineAsVariants(components, page);
  componentSet.name = "RefreshButton";
  componentSet.description =
    "RefreshButton component with size and loading state";

  componentSet.layoutMode = "NONE";

  // Calculate content dimensions (add label column width)
  const contentWidth = componentSet.width + labelColumnWidth;
  const contentHeight = componentSet.height;

  // Create light mode section
  const lightSection = createModeSection(page, "RefreshButton", "light");
  lightSection.frame.resize(
    contentWidth + SECTION_PADDING * 2,
    contentHeight + SECTION_PADDING * 2,
  );

  // Create dark mode section
  const darkSection = createModeSection(page, "RefreshButton", "dark");
  darkSection.frame.resize(
    contentWidth + SECTION_PADDING * 2,
    contentHeight + SECTION_PADDING * 2,
  );

  // Move ComponentSet into light section frame
  lightSection.frame.appendChild(componentSet);
  componentSet.x = SECTION_PADDING + labelColumnWidth;
  componentSet.y = SECTION_PADDING;

  // Add row labels to light section
  for (let li = 0; li < rowLabels.length; li++) {
    const label = rowLabels[li];
    const labelNode = await createRowLabel(
      label.text,
      SECTION_PADDING,
      SECTION_PADDING + label.y + GRID_LAYOUT.labelVerticalOffset.mdLg,
    );
    lightSection.frame.appendChild(labelNode);
  }

  // Create instances for dark section
  // Note: component positions are relative to ComponentSet after combineAsVariants
  // We need to add labelColumnWidth to match the light section layout
  for (let i = 0; i < components.length; i++) {
    const comp = components[i];
    const instance = comp.createInstance();
    instance.x = comp.x + SECTION_PADDING + labelColumnWidth;
    instance.y = comp.y + SECTION_PADDING;
    darkSection.frame.appendChild(instance);
  }

  // Add row labels to dark section
  for (let di = 0; di < rowLabels.length; di++) {
    const darkLabel = rowLabels[di];
    const darkLabelNode = await createRowLabel(
      darkLabel.text,
      SECTION_PADDING,
      SECTION_PADDING + darkLabel.y + 10,
    );
    darkSection.frame.appendChild(darkLabelNode);
  }

  // Resize sections to fit content with padding
  const totalWidth = contentWidth + SECTION_PADDING * 2;
  const totalHeight = contentHeight + SECTION_PADDING * 2;

  lightSection.frame.resize(totalWidth, totalHeight);
  darkSection.frame.resize(totalWidth, totalHeight);

  // Add title inside each frame

  // Position sections side by side
  lightSection.frame.x = SECTION_LAYOUT.startX;
  lightSection.frame.y = startY;

  darkSection.frame.x =
    lightSection.frame.x + totalWidth + SECTION_LAYOUT.modeGap;
  darkSection.frame.y = startY;

  const totalComponents = sizes.length * loadingOptions.length;
  logComplete(
    "✅ Generated RefreshButton ComponentSet with " +
      totalComponents +
      " variants (light + dark)",
  );

  return startY + totalHeight + SECTION_GAP;
}

/**
 * Exports for tests
 */
export const REFRESH_BUTTON_SIZES_EXPORT = sizeProp.values;
