import { logComplete } from "../logger";
/**
 * LinkButton Component Generator
 *
 * Generates LinkButton ComponentSet in Figma with properties:
 * - variant: primary, secondary, ghost, destructive, secondary-destructive, outline
 * - size: xs, sm, base, lg
 * - hasIcon: true, false
 *
 * LinkButton is an anchor-styled button for navigation.
 * Default variant is "ghost" (unlike Button which defaults to "secondary").
 *
 * Uses real icons from the Icon Library page.
 *
 * @see packages/kumo/src/components/button/button.tsx
 */

import {
  createTextNode,
  bindFillToVariable,
  bindStrokeToVariable,
  getVariableByName,
  createModeSection,
  createRowLabel,
  createColumnHeaders,
  setWhiteTextColor,
  bindTextColorToVariable,
  
  SECTION_PADDING,
  SECTION_GAP,
  SECTION_TITLE,
  FALLBACK_VALUES,
  GRID_LAYOUT,
  SECTION_LAYOUT,
} from "./shared";
import { parseTailwindClasses } from "../parsers/tailwind-to-figma";
import { getButtonIcon, bindIconColor, DEFAULT_ICONS } 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 (LinkButton uses same variants as Button)
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;
};

/**
 * Create a single link button component
 */
async function createLinkButtonComponent(
  variant: string,
  size: string,
  hasIcon: boolean,
): Promise<ComponentNode> {
  const variantClasses = variantProp.classes[variant] || "";
  const sizeClasses = sizeProp.classes[size] || "";
  const variantDesc = variantProp.descriptions[variant] || "";
  const sizeDesc = sizeProp.descriptions[size] || "";

  // Parse variant styles and size styles
  const variantStyles = parseTailwindClasses(variantClasses);
  const sizeStyles = parseTailwindClasses(sizeClasses);

  // Create component
  const component = figma.createComponent();
  component.name =
    "variant=" + variant + ", size=" + size + ", hasIcon=" + hasIcon;
  component.description = variantDesc + ". " + sizeDesc;

  // Configure auto-layout
  component.layoutMode = "HORIZONTAL";
  component.primaryAxisAlignItems = "CENTER";
  component.counterAxisAlignItems = "CENTER";
  component.paddingLeft =
    sizeStyles.paddingX || FALLBACK_VALUES.padding.horizontal;
  component.paddingRight =
    sizeStyles.paddingX || FALLBACK_VALUES.padding.horizontal;
  component.paddingTop = 0;
  component.paddingBottom = 0;
  component.itemSpacing = sizeStyles.gap || FALLBACK_VALUES.gap.standard;
  component.primaryAxisSizingMode = "AUTO";
  component.counterAxisSizingMode = "FIXED";
  component.resize(100, sizeStyles.height || FALLBACK_VALUES.height.base);

  // Set corner radius from size classes
  const cornerRadius =
    sizeStyles.borderRadius !== undefined ? sizeStyles.borderRadius : 8;
  component.cornerRadius = cornerRadius;

  // Apply fill from variant
  if (variantStyles.fillVariable) {
    const fillVar = getVariableByName(variantStyles.fillVariable);
    if (fillVar) {
      bindFillToVariable(component, fillVar.id);
    }
  } else {
    // Transparent background (ghost)
    component.fills = [];
  }

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

  // Add icon if hasIcon is true - use real icon from Icon Library
  if (hasIcon) {
    const icon = getButtonIcon(DEFAULT_ICONS.arrowRight, size);

    // Bind icon color to match 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);
  }

  // Create text label
  const fontWeight = FALLBACK_VALUES.fontWeight.medium;
  const textNode = await createTextNode(
    "Link Button",
    sizeStyles.fontSize || FALLBACK_VALUES.fontSize,
    fontWeight,
  );
  textNode.name = "Label";

  // Apply text color from variant
  if (variantStyles.isWhiteText) {
    setWhiteTextColor(textNode);
  } else if (variantStyles.textVariable) {
    const textVar = getVariableByName(variantStyles.textVariable);
    if (textVar) {
      bindTextColorToVariable(textNode, textVar.id);
    }
  }

  component.appendChild(textNode);

  return component;
}

/**
 * Generate LinkButton 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 generateLinkButtonComponents(
  page: PageNode,
  startY: number,
): Promise<number> {
  if (startY === undefined) startY = 100;

  figma.currentPage = page;

  const variants = variantProp.values;
  const sizes = sizeProp.values;
  const hasIconOptions = [false, true];

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

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

  // Track column headers: { x, text }
  let columnHeaders: { x: number; text: string }[] = [];
  let columnHeadersRecorded = false;

  const componentGap = 20;
  const iconGap = 40;
  const rowGap = 80; // Vertical space between variant rows
  const headerRowHeight = 24; // Space for column headers at top
  const labelColumnWidth = 220; // Space for labels on the left

  for (let v = 0; v < variants.length; v++) {
    // Record row label (offset by header row)
    rowLabels.push({
      y: v * rowGap + headerRowHeight,
      text: "variant=" + variants[v],
    });

    for (let hi = 0; hi < hasIconOptions.length; hi++) {
      let currentX = labelColumnWidth + hi * (sizes.length * 140 + iconGap);
      for (let sz = 0; sz < sizes.length; sz++) {
        const component = await createLinkButtonComponent(
          variants[v],
          sizes[sz],
          hasIconOptions[hi],
        );
        component.x = currentX;
        component.y = v * rowGap + headerRowHeight;

        // Record column headers from first row
        if (!columnHeadersRecorded) {
          const headerText =
            "size=" + sizes[sz] + (hasIconOptions[hi] ? " +icon" : "");
          columnHeaders.push({ x: currentX, text: headerText });
        }

        currentX = currentX + component.width + componentGap;
        components.push(component);
      }
    }
    if (!columnHeadersRecorded) {
      columnHeadersRecorded = true;
    }
  }

  // Combine into ComponentSet
  // @ts-ignore
  const componentSet = figma.combineAsVariants(components, page);
  componentSet.name = "LinkButton";
  componentSet.description =
    "LinkButton component for navigation with variant, size, and icon options";

  componentSet.layoutMode = "NONE";

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

  // Add contentYOffset for title space inside frame
  const contentYOffset = SECTION_TITLE.height;

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

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

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

  // Add section titles inside frames

  // Add column headers to light section
  await createColumnHeaders(
    columnHeaders.map(function (h) {
      return { x: h.x + SECTION_PADDING, text: h.text };
    }),
    SECTION_PADDING + contentYOffset,
    lightSection.frame,
  );

  // 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 +
        contentYOffset +
        label.y +
        GRID_LAYOUT.labelVerticalOffset.lg,
    );
    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 + headerRowHeight + contentYOffset;
    darkSection.frame.appendChild(instance);
  }

  // Add column headers to dark section
  await createColumnHeaders(
    columnHeaders.map(function (h) {
      return { x: h.x + SECTION_PADDING, text: h.text };
    }),
    SECTION_PADDING + contentYOffset,
    darkSection.frame,
  );

  // 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 +
        contentYOffset +
        darkLabel.y +
        GRID_LAYOUT.labelVerticalOffset.lg,
    );
    darkSection.frame.appendChild(darkLabelNode);
  }

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

  lightSection.section.resizeWithoutConstraints(totalWidth, totalHeight);
  darkSection.section.resizeWithoutConstraints(totalWidth, totalHeight);

  // 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 =
    variants.length * sizes.length * hasIconOptions.length;
  logComplete(
    "✅ Generated LinkButton ComponentSet with " +
      totalComponents +
      " variants (light + dark)",
  );

  return startY + totalHeight + SECTION_GAP;
}

/**
 * Testable exports for link-button.test.ts
 */

/**
 * Get variant configuration from registry
 */
export function getLinkButtonVariantConfig() {
  return {
    values: variantProp.values,
    classes: variantProp.classes,
    descriptions: variantProp.descriptions,
    default: variantProp.default,
  };
}

/**
 * Get size configuration from registry
 */
export function getLinkButtonSizeConfig() {
  return {
    values: sizeProp.values,
    classes: sizeProp.classes,
    descriptions: sizeProp.descriptions,
    default: sizeProp.default,
  };
}

/**
 * Get parsed styles for a specific variant
 */
export function getLinkButtonParsedVariantStyles(variant: string) {
  const classes = variantProp.classes[variant] || "";
  return {
    variant: variant,
    classes: classes,
    description: variantProp.descriptions[variant] || "",
    parsed: parseTailwindClasses(classes),
  };
}

/**
 * Get parsed styles for a specific size
 */
export function getLinkButtonParsedSizeStyles(size: string) {
  const classes = sizeProp.classes[size] || "";
  return {
    size: size,
    classes: classes,
    description: sizeProp.descriptions[size] || "",
    parsed: parseTailwindClasses(classes),
  };
}

/**
 * Get layout data for a link button with specific variant, size, and icon state
 */
export function getLinkButtonLayoutData(
  variant: string,
  size: string,
  hasIcon: boolean,
) {
  const variantClasses = variantProp.classes[variant] || "";
  const sizeClasses = sizeProp.classes[size] || "";

  const variantStyles = parseTailwindClasses(variantClasses);
  const sizeStyles = parseTailwindClasses(sizeClasses);

  return {
    variant: variant,
    size: size,
    hasIcon: hasIcon,
    variantDescription: variantProp.descriptions[variant] || "",
    sizeDescription: sizeProp.descriptions[size] || "",
    layout: {
      paddingX: sizeStyles.paddingX || FALLBACK_VALUES.padding.horizontal,
      height: sizeStyles.height || FALLBACK_VALUES.height.base,
      gap: sizeStyles.gap || FALLBACK_VALUES.gap.standard,
      cornerRadius:
        sizeStyles.borderRadius !== undefined
          ? sizeStyles.borderRadius
          : FALLBACK_VALUES.borderRadius.large,
      fontSize: sizeStyles.fontSize || FALLBACK_VALUES.fontSize,
    },
    fill: {
      hasBackground: !!variantStyles.fillVariable,
      variable: variantStyles.fillVariable || null,
    },
    stroke: {
      hasBorder: variantStyles.hasBorder || false,
      variable: variantStyles.strokeVariable || null,
    },
    text: {
      isWhiteText: variantStyles.isWhiteText || false,
      variable: variantStyles.textVariable || null,
    },
  };
}

/**
 * Get complete intermediate data for all link button variants
 */
export function getAllLinkButtonVariantData() {
  const variantConfig = getLinkButtonVariantConfig();
  const sizeConfig = getLinkButtonSizeConfig();

  return {
    variantConfig: variantConfig,
    sizeConfig: sizeConfig,
    variants: variantConfig.values.map(function (variant) {
      return getLinkButtonParsedVariantStyles(variant);
    }),
    sizes: sizeConfig.values.map(function (size) {
      return getLinkButtonParsedSizeStyles(size);
    }),
    hasIconOptions: [false, true],
    exampleLayouts: [
      // Primary + base + no icon (typical)
      getLinkButtonLayoutData("primary", "base", false),
      // Ghost + base + with icon (typical for link buttons)
      getLinkButtonLayoutData("ghost", "base", true),
      // Destructive + lg + with icon
      getLinkButtonLayoutData("destructive", "lg", true),
    ],
  };
}

// Legacy exports (kept for backwards compatibility if needed)
export const LINK_BUTTON_VARIANTS_EXPORT = variantProp.values;
export const LINK_BUTTON_SIZES_EXPORT = sizeProp.values;
