import {
  findJSDocComment,
} from '@es-joy/jsdoccomment';
import debugModule from 'debug';

const debug = debugModule('requireExportJsdoc');

/**
 * @typedef {{
 *   value: string
 * }} ValueObject
 */

/**
 * @typedef {{
 *   type?: string,
 *   value?: ValueObject|import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node,
 *   props: {
 *     [key: string]: CreatedNode|null,
 *   },
 *   special?: true,
 *   globalVars?: CreatedNode,
 *   exported?: boolean,
 *   ANONYMOUS_DEFAULT?: import('eslint').Rule.Node
 * }} CreatedNode
 */

/**
 * @returns {CreatedNode}
 */
const createNode = function () {
  return {
    props: {},
  };
};

/**
 * @param {CreatedNode|null} symbol
 * @returns {string|null}
 */
const getSymbolValue = function (symbol) {
  /* c8 ignore next 3 */
  if (!symbol) {
    return null;
  }

  /* c8 ignore else */
  if (symbol.type === 'literal') {
    return /** @type {ValueObject} */ (symbol.value).value;
  }
  /* c8 ignore next 2 */
  // eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
  return null;
};

/**
 *
 * @param {import('estree').Identifier} node
 * @param {CreatedNode} globals
 * @param {CreatedNode} scope
 * @param {SymbolOptions} opts
 * @returns {CreatedNode|null}
 */
const getIdentifier = function (node, globals, scope, opts) {
  if (opts.simpleIdentifier) {
    // Type is Identier for noncomputed properties
    const identifierLiteral = createNode();
    identifierLiteral.type = 'literal';
    identifierLiteral.value = {
      value: node.name,
    };

    return identifierLiteral;
  }

  /* c8 ignore next */
  const block = scope || globals;

  // As scopes are not currently supported, they are not traversed upwards recursively
  if (block.props[node.name]) {
    return block.props[node.name];
  }

  // Seems this will only be entered once scopes added and entered
  /* c8 ignore next 3 */
  if (globals.props[node.name]) {
    return globals.props[node.name];
  }

  return null;
};

/**
 * @callback CreateSymbol
 * @param {import('eslint').Rule.Node|null} node
 * @param {CreatedNode} globals
 * @param {import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node|null} value
 * @param {CreatedNode} [scope]
 * @param {boolean|SymbolOptions} [isGlobal]
 * @returns {CreatedNode|null}
 */

/** @type {CreateSymbol} */
let createSymbol; // eslint-disable-line prefer-const

/**
 * @typedef {{
 *   simpleIdentifier?: boolean
 * }} SymbolOptions
 */

/**
 *
 * @param {import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node} node
 * @param {CreatedNode} globals
 * @param {CreatedNode} scope
 * @param {SymbolOptions} [opt]
 * @returns {CreatedNode|null}
 */
const getSymbol = function (node, globals, scope, opt) {
  const opts = opt || {};
  /* c8 ignore next */
  switch (node.type) {
    /* c8 ignore next 4 -- No longer needed? */
    case 'ArrowFunctionExpression':

    // Fallthrough
    case 'ClassDeclaration':

    case 'FunctionDeclaration':

    case 'FunctionExpression':
    case 'TSEnumDeclaration':
    case 'TSInterfaceDeclaration':
    case 'TSTypeAliasDeclaration': {
      const val = createNode();
      val.props.prototype = createNode();
      val.props.prototype.type = 'object';
      val.type = 'object';
      val.value = node;

      return val;
    }

    case 'AssignmentExpression': {
      return createSymbol(
      /** @type {import('eslint').Rule.Node} */
        (node.left),
        globals,
        /** @type {import('eslint').Rule.Node} */
        (node.right),
        scope,
        opts,
      );
    }

    case 'ClassBody': {
      const val = createNode();
      for (const method of node.body) {
        // StaticBlock
        if (!('key' in method)) {
          continue;
        }

        val.props[
        /** @type {import('estree').Identifier} */ (
          /** @type {import('estree').MethodDefinition} */ (
              method
            ).key
          ).name
        ] = createNode();
        /** @type {{[key: string]: CreatedNode}} */ (val.props)[
        /** @type {import('estree').Identifier} */ (
          /** @type {import('estree').MethodDefinition} */ (
              method
            ).key
          ).name
        ].type = 'object';
        /** @type {{[key: string]: CreatedNode}} */ (val.props)[
        /** @type {import('estree').Identifier} */ (
          /** @type {import('estree').MethodDefinition} */ (
              method
            ).key
          ).name
        ].value = /** @type {import('eslint').Rule.Node} */ (
        /** @type {import('estree').MethodDefinition} */ (method).value
        );
      }

      val.type = 'object';
      val.value = node.parent;

      return val;
    }

    case 'ClassExpression': {
      return getSymbol(
      /** @type {import('eslint').Rule.Node} */
        (node.body),
        globals,
        scope,
        opts,
      );
    }

    case 'Identifier': {
      return getIdentifier(node, globals, scope, opts);
    }

    case 'Literal': {
      const val = createNode();
      val.type = 'literal';
      val.value = node;

      return val;
    }

    case 'MemberExpression': {
      const obj = getSymbol(
      /** @type {import('eslint').Rule.Node} */
        (node.object),
        globals,
        scope,
        opts,
      );
      const propertySymbol = getSymbol(
      /** @type {import('eslint').Rule.Node} */
        (node.property),
        globals,
        scope,
        {
          simpleIdentifier: !node.computed,
        },
      );
      const propertyValue = getSymbolValue(propertySymbol);

      /* c8 ignore else */
      if (obj && propertyValue && obj.props[propertyValue]) {
        const block = obj.props[propertyValue];

        return block;
      }
      /* c8 ignore next 11 */
      /*
    if (opts.createMissingProps && propertyValue) {
      obj.props[propertyValue] = createNode();

      return obj.props[propertyValue];
    }
    */
      // eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
      debug(`MemberExpression: Missing property ${
      /** @type {import('estree').PrivateIdentifier} */ (node.property).name
      }`);
      /* c8 ignore next 2 */
      return null;
    }

    case 'ObjectExpression': {
      const val = createNode();
      val.type = 'object';
      for (const prop of node.properties) {
        if ([
        // @babel/eslint-parser
          'ExperimentalSpreadProperty',

          // typescript-eslint, espree, acorn, etc.
          'SpreadElement',
        ].includes(prop.type)) {
          continue;
        }

        const propVal = getSymbol(
        /** @type {import('eslint').Rule.Node} */ (
          /** @type {import('estree').Property} */
            (prop).value
          ),
          globals,
          scope,
          opts,
        );
        /* c8 ignore next 8 */
        if (propVal) {
          val.props[
          /** @type {import('estree').PrivateIdentifier} */
            (
            /** @type {import('estree').Property} */ (prop).key
            ).name
          ] = propVal;
        }
      }

      return val;
    }
  }
  /* c8 ignore next 2 */
  // eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
  return null;
};

/**
 *
 * @param {CreatedNode} block
 * @param {string} name
 * @param {CreatedNode|null} value
 * @param {CreatedNode} globals
 * @param {boolean|SymbolOptions|undefined} isGlobal
 * @returns {void}
 */
const createBlockSymbol = function (block, name, value, globals, isGlobal) {
  block.props[name] = value;
  if (isGlobal && globals.props.window && globals.props.window.special) {
    globals.props.window.props[name] = value;
  }
};

createSymbol = function (node, globals, value, scope, isGlobal) {
  const block = scope || globals;
  /* c8 ignore next 3 */
  if (!node) {
    return null;
  }

  let symbol;
  switch (node.type) {
    case 'ClassDeclaration':
      /* c8 ignore next */
      // @ts-expect-error TS OK
      // Fall through
    case 'FunctionDeclaration': case 'TSEnumDeclaration':
      /* c8 ignore next */
      // @ts-expect-error TS OK
      // Fall through
    case 'TSInterfaceDeclaration': case 'TSTypeAliasDeclaration': {
      const nde = /** @type {import('estree').ClassDeclaration} */ (node);
      /* c8 ignore else */
      if (nde.id && nde.id.type === 'Identifier') {
        return createSymbol(
        /** @type {import('eslint').Rule.Node} */ (nde.id),
          globals,
          node,
          globals,
        );
      }
      /* c8 ignore next 3 */
      // eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
      break;
    }

    case 'Identifier': {
      const nde = /** @type {import('estree').Identifier} */ (node);
      if (value) {
        const valueSymbol = getSymbol(value, globals, block);
        /* c8 ignore else */
        if (valueSymbol) {
          createBlockSymbol(block, nde.name, valueSymbol, globals, isGlobal);

          return block.props[nde.name];
        }
        /* c8 ignore next 2 */
        // eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
        debug('Identifier: Missing value symbol for %s', nde.name);
      } else {
        createBlockSymbol(block, nde.name, createNode(), globals, isGlobal);

        return block.props[nde.name];
      }
      /* c8 ignore next 3 */
      // eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
      break;
    }

    case 'MemberExpression': {
      const nde = /** @type {import('estree').MemberExpression} */ (node);
      symbol = getSymbol(
      /** @type {import('eslint').Rule.Node} */ (nde.object), globals, block,
      );

      const propertySymbol = getSymbol(
      /** @type {import('eslint').Rule.Node} */ (nde.property),
        globals,
        block,
        {
          simpleIdentifier: !nde.computed,
        },
      );
      const propertyValue = getSymbolValue(propertySymbol);
      if (symbol && propertyValue) {
        createBlockSymbol(symbol, propertyValue, getSymbol(
        /** @type {import('eslint').Rule.Node} */
          (value), globals, block,
        ), globals, isGlobal);
        return symbol.props[propertyValue];
      }

      debug(
        'MemberExpression: Missing symbol: %s',
        /** @type {import('estree').Identifier} */ (
          nde.property
        ).name,
      );
      break;
    }
  }

  return null;
};

/**
 * Creates variables from variable definitions
 * @param {import('eslint').Rule.Node} node
 * @param {CreatedNode} globals
 * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opts
 * @returns {void}
 */
const initVariables = function (node, globals, opts) {
  switch (node.type) {
    case 'ExportNamedDeclaration': {
      if (node.declaration) {
        initVariables(
        /** @type {import('eslint').Rule.Node} */
          (node.declaration),
          globals,
          opts,
        );
      }

      break;
    }

    case 'ExpressionStatement': {
      initVariables(
      /** @type {import('eslint').Rule.Node} */
        (node.expression),
        globals,
        opts,
      );
      break;
    }

    case 'Program': {
      for (const childNode of node.body) {
        initVariables(
        /** @type {import('eslint').Rule.Node} */
          (childNode),
          globals,
          opts,
        );
      }

      break;
    }

    case 'VariableDeclaration': {
      for (const declaration of node.declarations) {
      // let and const
        const symbol = createSymbol(
        /** @type {import('eslint').Rule.Node} */
          (declaration.id),
          globals,
          null,
          globals,
        );
        if (opts.initWindow && node.kind === 'var' && globals.props.window) {
        // If var, also add to window
          globals.props.window.props[
          /** @type {import('estree').Identifier} */
            (declaration.id).name
          ] = symbol;
        }
      }

      break;
    }
  }
};

/**
 * Populates variable maps using AST
 * @param {import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node} node
 * @param {CreatedNode} globals
 * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
 * @param {true} [isExport]
 * @returns {boolean}
 */
const mapVariables = function (node, globals, opt, isExport) {
  /* c8 ignore next */
  const opts = opt || {};
  /* c8 ignore next */
  switch (node.type) {
    case 'AssignmentExpression': {
      createSymbol(
      /** @type {import('eslint').Rule.Node} */
        (node.left),
        globals,
        /** @type {import('eslint').Rule.Node} */
        (node.right),
      );
      break;
    }

    case 'ClassDeclaration': {
      createSymbol(
      /** @type {import('eslint').Rule.Node|null} */ (node.id),
        globals,
        /** @type {import('eslint').Rule.Node} */ (node.body),
        globals,
      );
      break;
    }

    case 'ExportDefaultDeclaration': {
      const symbol = createSymbol(
      /** @type {import('eslint').Rule.Node} */
        (node.declaration),
        globals,
        /** @type {import('eslint').Rule.Node} */
        (node.declaration),
      );
      if (symbol) {
        symbol.exported = true;
        /* c8 ignore next 6 */
      } else {
      // if (!node.id) {
        globals.ANONYMOUS_DEFAULT = /** @type {import('eslint').Rule.Node} */ (
          node.declaration
        );
      }

      break;
    }

    case 'ExportNamedDeclaration': {
      if (node.declaration) {
        if (node.declaration.type === 'VariableDeclaration') {
          mapVariables(
          /** @type {import('eslint').Rule.Node} */
            (node.declaration),
            globals,
            opts,
            true,
          );
        } else {
          const symbol = createSymbol(
          /** @type {import('eslint').Rule.Node} */
            (node.declaration),
            globals,
            /** @type {import('eslint').Rule.Node} */
            (node.declaration),
          );
          /* c8 ignore next 3 */
          if (symbol) {
            symbol.exported = true;
          }
        }
      }

      for (const specifier of node.specifiers) {
        mapVariables(
        /** @type {import('eslint').Rule.Node} */
          (specifier),
          globals,
          opts,
        );
      }

      break;
    }

    case 'ExportSpecifier': {
      const symbol = getSymbol(
      /** @type {import('eslint').Rule.Node} */
        (node.local),
        globals,
        globals,
      );
      /* c8 ignore next 3 */
      if (symbol) {
        symbol.exported = true;
      }

      break;
    }

    case 'ExpressionStatement': {
      mapVariables(
      /** @type {import('eslint').Rule.Node} */
        (node.expression),
        globals,
        opts,
      );
      break;
    }

    case 'FunctionDeclaration':

    case 'TSTypeAliasDeclaration': {
    /* c8 ignore next 10 */
      if (/** @type {import('estree').Identifier} */ (node.id).type === 'Identifier') {
        createSymbol(
        /** @type {import('eslint').Rule.Node} */
          (node.id),
          globals,
          node,
          globals,
          true,
        );
      }

      break;
    }

    case 'Program': {
      if (opts.ancestorsOnly) {
        return false;
      }

      for (const childNode of node.body) {
        mapVariables(
        /** @type {import('eslint').Rule.Node} */
          (childNode),
          globals,
          opts,
        );
      }

      break;
    }

    case 'VariableDeclaration': {
      for (const declaration of node.declarations) {
        const isGlobal = Boolean(opts.initWindow && node.kind === 'var' && globals.props.window);
        const symbol = createSymbol(
        /** @type {import('eslint').Rule.Node} */
          (declaration.id),
          globals,
          /** @type {import('eslint').Rule.Node} */
          (declaration.init),
          globals,
          isGlobal,
        );
        if (symbol && isExport) {
          symbol.exported = true;
        }
      }

      break;
    }

    default: {
    /* c8 ignore next */
      return false;
    }
  }

  return true;
};

/**
 *
 * @param {import('eslint').Rule.Node} node
 * @param {CreatedNode|ValueObject|string|undefined|
 *   import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node} block
 * @param {(CreatedNode|ValueObject|string|
 *   import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node)[]} [cache]
 * @returns {boolean}
 */
const findNode = function (node, block, cache) {
  let blockCache = cache || [];
  if (!block || blockCache.includes(block)) {
    return false;
  }

  blockCache = blockCache.slice();
  blockCache.push(block);

  if (
    typeof block === 'object' &&
    'type' in block &&
    (block.type === 'object' || block.type === 'MethodDefinition') &&
    block.value === node
  ) {
    return true;
  }

  if (typeof block !== 'object') {
    return false;
  }

  const props = ('props' in block && block.props) || ('body' in block && block.body);
  for (const propval of Object.values(props || {})) {
    if (Array.isArray(propval)) {
      /* c8 ignore next 5 */
      if (propval.some((val) => {
        return findNode(node, val, blockCache);
      })) {
        return true;
      }
    } else if (findNode(node, propval, blockCache)) {
      return true;
    }
  }

  return false;
};

const exportTypes = new Set([
  'ExportDefaultDeclaration', 'ExportNamedDeclaration',
]);
const ignorableNestedTypes = new Set([
  'ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression',
]);

/**
 * @param {import('eslint').Rule.Node} nde
 * @returns {import('eslint').Rule.Node|false}
 */
const getExportAncestor = function (nde) {
  /** @type {import('eslint').Rule.Node|null} */
  let node = nde;
  let idx = 0;
  const ignorableIfDeep = ignorableNestedTypes.has(nde?.type);
  while (node) {
    // Ignore functions nested more deeply than say `export default function () {}`
    if (idx >= 2 && ignorableIfDeep) {
      break;
    }

    if (exportTypes.has(node.type)) {
      return node;
    }

    node = node.parent;
    idx++;
  }

  return false;
};

const canBeExportedByAncestorType = new Set([
  'ClassProperty',
  'Method',
  'PropertyDefinition',
  'TSMethodSignature',
  'TSPropertySignature',
]);

const canExportChildrenType = new Set([
  'ClassBody',
  'ClassDeclaration',
  'ClassDefinition',
  'ClassExpression',
  'Program',
  'TSInterfaceBody',
  'TSInterfaceDeclaration',
  'TSTypeAliasDeclaration',
  'TSTypeLiteral',
  'TSTypeParameterInstantiation',
  'TSTypeReference',
]);

/**
 * @param {import('eslint').Rule.Node} nde
 * @returns {false|import('eslint').Rule.Node}
 */
const isExportByAncestor = function (nde) {
  if (!canBeExportedByAncestorType.has(nde.type)) {
    return false;
  }

  let node = nde.parent;
  while (node) {
    if (exportTypes.has(node.type)) {
      return node;
    }

    if (!canExportChildrenType.has(node.type)) {
      return false;
    }

    node = node.parent;
  }

  return false;
};

/**
 *
 * @param {CreatedNode} block
 * @param {import('eslint').Rule.Node} node
 * @param {CreatedNode[]} [cache] Currently unused
 * @returns {boolean}
 */
const findExportedNode = function (block, node, cache) {
  /* c8 ignore next 3 */
  if (block === null) {
    return false;
  }

  const blockCache = cache || [];
  const {
    props,
  } = block;
  for (const propval of Object.values(props)) {
    const pval = /** @type {CreatedNode} */ (propval);
    blockCache.push(pval);
    if (pval.exported && (node === pval.value || findNode(node, pval.value))) {
      return true;
    }

    // No need to check `propval` for exported nodes as ESM
    //  exports are only global
  }

  return false;
};

/**
 *
 * @param {import('eslint').Rule.Node} node
 * @param {CreatedNode} globals
 * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
 * @returns {boolean}
 */
const isNodeExported = function (node, globals, opt) {
  const moduleExports = globals.props.module?.props?.exports;
  if (
    opt.initModuleExports && moduleExports && findNode(node, moduleExports)
  ) {
    return true;
  }

  if (opt.initWindow && globals.props.window && findNode(node, globals.props.window)) {
    return true;
  }

  if (opt.esm && findExportedNode(globals, node)) {
    return true;
  }

  return false;
};

/**
 *
 * @param {import('eslint').Rule.Node} node
 * @param {CreatedNode} globalVars
 * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opts
 * @returns {boolean}
 */
const parseRecursive = function (node, globalVars, opts) {
  // Iterate from top using recursion - stop at first processed node from top
  if (node.parent && parseRecursive(node.parent, globalVars, opts)) {
    return true;
  }

  return mapVariables(node, globalVars, opts);
};

/**
 *
 * @param {import('eslint').Rule.Node} ast
 * @param {import('eslint').Rule.Node} node
 * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
 * @returns {CreatedNode}
 */
const parse = function (ast, node, opt) {
  /* c8 ignore next 6 */
  const opts = opt || {
    ancestorsOnly: false,
    esm: true,
    initModuleExports: true,
    initWindow: true,
  };

  const globalVars = createNode();
  if (opts.initModuleExports) {
    globalVars.props.module = createNode();
    globalVars.props.module.props.exports = createNode();
    globalVars.props.exports = globalVars.props.module.props.exports;
  }

  if (opts.initWindow) {
    globalVars.props.window = createNode();
    globalVars.props.window.special = true;
  }

  if (opts.ancestorsOnly) {
    parseRecursive(node, globalVars, opts);
  } else {
    initVariables(ast, globalVars, opts);
    mapVariables(ast, globalVars, opts);
  }

  return {
    globalVars,
    props: {},
  };
};

const accessibilityNodes = new Set([
  'MethodDefinition',
  'PropertyDefinition',
]);

/**
 *
 * @param {import('eslint').Rule.Node} node
 * @returns {boolean}
 */
const isPrivate = (node) => {
  return accessibilityNodes.has(node.type) &&
    (
      'accessibility' in node &&
      node.accessibility !== 'public' && node.accessibility !== undefined
    ) ||
  'key' in node &&
    node.key.type === 'PrivateIdentifier';
};

/**
 *
 * @param {import('eslint').Rule.Node} node
 * @param {import('eslint').SourceCode} sourceCode
 * @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
 * @param {import('./iterateJsdoc.js').Settings} settings
 * @returns {boolean}
 */
const isUncommentedExport = function (node, sourceCode, opt, settings) {
  // console.log({node});
  // Optimize with ancestor check for esm
  if (opt.esm) {
    if (isPrivate(node) ||
      node.parent && isPrivate(node.parent)) {
      return false;
    }

    const exportNode = getExportAncestor(node);

    // Is export node comment
    if (exportNode && !findJSDocComment(exportNode, sourceCode, settings)) {
      return true;
    }

    /**
     * Some typescript types are not in variable map, but inherit exported (interface property and method)
     */
    if (
      isExportByAncestor(node) &&
      !findJSDocComment(node, sourceCode, settings)
    ) {
      return true;
    }
  }

  const ast = /** @type {unknown} */ (sourceCode.ast);

  const parseResult = parse(
    /** @type {import('eslint').Rule.Node} */
    (ast),
    node,
    opt,
  );

  return isNodeExported(
    node, /** @type {CreatedNode} */ (parseResult.globalVars), opt,
  );
};

export default {
  isUncommentedExport,
  parse,
};
