package top.r3944realms.lib39.core.command.model;

import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 命令路径构建器 - 提供编译时类型安全
 */
public final class CommandPath {
    private final List<String> segments;
    private final String fullPath;

    private CommandPath(List<String> segments) {
        this.segments = List.copyOf(segments);
        this.fullPath = String.join(" ", segments);
    }

    /**
     * Of command path.
     *
     * @param segments the segments
     * @return the command path
     */
    @Contract("_ -> new")
    public static @NotNull CommandPath of(String... segments) {
        validateSegments(segments);
        return new CommandPath(List.of(segments));
    }

    /**
     * From string command path.
     *
     * @param path the path
     * @return the command path
     */
    @Contract("_ -> new")
    public static @NotNull CommandPath fromString(@NotNull String path) {
        if (path.charAt(0) == '/') {
            path = path.substring(1);
        }
        return of(path.split(" "));
    }

    /**
     * Then command path.
     *
     * @param subSegments the sub segments
     * @return the command path
     */
    @Contract("_ -> new")
    public @NotNull CommandPath then(String... subSegments) {
        validateSegments(subSegments);
        List<String> newSegments = new ArrayList<>(this.segments);
        newSegments.addAll(List.of(subSegments));
        return new CommandPath(newSegments);
    }

    /**
     * Parent optional.
     *
     * @return the optional
     */
    public Optional<CommandPath> parent() {
        if (segments.size() <= 1) {
            return Optional.empty();
        }
        return Optional.of(new CommandPath(segments.subList(0, segments.size() - 1)));
    }

    /**
     * Last segment string.
     *
     * @return the string
     */
    public String lastSegment() {
        return segments.isEmpty() ? "" : segments.get(segments.size() - 1);
    }

    /**
     * Segments string @ not null [ ].
     *
     * @return the string @ not null [ ]
     */
    public String @NotNull [] segments() {
        return segments.toArray(new String[0]);
    }

    /**
     * Full path string.
     *
     * @return the string
     */
    public String fullPath() {
        return fullPath;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CommandPath that = (CommandPath) o;
        return Objects.equals(fullPath, that.fullPath);
    }

    @Override
    public int hashCode() {
        return fullPath.hashCode();
    }

    @Override
    public String toString() {
        return fullPath;
    }

    private static void validateSegments(String @NotNull [] segments) {
        for (String segment : segments) {
            if (segment == null || segment.isEmpty() || segment.contains(" ")) {
                throw new IllegalArgumentException("Invalid command segment: " + segment);
            }
        }
    }
}
