import type { PluginInput } from '@opencode-ai/plugin';

export const JSON_ERROR_TOOL_EXCLUDE_LIST = [
  'bash',
  'read',
  'glob',
  'webfetch',
  'grep_app_searchgithub',
  'websearch_web_search_exa',
] as const;

export const JSON_ERROR_PATTERNS = [
  /json parse error/i,
  /failed to parse json/i,
  /invalid json/i,
  /malformed json/i,
  /unexpected end of json input/i,
  /syntaxerror:\s*unexpected token.*json/i,
  /json[^\n]*expected '\}'/i,
  /json[^\n]*unexpected eof/i,
] as const;

const JSON_ERROR_REMINDER_MARKER =
  '[JSON PARSE ERROR - IMMEDIATE ACTION REQUIRED]';
const JSON_ERROR_EXCLUDED_TOOLS = new Set<string>(JSON_ERROR_TOOL_EXCLUDE_LIST);

export const JSON_ERROR_REMINDER = `
[JSON PARSE ERROR - IMMEDIATE ACTION REQUIRED]

You sent invalid JSON arguments. The system could not parse your tool call.
STOP and do this NOW:

1. LOOK at the error message above to see what was expected vs what you sent.
2. CORRECT your JSON syntax (missing braces, unescaped quotes, trailing commas, etc).
3. RETRY the tool call with valid JSON.

DO NOT repeat the exact same invalid call.
`;

interface ToolExecuteAfterInput {
  tool: string;
  sessionID: string;
  callID: string;
}

interface ToolExecuteAfterOutput {
  title: string;
  output: unknown;
  metadata: unknown;
}

export function createJsonErrorRecoveryHook(_ctx: PluginInput) {
  return {
    'tool.execute.after': async (
      input: ToolExecuteAfterInput,
      output: ToolExecuteAfterOutput,
    ): Promise<void> => {
      if (JSON_ERROR_EXCLUDED_TOOLS.has(input.tool.toLowerCase())) return;
      if (typeof output.output !== 'string') return;
      if (output.output.includes(JSON_ERROR_REMINDER_MARKER)) return;

      const outputText = output.output;

      const hasJsonError = JSON_ERROR_PATTERNS.some((pattern) =>
        pattern.test(outputText),
      );

      if (hasJsonError) {
        output.output += `\n${JSON_ERROR_REMINDER}`;
      }
    },
  };
}
