/**
 * jscodeshift transform for fix-template-currenturl.
 *
 * Matches:
 *   const currentUrl = (URL | process.env.NEXT_PUBLIC_URL) + pathname + searchParams;
 *
 * Replaces the right-hand side with the template literal
 *   `${X}${pathname}`
 *
 * Only runs against files whose path ends in `/app/**\/template.tsx`. Returns
 * null (no source change) when no match is found in the file or the
 * declarator already has a non-binary initializer.
 */

function isUrlBase(node) {
  if (!node) return false;
  if (node.type === 'Identifier' && node.name === 'URL') return true;
  if (
    node.type === 'MemberExpression' &&
    node.object &&
    node.object.type === 'MemberExpression' &&
    node.object.object &&
    node.object.object.type === 'Identifier' &&
    node.object.object.name === 'process' &&
    node.object.property &&
    node.object.property.type === 'Identifier' &&
    node.object.property.name === 'env' &&
    node.property &&
    node.property.type === 'Identifier' &&
    node.property.name === 'NEXT_PUBLIC_URL'
  ) {
    return true;
  }
  return false;
}

function flattenAdd(node, out) {
  if (
    node &&
    node.type === 'BinaryExpression' &&
    node.operator === '+'
  ) {
    flattenAdd(node.left, out);
    flattenAdd(node.right, out);
  } else {
    out.push(node);
  }
}

module.exports = function transform(fileInfo, api) {
  // Restrict to template.tsx under any nested app/ segment. Brand routing
  // depth varies (e.g. [commerce]/[locale]/[currency] vs deeper member-type
  // splits) but the file name is constant.
  if (!/[\\/]app[\\/].*template\.tsx$/.test(fileInfo.path)) {
    return null;
  }

  const j = api.jscodeshift;
  const root = j(fileInfo.source);
  let changed = false;

  root
    .find(j.VariableDeclarator, { id: { name: 'currentUrl' } })
    .forEach((p) => {
      const init = p.node.init;
      if (
        !init ||
        init.type !== 'BinaryExpression' ||
        init.operator !== '+'
      ) {
        return;
      }

      const parts = [];
      flattenAdd(init, parts);
      if (parts.length !== 3) return;

      const [base, mid, tail] = parts;
      if (mid.type !== 'Identifier' || mid.name !== 'pathname') return;
      if (tail.type !== 'Identifier' || tail.name !== 'searchParams') return;
      if (!isUrlBase(base)) return;

      // Build: `${base}${pathname}`
      const empty = () => j.templateElement({ raw: '', cooked: '' }, false);
      const tail2 = j.templateElement({ raw: '', cooked: '' }, true);
      p.node.init = j.templateLiteral([empty(), empty(), tail2], [base, mid]);
      changed = true;
    });

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