import { describe, expect, it } from "vitest";
import { extractUcfsForSfc } from "../sfc-adapter.js";

describe("extractUcfsForSfc", () => {
  it("extracts Vue SFC props, root elements, slots, classes, and styles", () => {
    const [ucf] = extractUcfsForSfc({
      sourceCommit: "sha",
      sources: [
        {
          filePath: "src/components/BaseButton.vue",
          source: [
            "<template>",
            '  <button class="bg-blue-600 rounded" role="button" aria-label="Save">',
            '    <slot name="icon" />',
            "  </button>",
            "</template>",
            "<script setup lang=\"ts\">",
            "const props = defineProps<{",
            "  variant?: 'primary' | 'secondary';",
            "  disabled: boolean;",
            "}>();",
            "const count = ref(0);",
            "</script>",
            "<style scoped>.button { color: red; }</style>",
          ].join("\n"),
        },
      ],
    });

    expect(ucf).toMatchObject({
      filePath: "src/components/BaseButton.vue",
      componentName: "BaseButton",
      framework: "vue",
      definitionKind: "sfc",
      rootElements: [
        expect.objectContaining({
          tag: "button",
          attrs: expect.objectContaining({ role: "button" }),
          loc: expect.objectContaining({ line: 2 }),
        }),
      ],
      ariaRoles: ["button"],
      ariaAttributes: { "aria-label": "Save" },
      slots: [{ name: "icon", scoped: false }],
      hasInternalState: true,
      styleSystem: "tailwind",
      classNamesUsed: ["bg-blue-600", "rounded"],
    });
    expect(ucf?.props).toEqual([
      expect.objectContaining({
        name: "variant",
        loc: expect.objectContaining({ line: 8 }),
        optional: true,
        isUnion: true,
        unionMembers: ["'primary'", "'secondary'"],
      }),
      expect.objectContaining({
        name: "disabled",
        optional: false,
        typeText: "boolean",
      }),
    ]);
  });

  it("extracts Svelte exported props and slots", () => {
    const [ucf] = extractUcfsForSfc({
      sourceCommit: "sha",
      sources: [
        {
          filePath: "src/Card.svelte",
          source: [
            "<script lang=\"ts\">",
            "  import { onMount } from 'svelte';",
            "  export let tone: 'info' | 'danger' = 'info';",
            "  export let disabled: boolean;",
            "  let expanded = false;",
            "  onMount(() => {});",
            "</script>",
            "<article class=\"card\"><slot /></article>",
          ].join("\n"),
        },
      ],
    });

    expect(ucf).toMatchObject({
      filePath: "src/Card.svelte",
      componentName: "Card",
      framework: "svelte",
      rootElements: [expect.objectContaining({ tag: "article" })],
      slots: [{ name: "default", scoped: false }],
      hasInternalState: true,
      hasEffects: true,
      classNamesUsed: ["card"],
    });
    expect(ucf?.props).toEqual([
      expect.objectContaining({
        name: "tone",
        optional: true,
        hasDefault: true,
        unionMembers: ["'info'", "'danger'"],
      }),
      expect.objectContaining({
        name: "disabled",
        optional: false,
        typeText: "boolean",
      }),
    ]);
  });
});
