// @ts-check

export const parser = 'tsx';

const getAttr = (j, node, attribute) => {
    const attributes = node.value?.openingElement?.attributes || [];
    const attr = attributes.find(
        (attr) => j.JSXAttribute.check(attr) && attr.name.name === attribute,
    );

    if (!attr) {
        return null;
    }

    const value = attr.value;

    if (value.type === 'StringLiteral') {
        return value;
    }

    return value?.expression || null;
};

/** @type {import('jscodeshift').Transform} */
const transform = (file, api, options) => {
    const j = api.jscodeshift;
    const root = j(file.source);

    root.findJSXElements('ConditionallyRender')
        .forEach((path) => {
            const attributes = path.node.openingElement.attributes;

            attributes?.forEach((attr) => {
                if (
                    j.JSXAttribute.check(attr) &&
                    (attr.name.name === 'show' || attr.name.name === 'elseShow')
                ) {
                    const attrValue = attr.value;

                    // Check if the attribute value is an arrow function returning JSX
                    if (
                        j.JSXExpressionContainer.check(attrValue) &&
                        j.ArrowFunctionExpression.check(attrValue.expression)
                    ) {
                        const arrowFunctionBody = attrValue.expression.body;

                        if (
                            j.JSXElement.check(arrowFunctionBody) ||
                            j.JSXFragment.check(arrowFunctionBody)
                        ) {
                            // Replace the arrow function with the direct JSX element or fragment
                            attr.value =
                                j.jsxExpressionContainer(arrowFunctionBody);
                        }
                    }
                }
            });
        })
        .replaceWith((node) => {
            const isInJSX = ['JSXElement', 'JSXFragment'].includes(
                node.parent.value.type,
            );

            const condition = getAttr(j, node, 'condition');
            const show = getAttr(j, node, 'show');
            const elseShow = getAttr(j, node, 'elseShow');
            const alternate = elseShow === null ? j.nullLiteral() : elseShow;

            return isInJSX
                ? j.jsxExpressionContainer({
                      type: 'ConditionalExpression',
                      test: condition,
                      consequent: show,
                      alternate,
                  })
                : j.conditionalExpression(condition, show, alternate);
        });

    return root.toSource();
};

export default transform;