import {
  definePluginEntry,
  type OpenClawPluginApi,
} from "openclaw/plugin-sdk/plugin-entry";
import { clampRequestedLimit, resolvePluginConfig } from "./config.js";
import { loadCpvEntries, loadSynonyms } from "./dataset.js";
import { buildSearchPayload, formatPayloadAsText } from "./format.js";
import { searchEntries } from "./search.js";
import type { SearchParams } from "./types.js";

const toolParameters = {
  type: "object",
  additionalProperties: false,
  properties: {
    query: {
      type: "string",
      description:
        "Fragment kodu CPV lub opis tekstowy do wyszukania. Obsługuje synonimy.",
    },
    limit: {
      type: "integer",
      minimum: 1,
      maximum: 50,
      description: "Maksymalna liczba wyników do zwrócenia.",
    },
  },
  required: ["query"],
} as const;

export default definePluginEntry({
  id: "wyszukiwara-przetargow",
  name: "Wyszukiwarka przetargów",
  description:
    "Search CPV tender categories with synonym expansion. Tool and /przetargi command for OpenClaw.",
  register(api: OpenClawPluginApi) {
    const config = resolvePluginConfig(api.pluginConfig);

    api.registerTool({
      name: "search_przetargi",
      label: "Wyszukiwarka przetargów",
      description:
        "Wyszukuje kategorie przetargów CPV po kodzie lub opisie z rozszerzeniem synonimów.",
      parameters: toolParameters,
      async execute(_toolCallId: string, params: SearchParams) {
        const payload = await runSearch(params, config, api);
        return {
          content: [
            {
              type: "text" as const,
              text: formatPayloadAsText(payload),
            },
          ],
          details: payload,
        };
      },
    });

    api.registerCommand({
      name: "przetargi",
      description: "Wyszukaj kategorie przetargów CPV po kodzie lub opisie.",
      acceptsArgs: true,
      handler: async (ctx: { args?: string }) => {
        const query = ctx.args?.trim() ?? "";

        if (!query) {
          return {
            text: "Użycie: /przetargi <zapytanie>\nPrzykład: /przetargi usługi sprzątania\nPrzykład: /przetargi 90910000",
          };
        }

        const payload = await runSearch({ query }, config, api);
        return { text: formatPayloadAsText(payload) };
      },
    });

    api.logger.info?.(
      "[wyszukiwara-przetargow] Registered search_przetargi tool and /przetargi command",
    );
  },
});

async function runSearch(
  params: SearchParams,
  config: ReturnType<typeof resolvePluginConfig>,
  api: OpenClawPluginApi,
) {
  const query = params.query?.trim() ?? "";

  if (!query) {
    throw new Error("query is required");
  }

  const limit = clampRequestedLimit(params.limit, config);
  const [entries, synonymMap] = await Promise.all([
    loadCpvEntries(),
    loadSynonyms(),
  ]);
  const matches = searchEntries(entries, query, limit, synonymMap);

  api.logger.debug?.(
    `[wyszukiwara-przetargow] Search query: ${query}; returned: ${matches.length}`,
  );

  return buildSearchPayload(
    query,
    matches.map((m) => ({
      code: m.code,
      text: m.text,
      matchType: m.matchType,
      synonymTerm: m.synonymTerm,
    })),
  );
}
