package com.shanebeestudios.skbee.elements.other.conditions;

import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.SyntaxStringBuilder;
import ch.njol.util.Kleenean;
import com.github.shanebeee.skr.scheduling.RegionUtils;
import com.github.shanebeee.skr.Registration;
import com.shanebeestudios.skbee.api.skript.base.Condition;
import org.bukkit.World;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

public class CondIsOwnedByRegion extends Condition {

    public static void register(Registration reg) {
        reg.newCondition(CondIsOwnedByRegion.class,
                "%entities/blocks/locations% (is|are)[neg:n't] owned by current region",
                "chunk at %integer%,[ ]%integer% (in|of) %world% is[neg:n't] owned by current region")
            .name("Folia - Object Owned by Current Region")
            .description("Returns whether the current thread is ticking a region and that the region being ticked owns the " +
                    "entity/block/location/chunk at the specified world/position as included in the specified object.",
                "The chunk pattern accepts Chunk X/Z, not world position.",
                "This is useful to check before manipulating entities/blocks/ect which may not be in the same region as the caller.")
            .examples(
                "on break:",
                "\tif block at location(1,1,1) is owned by current region:",
                "\t\tset block at location(1,1,1) to stone")
            .since("3.10.0")
            .register();
    }

    private int pattern;
    private Expression<?> objects;
    private Expression<Integer> x, z;
    private Expression<World> world;

    @SuppressWarnings("unchecked")
    @Override
    public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
        setNegated(parseResult.hasTag("neg"));
        this.pattern = matchedPattern;
        if (matchedPattern == 0) {
            this.objects = exprs[0];
        } else {
            this.x = (Expression<Integer>) exprs[0];
            this.z = (Expression<Integer>) exprs[1];
            this.world = (Expression<World>) exprs[2];
        }
        return true;
    }


    @Override
    public boolean check(Event event) {
        if (this.pattern == 0) {
            return this.objects.check(event, RegionUtils::isOwnedByCurrentRegion, isNegated());
        } else {
            Integer x = this.x.getSingle(event);
            Integer z = this.z.getSingle(event);
            if (x == null || z == null) return false;
            return this.world.check(event, world -> RegionUtils.isOwnedByCurrentRegion(world, x, z), isNegated());
        }
    }

    @Override
    public String toString(@Nullable Event event, boolean debug) {
        if (this.pattern == 0) {
            String plural = this.objects.isSingle() ? "is" : "are";
            return new SyntaxStringBuilder(event, debug)
                .append(this.objects)
                .append(isNegated() ? plural + " not" : plural)
                .append("owned by current region")
                .toString();
        } else {
            return new SyntaxStringBuilder(event, debug)
                .append("chunk at", this.x, ",", this.z)
                .append("in world", this.world)
                .append(isNegated() ? "is not" : "is")
                .append("owned by current region")
                .toString();
        }
    }

}
