import { describe, it, expect } from "vitest";
import { generateSwift } from "../../src/core/generator.js";
import type { IRIntent } from "../../src/core/types.js";

const SIMPLE_INTENT: IRIntent = {
  name: "SendMessage",
  title: "Send Message",
  description: "Sends a message to a contact",
  domain: "messaging",
  parameters: [
    {
      name: "recipient",
      type: { kind: "primitive", value: "string" },
      title: "Recipient",
      description: "Who to send the message to",
      isOptional: false,
    },
    {
      name: "body",
      type: { kind: "primitive", value: "string" },
      title: "Body",
      description: "The message content",
      isOptional: false,
    },
  ],
  returnType: { kind: "primitive", value: "string" },
  sourceFile: "test.ts",
};

const NO_PARAMS_INTENT: IRIntent = {
  name: "GetStatus",
  title: "Get Status",
  description: "Gets current status",
  parameters: [],
  returnType: { kind: "primitive", value: "string" },
  sourceFile: "test.ts",
};

const OPTIONAL_PARAMS_INTENT: IRIntent = {
  name: "CreateReminder",
  title: "Create Reminder",
  description: "Creates a reminder",
  parameters: [
    {
      name: "title",
      type: { kind: "primitive", value: "string" },
      title: "Title",
      description: "Reminder title",
      isOptional: false,
    },
    {
      name: "notes",
      type: { kind: "optional", innerType: { kind: "primitive", value: "string" } },
      title: "Notes",
      description: "Optional notes",
      isOptional: true,
    },
    {
      name: "priority",
      type: { kind: "primitive", value: "int" },
      title: "Priority",
      description: "Priority level",
      isOptional: false,
      defaultValue: 1,
    },
  ],
  returnType: { kind: "primitive", value: "string" },
  sourceFile: "test.ts",
};

describe("generateSwift", () => {
  it("generates correct Swift for a simple intent", () => {
    const swift = generateSwift(SIMPLE_INTENT);
    expect(swift).toMatchSnapshot();
  });

  it("generates correct Swift for an intent with no parameters", () => {
    const swift = generateSwift(NO_PARAMS_INTENT);
    expect(swift).toMatchSnapshot();
  });

  it("generates correct Swift for optional and default params", () => {
    const swift = generateSwift(OPTIONAL_PARAMS_INTENT);
    expect(swift).toMatchSnapshot();
  });

  it("includes the Axint compiler output header comment", () => {
    const swift = generateSwift(SIMPLE_INTENT);
    expect(swift).toContain("Axint compiler output");
    expect(swift).toContain("Edit freely");
  });

  it("includes import AppIntents", () => {
    const swift = generateSwift(SIMPLE_INTENT);
    expect(swift).toContain("import AppIntents");
  });

  it("generates AppIntent conformance", () => {
    const swift = generateSwift(SIMPLE_INTENT);
    expect(swift).toContain("struct SendMessageIntent: AppIntent");
  });

  it("generates static title and description", () => {
    const swift = generateSwift(SIMPLE_INTENT);
    expect(swift).toContain('static var title: LocalizedStringResource = "Send Message"');
    expect(swift).toContain("static var description: IntentDescription");
    expect(swift).toContain('IntentDescription("Sends a message to a contact")');
  });

  it("generates @Parameter decorators", () => {
    const swift = generateSwift(SIMPLE_INTENT);
    expect(swift).toContain('@Parameter(title: "Recipient"');
    expect(swift).toContain("var recipient: String");
  });

  it("generates perform() function with return-value-aware signature", () => {
    const swift = generateSwift(SIMPLE_INTENT);
    expect(swift).toContain(
      "func perform() async throws -> some IntentResult & ReturnsValue<String>"
    );
    expect(swift).toContain('return .result(value: "")');
  });

  it("handles default values in Swift output", () => {
    const swift = generateSwift(OPTIONAL_PARAMS_INTENT);
    expect(swift).toContain("var priority: Int = 1");
  });

  it("handles optional types with ? suffix", () => {
    const swift = generateSwift(OPTIONAL_PARAMS_INTENT);
    expect(swift).toContain("var notes: String?");
  });
});
