// zig fmt: off
const Api = @import("artifacts-api");
const Artificer = @import("./root.zig");
const Requirements = Artificer.Requirements;

const Goal = @This();

item: Api.Store.Id,
quantity: u64,

fn getCraftMultiples(self: Goal, craft: Api.Craft) u64 {
    return @intFromFloat(@ceil(
        @as(f32, @floatFromInt(self.quantity)) /
        @as(f32, @floatFromInt(craft.quantity))
    ));
}

pub fn tick(self: *Goal, goal_id: Artificer.GoalId, artificer: *Artificer) !void {
    const store = artificer.server.store;
    const character = store.characters.get(artificer.character).?;

    if (self.quantity == 0) {
        artificer.removeGoal(goal_id);
        return;
    }

    const item = store.items.get(self.item).?;
    const craft = item.craft.?;

    const skill = craft.skill.toCharacterSkill();
    if (character.skills.get(skill).level < craft.level) {
        return error.SkillTooLow;
    }

    const workshop_position = artificer.findNearestWorkstation(craft.skill).?;
    if (!workshop_position.eql(character.position)) {
        artificer.queued_actions.appendAssumeCapacity(.{
            .goal = goal_id,
            .action = .{ .move = workshop_position }
        });
        return;
    }

    artificer.queued_actions.appendAssumeCapacity(.{
        .goal = goal_id,
        .action = .{ .craft = .{ .item = self.item, .quantity = self.quantity } }
    });
}

pub fn requirements(self: Goal, artificer: *Artificer) Artificer.Requirements {
    var reqs: Artificer.Requirements = .{};

    const store = artificer.server.store;
    const item = store.items.get(self.item).?;
    const craft = item.craft.?;
    const craft_multiples = self.getCraftMultiples(craft);

    for (craft.items.slice()) |craft_item| {
        reqs.items.addAssumeCapacity(craft_item.id, craft_item.quantity * craft_multiples);
    }

    return reqs;
}

pub fn onActionCompleted(self: *Goal, goal_id: Artificer.GoalId, result: Artificer.ActionResult) void {
    _ = goal_id;

    if (result == .craft) {
        const craft_result = result.craft;
        const craft_quantity = craft_result.details.items.getQuantity(self.item);

        if (self.quantity > craft_quantity) {
            self.quantity -= craft_quantity;
        } else {
            self.quantity = 0;
        }
    }
}
