#!/usr/bin/env node
/* eslint-env node */
/* global __dirname, console, process */

const fs = require("node:fs");
const path = require("node:path");
const Module = require("node:module");
const ts = require("typescript");

const srcRoot = path.join(path.resolve(__dirname, ".."), "src");

const registerTsCompiler = extension => {
  require.extensions[extension] = (module, filename) => {
    const source = fs.readFileSync(filename, "utf8");
    const { outputText } = ts.transpileModule(source, {
      compilerOptions: {
        module: ts.ModuleKind.CommonJS,
        target: ts.ScriptTarget.ES2020,
        jsx: ts.JsxEmit.ReactJSX,
        esModuleInterop: true,
        moduleResolution: ts.ModuleResolutionKind.NodeNext,
        resolveJsonModule: true,
        skipLibCheck: true,
      },
      fileName: filename,
    });

    module._compile(outputText, filename);
  };
};

registerTsCompiler(".ts");
registerTsCompiler(".tsx");

const originalResolveFilename = Module._resolveFilename;
Module._resolveFilename = function resolve(request, parent, isMain, options) {
  if (request === "@/core/api") {
    const stubPath = path.resolve(__dirname, "stubs/core-api.ts");
    return originalResolveFilename.call(this, stubPath, parent, isMain, options);
  }

  if (request.startsWith("@/")) {
    const resolved = path.resolve(srcRoot, request.slice(2));
    return originalResolveFilename.call(this, resolved, parent, isMain, options);
  }

  return originalResolveFilename.call(this, request, parent, isMain, options);
};

class LocalStorageMock {
  constructor() {
    this._store = new Map();
  }

  clear() {
    this._store.clear();
  }

  getItem(key) {
    return this._store.has(key) ? this._store.get(key) : null;
  }

  key(index) {
    return Array.from(this._store.keys())[index] ?? null;
  }

  removeItem(key) {
    this._store.delete(key);
  }

  setItem(key, value) {
    this._store.set(key, String(value));
  }

  get length() {
    return this._store.size;
  }
}

global.localStorage = new LocalStorageMock();

const coreApiStub = require("./stubs/core-api.ts");
coreApiStub.postCalls.length = 0;

const { useAuthStore } = require("../src/features/auth/services/auth.store.ts");

(async () => {
  try {
    const payload = { email: "tester@example.com" };
    await useAuthStore.getState().requestPasswordReset(payload);

    if (coreApiStub.postCalls.length !== 1) {
      throw new Error(`Expected 1 POST call, received ${coreApiStub.postCalls.length}`);
    }

    const [endpoint, options] = coreApiStub.postCalls[0];
    if (endpoint !== "/auth/request-password-reset") {
      throw new Error(
        `Expected endpoint "/auth/request-password-reset" but received "${endpoint}"`
      );
    }

    if (!options || typeof options !== "object") {
      throw new Error("Password reset request did not include options payload");
    }

    const body = options.body;
    if (!body || typeof body !== "object") {
      throw new Error("Password reset request did not include a body");
    }

    if (body.email !== payload.email) {
      throw new Error(
        `Expected request body email to be "${payload.email}" but received "${body.email}"`
      );
    }

    console.log("Password reset request forwarded correctly:", { endpoint, body });
  } catch (error) {
    console.error("Password reset request verification failed:", error);
    process.exitCode = 1;
  }
})();
