/**
 * ESLint rule to prefer SDK hooks over native browser APIs
 * @fileoverview Enforce using Shop Minis SDK hooks instead of native browser APIs
 */

module.exports = {
  meta: {
    type: 'suggestion',
    docs: {
      description:
        'Prefer Shop Minis SDK hooks over native browser APIs for better compatibility and functionality',
      category: 'Best Practices',
      recommended: true,
    },
    messages: {
      preferAsyncStorage:
        'Use useAsyncStorage from @shopify/shop-minis-react instead of localStorage. The SDK hook provides async storage that works reliably in the Shop mini-app environment.',
      preferSecureStorage:
        'Use useSecureStorage from @shopify/shop-minis-react instead of localStorage for sensitive data. The SDK hook provides encrypted storage.',
    },
    schema: [
      {
        type: 'object',
        properties: {
          apis: {
            type: 'object',
            description: 'Map of native APIs to SDK hooks',
            additionalProperties: {
              type: 'string',
            },
          },
        },
        additionalProperties: false,
      },
    ],
  },

  create(context) {
    // Default API mappings
    const defaultApis = {
      localStorage: 'useAsyncStorage',
      sessionStorage: 'useAsyncStorage',
      // Future additions will go here:
      // navigator.geolocation: 'useGeolocation',
      // window.history: 'useNavigation',
    }

    // Get user configuration or use defaults
    const options = context.options[0] || {}
    const apiMap = {
      ...defaultApis,
      ...(options.apis || {}),
    }

    return {
      MemberExpression(node) {
        // Check for direct access: localStorage.getItem()
        if (node.object.type === 'Identifier' && apiMap[node.object.name]) {
          const apiName = node.object.name
          const sdkHook = apiMap[apiName]

          context.report({
            node: node.object,
            messageId: 'preferAsyncStorage',
            data: {
              nativeApi: apiName,
              sdkHook,
            },
          })
          return
        }

        // Check for global access: window.localStorage or globalThis.localStorage
        if (
          node.object.type === 'MemberExpression' &&
          node.object.object.type === 'Identifier' &&
          (node.object.object.name === 'window' ||
            node.object.object.name === 'globalThis') &&
          node.object.property.type === 'Identifier' &&
          apiMap[node.object.property.name]
        ) {
          const apiName = node.object.property.name
          const sdkHook = apiMap[apiName]

          context.report({
            node: node.object,
            messageId: 'preferAsyncStorage',
            data: {
              nativeApi: apiName,
              sdkHook,
            },
          })
        }
      },

      // Also catch direct references to localStorage/sessionStorage
      Identifier(node) {
        // Only flag if it's being used, not just referenced in imports
        const parent = node.parent

        // Skip if it's part of an import statement
        if (
          parent.type === 'ImportSpecifier' ||
          parent.type === 'ImportDefaultSpecifier'
        ) {
          return
        }

        // Skip if it's already part of a MemberExpression (handled above)
        if (parent.type === 'MemberExpression' && parent.object === node) {
          return
        }

        // Check if this is a direct reference to localStorage/sessionStorage
        if (!apiMap[node.name]) {
          return
        }

        // Skip if it's being declared as a variable
        if (parent.type === 'VariableDeclarator' && parent.init === node) {
          return
        }

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