import { createElement } from "react";
import { createRoot } from "react-dom/client";
import type {
  PluginAssetPageOptions,
  PluginAssetReadOptions,
  PluginPropertyBatchOptions,
  PluginPropertyValueLookupRequest,
} from "@thortiq/plugin-api";
import type {
  SandboxBootstrapCallbackContext,
  SandboxControllerApiV1,
} from "@thortiq/plugin-sdk/sandbox";
import {
  runCsvImportWorkflow,
  type CsvRunReason,
  type CsvWorkflowStatus,
} from "./workflow.js";

const JOB = Object.freeze({
  id: "import-csv",
  title: "Preview CSV property import",
  triggers: Object.freeze([
    Object.freeze({ type: "command" as const, command: "import-now" }),
    Object.freeze({ type: "asset-change" as const, pathSetting: "csvPath" }),
  ]),
  concurrency: "skip-if-running" as const,
});

const COMMAND = Object.freeze({
  id: "import-now",
  title: "Preview CSV property import",
});

function withoutSignal<T>(
  value: T,
): Omit<T, "signal"> {
  const { signal: _signal, ...rest } = value as T & {
    readonly signal?: AbortSignal;
  };
  return rest as Omit<T, "signal">;
}

export function runCsvFromSandbox(
  api: SandboxControllerApiV1,
  reason: CsvRunReason,
  signal: AbortSignal,
): Promise<CsvWorkflowStatus> {
  return runCsvImportWorkflow({
    assets: {
      list: (options: PluginAssetPageOptions = {}) =>
        api.assets.list(withoutSignal(options)),
      readBytes: (path: string, options: PluginAssetReadOptions) =>
        api.assets.readBytes(path, withoutSignal(options)),
    },
    metadata: {
      findByPropertyValues: (
        request: PluginPropertyValueLookupRequest,
      ) => api.metadata.findByPropertyValues(withoutSignal(request)),
    },
    notes: {
      updatePropertiesBatch: (
        operations,
        options: PluginPropertyBatchOptions,
      ) => api.notes.updatePropertiesBatch(
        operations,
        withoutSignal(options),
      ),
    },
    settings: {
      get: key => api.settings.get(key),
    },
    statusStorage: {
      set: (key, value) => api.storage.local.set(key, value),
    },
    now: () => "2026-01-01T00:00:00.000Z",
    confirmPreview: preview => api.dialogs.confirm({
      title: "Apply CSV property preview?",
      message: preview.message,
      confirmLabel: "Apply updates",
      cancelLabel: "Keep preview only",
    }),
  }, {
    reason,
    signal,
    scheduledAutoApplyConfirmed: false,
  });
}

export async function activate(
  context: SandboxBootstrapCallbackContext,
): Promise<() => void> {
  if (context.kind === "controller") {
    const command = await context.api.commands.register(COMMAND, async () => {});
    const job = await context.api.jobs.register(JOB, async jobContext => {
      await runCsvFromSandbox(context.api, jobContext.reason, jobContext.signal);
    });
    return async () => {
      await job.destroy();
      await command.destroy();
    };
  }

  const container = document.querySelector<HTMLElement>("#root");
  if (!container) throw new Error("The sandbox page root is missing.");
  const root = createRoot(container);
  const run = () => {
    void context.api.jobs.run("import-csv");
  };
  root.render(createElement(
    "main",
    { className: "csv-sandbox-import-panel" },
    createElement("h2", null, "CSV property import"),
    createElement(
      "p",
      null,
      "The host reads one indexed CSV and confirms a conditional preview before writing.",
    ),
    createElement("button", { type: "button", onClick: run }, "Preview import"),
  ));
  await context.api.workspace.setViewTitle("CSV property import");
  return () => root.unmount();
}
