/**
 * jscodeshift transform for fix-login-form-action.
 *
 * Replaces every JSXAttribute named `action` whose value is the string
 * "/api/auth/signin/credentials" with a no-op arrow function expression
 * (`action={() => {}}`), and attaches an explanatory leading comment block.
 *
 * Returns null (no source change) when no matching attribute is found.
 */
module.exports = function transform(fileInfo, api) {
  const j = api.jscodeshift;
  const root = j(fileInfo.source);
  let changed = false;

  root.find(j.JSXAttribute, { name: { name: 'action' } }).forEach((p) => {
    const v = p.node.value;
    if (!v) return;

    // String values can show up as either Literal or StringLiteral depending
    // on the parser version. Match both.
    const isString = v.type === 'Literal' || v.type === 'StringLiteral';
    if (!isString || v.value !== '/api/auth/signin/credentials') return;

    const arrow = j.arrowFunctionExpression([], j.blockStatement([]));
    p.node.value = j.jsxExpressionContainer(arrow);

    // Leading block comment explains why the action is a no-op. Attaching
    // to the attribute keeps the comment adjacent in the printed output.
    const comment = j.commentBlock(
      ' React 19 belt-and-suspenders: passing a function to `action` makes\n' +
        '         React itself call preventDefault on the native submit before any\n' +
        '         listener runs, so a hydration race cannot leak credentials into\n' +
        '         the URL bar. onSubmit still drives the actual signIn flow. ',
      true,
      false
    );
    p.node.comments = [comment];

    changed = true;
  });

  return changed ? root.toSource({ quote: 'single' }) : null;
};
