// NOTICE: This file is generated by Rollup. To modify it,
// please instead edit the ESM counterpart and rebuild with Rollup (npm run build).
'use strict';

const typeGuards = require('./typeGuards.cjs');

/**
 * @param {import('postcss').Node} statement
 * @returns {boolean}
 */
function isFirstNested(statement) {
	const parentNode = statement.parent;

	if (parentNode === undefined) {
		return false;
	}

	if (typeGuards.isRoot(parentNode) && !isInDocument(parentNode)) {
		return false;
	}

	if (statement === parentNode.first) {
		return true;
	}

	/*
	 * Search for the statement in the parent's nodes, ignoring comment
	 * nodes on the same line as the parent's opening brace.
	 */

	const parentNodes = parentNode.nodes;

	if (!parentNodes) {
		return false;
	}

	const firstNode = parentNodes[0];

	if (!firstNode) {
		return false;
	}

	if (
		!typeGuards.isComment(firstNode) ||
		(typeof firstNode.raws.before === 'string' && firstNode.raws.before.includes('\n'))
	) {
		return false;
	}

	if (!typeGuards.hasSource(firstNode) || !firstNode.source.start) {
		return false;
	}

	const openingBraceLine = firstNode.source.start.line;

	if (!firstNode.source.end || openingBraceLine !== firstNode.source.end.line) {
		return false;
	}

	for (const [index, node] of parentNodes.entries()) {
		if (index === 0) {
			continue;
		}

		if (node === statement) {
			return true;
		}

		if (
			!typeGuards.isComment(node) ||
			(typeGuards.hasSource(node) && node.source.end && node.source.end.line !== openingBraceLine)
		) {
			return false;
		}
	}

	/* istanbul ignore next: Should always return in the loop */
	return false;
}

/**
 * @param {import('postcss').Node} node
 * @returns {boolean}
 */
function isInDocument({ parent }) {
	return Boolean(parent && typeGuards.isDocument(parent));
}

module.exports = isFirstNested;
