package click.kamil.springstatemachineexporter.analysis.flow.eventid;

import click.kamil.springstatemachineexporter.ast.common.AstUtils;

/**
 * Format-safe identity for event constants that may appear bare ({@code PAY}) or
 * qualified ({@code OrderEvent.PAY}). Used at compare/merge boundaries only —
 * {@code resolveUnique} may still return bare carriers for PathBinding callers.
 */
public final class EventIdentityNormalize {

    private EventIdentityNormalize() {
    }

    /**
     * Last segment of a dotted constant, or the whole string if bare.
     * Analysis tokens yield {@code null}.
     */
    public static String simpleName(String value) {
        if (value == null || value.isBlank() || AstUtils.isAnalysisToken(value)) {
            return null;
        }
        int dot = value.lastIndexOf('.');
        if (dot < 0 || dot >= value.length() - 1) {
            return value;
        }
        // Prefer EnumType.MEMBER stripping (last two segments → MEMBER is wrong;
        // use last segment only for identity).
        return value.substring(dot + 1);
    }

    /** True when both name the same enum member (bare or qualified). */
    public static boolean sameConstant(String a, String b) {
        String sa = simpleName(a);
        String sb = simpleName(b);
        return sa != null && sa.equals(sb);
    }

    /**
     * Prefer {@code EnumType.MEMBER} when either side is already qualified or
     * {@code enumType} is known; otherwise keep the first non-blank.
     */
    public static String preferQualified(String existing, String candidate, String enumType) {
        String a = existing == null || existing.isBlank() ? null : existing;
        String b = candidate == null || candidate.isBlank() ? null : candidate;
        if (a == null) {
            return qualifyIfPossible(b, enumType);
        }
        if (b == null) {
            return qualifyIfPossible(a, enumType);
        }
        if (!sameConstant(a, b)) {
            return a;
        }
        String preferred = moreQualified(a, b);
        return qualifyIfPossible(preferred, enumType);
    }

    private static String moreQualified(String a, String b) {
        boolean aQ = a.contains(".");
        boolean bQ = b.contains(".");
        if (aQ && !bQ) {
            return a;
        }
        if (bQ && !aQ) {
            return b;
        }
        return a;
    }

    private static String qualifyIfPossible(String value, String enumType) {
        if (value == null || value.isBlank() || AstUtils.isAnalysisToken(value)) {
            return value;
        }
        if (value.contains(".") || enumType == null || enumType.isBlank()) {
            return value;
        }
        String simple = simpleName(value);
        if (simple == null || !simple.matches("[A-Z_][A-Z0-9_]*")) {
            return value;
        }
        String typeSimple = enumType.contains(".")
                ? enumType.substring(enumType.lastIndexOf('.') + 1)
                : enumType;
        return typeSimple + "." + simple;
    }
}
