import { delay } from "octagonal-wheels/promises";
import { __onMissingTranslation } from "@/common/translation";
import { AbstractObsidianModule } from "@/modules/AbstractObsidianModule.ts";
import { LOG_LEVEL_VERBOSE } from "octagonal-wheels/common/logger";
import { writable } from "svelte/store";
import type { FilePathWithPrefix } from "@vrtmrz/livesync-commonlib/compat/common/types";
import type { LiveSyncCore } from "@/main.ts";
export class ModuleDev extends AbstractObsidianModule {
    _everyOnloadStart(): Promise<boolean> {
        __onMissingTranslation(() => {});
        return Promise.resolve(true);
    }
    async onMissingTranslation(key: string): Promise<void> {
        const now = new Date();
        const filename = `missing-translation-`;
        const time = now.toISOString().split("T")[0];
        const outFile = `${filename}${time}.jsonl`;
        const piece = JSON.stringify({
            [key]: {},
        });
        const writePiece = piece.substring(1, piece.length - 1) + ",";
        try {
            await this.core.storageAccess.ensureDir(this.app.vault.configDir + "/ls-debug/");
            await this.core.storageAccess.appendHiddenFile(
                this.app.vault.configDir + "/ls-debug/" + outFile,
                writePiece + "\n"
            );
        } catch (ex) {
            this._log(`Could not write ${outFile}`, LOG_LEVEL_VERBOSE);
            this._log(`Missing translation: ${writePiece}`, LOG_LEVEL_VERBOSE);
            this._log(ex, LOG_LEVEL_VERBOSE);
        }
    }

    async _everyOnLayoutReady(): Promise<boolean> {
        if (!this.settings.enableDebugTools) return Promise.resolve(true);
        this.addCommand({
            id: "test-create-conflict",
            name: "Create conflict",
            callback: async () => {
                const filename = "test-create-conflict.md";
                const content = `# Test create conflict\n\n`;
                const w = await this.core.databaseFileAccess.store({
                    name: filename,
                    path: filename as FilePathWithPrefix,
                    body: new Blob([content], { type: "text/markdown" }),
                    stat: {
                        ctime: new Date().getTime(),
                        mtime: new Date().getTime(),
                        size: content.length,
                        type: "file",
                    },
                });
                if (w) {
                    const id = await this.services.path.path2id(filename as FilePathWithPrefix);
                    const f = await this.core.localDatabase.getRaw(id);
                    this._log(f, LOG_LEVEL_VERBOSE);
                    this._log(f._rev, LOG_LEVEL_VERBOSE);
                    const revConflict = f._rev.split("-")[0] + "-" + (parseInt(f._rev.split("-")[1]) + 1).toString();
                    this._log(await this.core.localDatabase.bulkDocsRaw([f], { new_edits: false }), LOG_LEVEL_VERBOSE);
                    this._log(
                        await this.core.localDatabase.bulkDocsRaw([{ ...f, _rev: revConflict }], { new_edits: false }),
                        LOG_LEVEL_VERBOSE
                    );
                }
            },
        });
        await delay(1);
        return true;
    }
    testResults = writable<[boolean, string, string][]>([]);
    // testResults: string[] = [];

    private _addTestResult(name: string, key: string, result: boolean, summary?: string, message?: string): void {
        const logLine = `${name}: ${key} ${summary ?? ""}`;
        this.testResults.update((results) => {
            results.push([result, logLine, message ?? ""]);
            return results;
        });
    }
    private _everyModuleTest(): Promise<boolean> {
        if (!this.settings.enableDebugTools) return Promise.resolve(true);
        // this.core.$$addTestResult("DevModule", "Test", true);
        // return Promise.resolve(true);
        // this.addTestResult("Test of test1", true, "Just OK", "This is a test of test");
        // this.addTestResult("Test of test2", true, "Just OK?");
        // this.addTestResult("Test of test3", true);
        return this.testDone();
    }
    override onBindFunction(core: LiveSyncCore, services: typeof core.services): void {
        services.appLifecycle.onLayoutReady.addHandler(this._everyOnLayoutReady.bind(this));
        services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this));
        services.test.test.addHandler(this._everyModuleTest.bind(this));
        services.test.addTestResult.setHandler(this._addTestResult.bind(this));
    }
}
