/**
 * ESLint rule to suggest proper component classification and enforce UI component usage
 * 
 * Architecture:
 * - app/ - Pages and layouts only (no business logic)
 * - components/ - App-level components (can be stateful, can use hooks)
 * - ui/ - Pure, reusable UI elements (stateless, no hooks)
 * 
 * This rule enforces that components use proper UI elements instead of raw HTML and className.
 */

module.exports = {
  meta: {
    type: 'problem',
    docs: {
      description: 'Enforce proper component classification and UI component usage',
      category: 'Architecture',
      recommended: true,
    },
    fixable: null,
    schema: [],
    messages: {
      uiShouldBePure: 'This appears to be a pure UI element. Consider moving to ui/ for maximum reusability.',
      componentShouldBeInComponents: 'This component uses state/hooks. Consider moving to components/.',
      pureComponentInComponents: 'Pure component in components/. Consider moving to ui/ for better reusability.',
      noRawHtml: 'Raw HTML tags are forbidden in components and pages. Use UI components from ui/ instead.',
      noClassName: 'The className property is forbidden in components and pages. Use proper component props for styling.',
      noStyle: 'The style property is forbidden in components and pages. Use proper component props for styling.',
    },
  },

  create(context) {
    const filename = context.getFilename();
    const isInUi = filename.includes('/ui/');
    const isInComponents = filename.includes('/components/');
    const isInApp = filename.includes('/app/');
    
    if (!isInUi && !isInComponents && !isInApp) return {};

    return {
      Program(node) {
        if (isInApp) return; // Don't check classification for app/ files

        const sourceCode = context.getSourceCode();
        const text = sourceCode.getText();
        
        // Detect stateful patterns
        const hasState = /useState|useReducer|this\.state/.test(text);
        const hasEffects = /useEffect|useLayoutEffect/.test(text);
        const hasContext = /useContext/.test(text);
        const hasComplexLogic = /if\s*\(|switch\s*\(|for\s*\(|while\s*\(/.test(text);
        
        // Detect pure UI patterns (just JSX, props, simple functions)
        const hasOnlyJsx = /^\s*import.*from.*;\s*export\s+function\s+\w+\s*\([^)]*\)\s*{?\s*return\s*\(?.*\)?;?\s*}?\s*$/m.test(text);
        const hasNoLogic = !hasState && !hasEffects && !hasContext && !hasComplexLogic;
        
        if (isInUi && hasState) {
          context.report({
            loc: { line: 1, column: 0 },
            messageId: 'componentShouldBeInComponents',
          });
        }
        
        if (isInComponents && hasNoLogic && hasOnlyJsx) {
          context.report({
            loc: { line: 1, column: 0 },
            messageId: 'pureComponentInComponents',
          });
        }
      },

      JSXOpeningElement(node) {
        if (isInUi) return; // Allow raw HTML and className in ui/

        let tagName = '';
        if (node.name.type === 'JSXIdentifier') {
          tagName = node.name.name;
        } else if (node.name.type === 'JSXMemberExpression') {
          tagName = node.name.property.name;
        }

        if (!tagName) return;

        // 1. Forbid raw HTML tags (lowercase)
        if (tagName[0] === tagName[0].toLowerCase()) {
          // Special case for html and body in RootLayout
          if (isInApp && (tagName === 'html' || tagName === 'body' || tagName === 'head' || tagName === 'meta' || tagName === 'link' || tagName === 'script')) {
            return;
          }

          context.report({
            node,
            messageId: 'noRawHtml',
          });
        }

        // 2. Forbid className property
        const classNameAttr = node.attributes.find(
          attr => attr.type === 'JSXAttribute' && 
                 attr.name.type === 'JSXIdentifier' && 
                 attr.name.name === 'className'
        );

        if (classNameAttr) {
          // Special case for html and body in RootLayout
          if (isInApp && (tagName === 'html' || tagName === 'body')) {
            return;
          }

          context.report({
            node: classNameAttr,
            messageId: 'noClassName',
          });
        }

        // 3. Forbid style property
        const styleAttr = node.attributes.find(
          attr => attr.type === 'JSXAttribute' && 
                 attr.name.type === 'JSXIdentifier' && 
                 attr.name.name === 'style'
        );

        if (styleAttr) {
          context.report({
            node: styleAttr,
            messageId: 'noStyle',
          });
        }
      },
    };
  },
};
