import { expect, test, vi } from "vitest";
import { newProject } from "./newProject.js";
import { loadProjectInMemory } from "./loadProjectInMemory.js";
import { PluginImportError } from "../plugin/errors.js";
import { validate } from "uuid";
test("it should persist changes of bundles, messages, and variants to lix ", async () => {
    const file1 = await newProject();
    const project1 = await loadProjectInMemory({ blob: file1 });
    const bundle = await project1.db
        .insertInto("bundle")
        .defaultValues()
        .returning("id")
        .executeTakeFirstOrThrow();
    const message = await project1.db
        .insertInto("message")
        .values({
        bundleId: bundle.id,
        locale: "en",
    })
        .returning("id")
        .executeTakeFirstOrThrow();
    await project1.db
        .insertInto("variant")
        .values({
        messageId: message.id,
    })
        .execute();
    const file1AfterUpdates = await project1.toBlob();
    await project1.close();
    const project2 = await loadProjectInMemory({ blob: file1AfterUpdates });
    const bundles = await project2.db.selectFrom("bundle").select("id").execute();
    const messages = await project2.db
        .selectFrom("message")
        .select("id")
        .execute();
    const variants = await project2.db
        .selectFrom("variant")
        .select("id")
        .execute();
    expect(bundles.length).toBe(1);
    expect(messages.length).toBe(1);
    expect(variants.length).toBe(1);
});
test("get and set settings", async () => {
    const project = await loadProjectInMemory({ blob: await newProject() });
    const settings = await project.settings.get();
    expect(settings["plugin.key"]).toBeUndefined();
    const copied = structuredClone(settings);
    copied["plugin.key"] = { test: "value" };
    await project.settings.set(copied);
    const updatedSettings = await project.settings.get();
    expect(updatedSettings["plugin.key"]).toEqual({ test: "value" });
});
test("it should set sourceLanguageTag and languageTags if non-existent to make v1 plugins work", async () => {
    const project = await loadProjectInMemory({
        blob: await newProject({
            settings: {
                baseLocale: "en",
                locales: ["en", "de"],
            },
        }),
    });
    const settings = await project.settings.get();
    expect(settings.baseLocale).toBe("en");
    expect(settings.sourceLanguageTag).toBe("en");
    expect(settings.languageTags).toEqual(["en", "de"]);
    expect(settings.locales).toEqual(["en", "de"]);
});
test("providing plugins should work", async () => {
    const project = await loadProjectInMemory({
        blob: await newProject({
            settings: {
                baseLocale: "en",
                locales: ["en"],
                modules: [],
            },
        }),
        providePlugins: [{ key: "my-provided-plugin" }],
    });
    const plugins = await project.plugins.get();
    const errors = await project.errors.get();
    expect(plugins.length).toBe(1);
    expect(plugins[0]?.key).toBe("my-provided-plugin");
    expect(errors.length).toBe(0);
});
test("if a project has no id, it should be generated", async () => {
    const project = await loadProjectInMemory({ blob: await newProject() });
    await project.lix.db
        .deleteFrom("file")
        .where("path", "=", "/project_id")
        .execute();
    const blob = await project.toBlob();
    const project2 = await loadProjectInMemory({ blob });
    const id = await project2.id.get();
    expect(id).toBeDefined();
    expect(validate(id)).toBe(true);
});
test("providing an account should work", async () => {
    const mockAccount = {
        id: "mock-account-id",
        name: "peter",
    };
    const project = await loadProjectInMemory({
        blob: await newProject(),
        account: mockAccount,
    });
    const activeAccount = await project.lix.db
        .selectFrom("active_account")
        .selectAll()
        .execute();
    expect(activeAccount).toEqual([mockAccount]);
});
// test("subscribing to errors should work", async () => {
// 	const project = await loadProjectInMemory({ blob: await newProject() });
// 	expect(await project.errors.get()).toEqual([]);
// 	let errorsFromSub: readonly Error[] = [];
// 	project.errors.subscribe((value) => {
// 		errorsFromSub = value;
// 	});
// 	await project.lix.db
// 		.updateTable("file")
// 		.where("path", "=", "/settings.json")
// 		.set({
// 			data: new TextEncoder().encode(
// 				JSON.stringify({
// 					baseLocale: "en",
// 					locales: ["en"],
// 					modules: ["invalid-module.js"],
// 				})
// 			),
// 		})
// 		.execute();
// 	const errors = await project.errors.get();
// 	expect(errors.length).toBe(1);
// 	expect(errorsFromSub.length).toBe(1);
// 	expect(errorsFromSub).toStrictEqual(errors);
// });
test("closing a project should not lead to a throw", async () => {
    const project = await loadProjectInMemory({ blob: await newProject() });
    await project.close();
    // capture async throws
    await new Promise((resolve) => setTimeout(resolve, 250));
});
test("project.errors.get() returns errors for modules that couldn't be imported via http", async () => {
    // Mock global fetch to simulate a network error
    global.fetch = vi.fn().mockRejectedValue(new Error("Network error"));
    const project = await loadProjectInMemory({
        blob: await newProject({
            settings: {
                baseLocale: "en",
                locales: ["en", "de", "fr"],
                modules: ["https://example.com/non-existent-paraglide-plugin.js"],
            },
        }),
    });
    // Get the errors from project
    const errors = await project.errors.get();
    // Verify there's at least one error
    expect(errors.length).toBeGreaterThan(0);
    // Find the error related to the HTTP import
    const httpImportError = errors.find((error) => error instanceof PluginImportError &&
        error.plugin === "https://example.com/non-existent-paraglide-plugin.js");
    // Verify the error exists and contains appropriate information
    expect(httpImportError).toBeDefined();
    expect(httpImportError?.message).toContain("non-existent-paraglide-plugin.js");
    expect(httpImportError?.message).toContain("Couldn't import");
    await project.close();
});
//# sourceMappingURL=loadProject.test.js.map