/**
 * ESLint Rule: Server Actions Must Use Mutations
 *
 * Ensures server actions use mutations instead of direct service calls
 */

module.exports = {
  meta: {
    type: 'problem',
    docs: {
      description: 'Ensure server actions use mutations instead of direct service calls',
      category: 'Server Actions',
      recommended: true,
    },
    messages: {
      mustUseMutations: 'Server actions must use Mutations, not direct Service or API Client calls. See apps/website/docs/architecture/write/MUTATIONS.md',
      noDirectService: 'Direct service calls in server actions are not allowed',
      noMutationUsage: 'Server actions should instantiate and call mutations',
    },
    schema: [],
  },

  create(context) {
    const filename = context.getFilename();
    const isServerAction = filename.includes('/app/') &&
                          (filename.endsWith('.ts') || filename.endsWith('.tsx')) &&
                          !filename.endsWith('.test.ts') &&
                          !filename.endsWith('.test.tsx');

    if (!isServerAction) {
      return {};
    }

    let hasUseServerDirective = false;
    let hasServiceImport = false;
    let hasApiClientImport = false;
    let hasMutationImport = false;
    const newExpressions = [];
    const callExpressions = [];

    return {
      // Check for 'use server' directive
      ExpressionStatement(node) {
        if (node.expression.type === 'Literal' && node.expression.value === 'use server') {
          hasUseServerDirective = true;
        }
      },

      // Check imports
      ImportDeclaration(node) {
        const importPath = node.source.value;
        
        if (importPath.includes('/lib/services/')) {
          hasServiceImport = true;
        }
        if (importPath.includes('/lib/api/') || importPath.includes('/api/')) {
          hasApiClientImport = true;
        }
        if (importPath.includes('/lib/mutations/')) {
          hasMutationImport = true;
        }
      },

      // Track all NewExpression (instantiations)
      NewExpression(node) {
        newExpressions.push(node);
      },

      // Track all CallExpression (method calls)
      CallExpression(node) {
        callExpressions.push(node);
      },

      'Program:exit'() {
        // Only check files with 'use server' directive
        if (!hasUseServerDirective) return;

        // Check for direct service/API client instantiation
        const hasDirectServiceInstantiation = newExpressions.some(node => {
          if (node.callee.type === 'Identifier') {
            const calleeName = node.callee.name;
            return calleeName.endsWith('Service') || calleeName.endsWith('ApiClient') || calleeName.endsWith('Client');
          }
          return false;
        });

        // Check for direct service method calls
        const hasDirectServiceCall = callExpressions.some(node => {
          if (node.callee.type === 'MemberExpression' &&
              node.callee.object.type === 'Identifier') {
            const objName = node.callee.object.name;
            return objName.endsWith('Service') || objName.endsWith('ApiClient');
          }
          return false;
        });

        // Check if mutations are being used
        const hasMutationUsage = newExpressions.some(node => {
          if (node.callee.type === 'Identifier') {
            return node.callee.name.endsWith('Mutation');
          }
          return false;
        });

        // Report violations
        if (hasDirectServiceInstantiation && !hasMutationUsage) {
          context.report({
            node: context.getSourceCode().ast,
            messageId: 'mustUseMutations',
          });
        }

        if (hasDirectServiceCall) {
          context.report({
            node: context.getSourceCode().ast,
            messageId: 'noDirectService',
          });
        }

        // If imports exist but no mutation usage
        if ((hasServiceImport || hasApiClientImport) && !hasMutationImport) {
          context.report({
            node: context.getSourceCode().ast,
            messageId: 'mustUseMutations',
          });
        }
      },
    };
  },
};
