package p.studio.compiler.pbs.semantics;

import p.studio.compiler.pbs.semantics.PbsFlowSemanticSupport.TupleField;
import p.studio.compiler.pbs.semantics.PbsFlowSemanticSupport.TypeView;

final class PbsInlineHintSurfaceFormatter {
    String format(final TypeView type) {
        if (type == null) {
            return null;
        }
        return switch (type.kind()) {
            case UNKNOWN, ASSET_NAMESPACE -> null;
            case UNIT -> "void";
            case INT, FLOAT, BOOL, STR -> type.name();
            case STRUCT,
                    SERVICE,
                    CONTRACT,
                    CALLBACK,
                    ENUM,
                    ERROR,
                    TYPE_REF,
                    ADDRESSABLE -> type.name();
            case OPTIONAL -> {
                final var inner = format(type.inner());
                yield inner == null ? null : "optional " + inner;
            }
            case RESULT -> {
                final var errorType = format(type.errorType());
                final var payloadType = format(type.inner());
                if (errorType == null) {
                    yield null;
                }
                yield payloadType == null
                        ? "result<%s>".formatted(errorType)
                        : "result<%s> %s".formatted(errorType, payloadType);
            }
            case TUPLE -> formatTuple(type.tupleFields());
        };
    }

    private String formatTuple(final java.util.List<TupleField> fields) {
        if (fields.isEmpty()) {
            return "()";
        }
        final var builder = new StringBuilder("(");
        for (int i = 0; i < fields.size(); i++) {
            if (i > 0) {
                builder.append(", ");
            }
            final var field = fields.get(i);
            final var fieldType = format(field.type());
            if (fieldType == null) {
                return null;
            }
            builder.append(field.label())
                    .append(": ")
                    .append(fieldType);
        }
        builder.append(')');
        return builder.toString();
    }
}
