// zig fmt: off
const std = @import("std");
const json_utils = @import("../json_utils.zig");
const Store = @import("../store.zig");
const Item = @import("./item.zig");

const Equipment = @This();

pub const UtilitySlot = struct {
    id: Store.Id,
    quantity: u64,

    fn parse(store: *Store, obj: std.json.ObjectMap, name: []const u8, quantity: []const u8) !?UtilitySlot {
        const item_code = try json_utils.getStringRequired(obj, name);
        if (item_code.len == 0) {
            return null;
        }

        return UtilitySlot{
            .id = try store.items.getOrReserveId(item_code),
            .quantity = try json_utils.getPositiveIntegerRequired(obj, quantity),
        };
    }
};

pub const Slot = enum {
    weapon,
    shield,
    helmet,
    body_armor,
    leg_armor,
    boots,
    ring1,
    ring2,
    amulet,
    artifact1,
    artifact2,
    utility1,
    utility2,

    fn name(self: Slot) []const u8 {
        return switch (self) {
            .weapon => "weapon",
            .shield => "shield",
            .helmet => "helmet",
            .body_armor => "body_armor",
            .leg_armor => "leg_armor",
            .boots => "boots",
            .ring1 => "ring1",
            .ring2 => "ring2",
            .amulet => "amulet",
            .artifact1 => "artifact1",
            .artifact2 => "artifact2",
            .utility1 => "utility1",
            .utility2 => "utility2",
        };
    }
};

weapon: ?Store.Id,
shield: ?Store.Id,
helmet: ?Store.Id,
body_armor: ?Store.Id,
leg_armor: ?Store.Id,
boots: ?Store.Id,

ring1: ?Store.Id,
ring2: ?Store.Id,
amulet: ?Store.Id,

artifact1: ?Store.Id,
artifact2: ?Store.Id,
artifact3: ?Store.Id,

utility1: ?UtilitySlot,
utility2: ?UtilitySlot,

pub fn parse(store: *Store, obj: std.json.ObjectMap) !Equipment {
    const weapon = try json_utils.getStringRequired(obj, "weapon_slot");
    const shield = try json_utils.getStringRequired(obj, "shield_slot");
    const helmet = try json_utils.getStringRequired(obj, "helmet_slot");
    const body_armor = try json_utils.getStringRequired(obj, "body_armor_slot");
    const leg_armor = try json_utils.getStringRequired(obj, "leg_armor_slot");
    const boots = try json_utils.getStringRequired(obj, "boots_slot");
    const ring1 = try json_utils.getStringRequired(obj, "ring1_slot");
    const ring2 = try json_utils.getStringRequired(obj, "ring2_slot");
    const amulet = try json_utils.getStringRequired(obj, "amulet_slot");
    const artifact1 = try json_utils.getStringRequired(obj, "artifact1_slot");
    const artifact2 = try json_utils.getStringRequired(obj, "artifact2_slot");
    const artifact3 = try json_utils.getStringRequired(obj, "artifact3_slot");

    return Equipment{
        .weapon = try store.items.getOrReserveId(weapon),
        .shield = try store.items.getOrReserveId(shield),
        .helmet = try store.items.getOrReserveId(helmet),
        .body_armor = try store.items.getOrReserveId(body_armor),
        .leg_armor = try store.items.getOrReserveId(leg_armor),
        .boots = try store.items.getOrReserveId(boots),
        .ring1 = try store.items.getOrReserveId(ring1),
        .ring2 = try store.items.getOrReserveId(ring2),
        .amulet = try store.items.getOrReserveId(amulet),
        .artifact1 = try store.items.getOrReserveId(artifact1),
        .artifact2 = try store.items.getOrReserveId(artifact2),
        .artifact3 = try store.items.getOrReserveId(artifact3),
        .utility1 = try UtilitySlot.parse(store, obj, "utility1_slot", "utility1_slot_quantity"),
        .utility2 = try UtilitySlot.parse(store, obj, "utility2_slot", "utility2_slot_quantity"),
    };
}
