/**
 * Test with logging inside the rule
 */

const rule = {
  meta: {
    type: 'problem',
    docs: {
      description: 'Test',
      category: 'Page Query',
    },
    fixable: null,
    schema: [],
    messages: {
      mustUseBuilder: 'Must use builders',
    },
  },

  create(context) {
    let inPageQueryExecute = false;
    let hasManualTransformation = false;
    let hasBuilderCall = false;
    let pageQueryClassName = null;

    return {
      ClassDeclaration(node) {
        if (node.id && node.id.name && node.id.name.endsWith('PageQuery')) {
          pageQueryClassName = node.id.name;
          console.log('  [ClassDeclaration] Found:', pageQueryClassName);
        }
      },

      MethodDefinition(node) {
        if (node.key.type === 'Identifier' &&
            node.key.name === 'execute' &&
            node.parent.type === 'ClassBody') {
          
          const classNode = node.parent.parent;
          if (classNode && classNode.id && classNode.id.name &&
              classNode.id.name.endsWith('PageQuery')) {
            inPageQueryExecute = true;
            console.log('  [MethodDefinition] execute() in PageQuery');
          }
        }
      },

      CallExpression(node) {
        if (inPageQueryExecute) {
          console.log('  [CallExpression] inside execute:', node.callee.type);
          if (node.callee.type === 'MemberExpression' &&
              node.callee.property.type === 'Identifier' &&
              (node.callee.property.name === 'build' || node.callee.property.name === 'createViewData')) {
            console.log('  [CallExpression] Found Builder call!');
            hasBuilderCall = true;
          }
        }
      },

      VariableDeclarator(node) {
        if (inPageQueryExecute && node.init && node.init.type === 'ObjectExpression') {
          console.log('  [VariableDeclarator] ObjectExpression found');
          hasManualTransformation = true;
        }
      },

      ReturnStatement(node) {
        if (inPageQueryExecute && node.argument) {
          console.log('  [ReturnStatement] type:', node.argument.type);
          
          // Direct object literal return
          if (node.argument.type === 'ObjectExpression') {
            console.log('  [ReturnStatement] ObjectExpression - setting manual transformation');
            hasManualTransformation = true;
          }
          // Direct identifier return
          else if (node.argument.type === 'Identifier') {
            console.log('  [ReturnStatement] Identifier:', node.argument.name);
            if (!node.argument.name.includes('ViewData') && !node.argument.name.includes('viewData')) {
              console.log('  [ReturnStatement] Not ViewData, checking builder call...');
              if (!hasBuilderCall) {
                console.log('  [ReturnStatement] No builder call - setting manual transformation');
                hasManualTransformation = true;
              }
            }
          }
          // CallExpression
          else if (node.argument.type === 'CallExpression') {
            console.log('  [ReturnStatement] CallExpression');
            const callExpr = node.argument;
            if (callExpr.callee.type === 'MemberExpression' &&
                callExpr.callee.object.type === 'Identifier' &&
                callExpr.callee.object.name === 'Result' &&
                callExpr.callee.property.type === 'Identifier' &&
                (callExpr.callee.property.name === 'ok' || callExpr.callee.property.name === 'err')) {
              
              console.log('  [ReturnStatement] Result.' + callExpr.callee.property.name + '()');
              
              if (callExpr.callee.property.name === 'ok' && 
                  callExpr.arguments.length > 0 &&
                  callExpr.arguments[0].type === 'Identifier') {
                const argName = callExpr.arguments[0].name;
                console.log('  [ReturnStatement] Argument:', argName);
                
                const isApiDto = argName.includes('Dto') || 
                                 argName.includes('api') || 
                                 argName === 'result' ||
                                 argName === 'data';
                
                console.log('  [ReturnStatement] Is API DTO?', isApiDto);
                console.log('  [ReturnStatement] Has builder call?', hasBuilderCall);
                
                if (isApiDto && !hasBuilderCall) {
                  console.log('  [ReturnStatement] ✓ Setting manual transformation!');
                  hasManualTransformation = true;
                }
              }
            }
          }
        }
      },

      'MethodDefinition:exit'(node) {
        if (node.key.type === 'Identifier' && node.key.name === 'execute') {
          inPageQueryExecute = false;
          console.log('  [MethodDefinition:exit] execute()');
        }
      },

      'Program:exit'() {
        console.log('\n[Program:exit]');
        console.log('  hasManualTransformation:', hasManualTransformation);
        console.log('  hasBuilderCall:', hasBuilderCall);
        console.log('  Should report?', hasManualTransformation && !hasBuilderCall);
        
        if (hasManualTransformation && !hasBuilderCall) {
          console.log('  ✓✓✓ REPORTING ERROR ✓✓✓');
          context.report({
            node: context.getSourceCode().ast,
            messageId: 'mustUseBuilder',
          });
        }
      },
    };
  },
};

// Test it
const mockContext = {
  getSourceCode: () => ({ ast: {} }),
  report: (data) => {
    console.log('\n*** REPORT CALLED ***');
  }
};

const visitor = rule.create(mockContext);

console.log('=== Test with Logging ===\n');

visitor.ClassDeclaration({
  id: { name: 'AdminDashboardPageQuery' }
});

visitor.MethodDefinition({
  key: { type: 'Identifier', name: 'execute' },
  parent: { type: 'ClassBody' }
});

visitor.VariableDeclarator({
  init: { type: 'CallExpression' }
});

visitor.ReturnStatement({
  argument: {
    type: 'CallExpression',
    callee: {
      type: 'MemberExpression',
      object: { type: 'Identifier', name: 'Result' },
      property: { type: 'Identifier', name: 'ok' }
    },
    arguments: [{ type: 'Identifier', name: 'apiDto' }]
  }
});

visitor['MethodDefinition:exit']({
  key: { type: 'Identifier', name: 'execute' }
});

visitor['Program:exit']();

console.log('\n=== Done ===');
