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

const GEOrder = @This();

pub const max_id_size = 32;
pub const Id = std.BoundedArray(u8, max_id_size);
pub const Account = Character.Account;
pub const Code = Item.Code;

id: Id,
seller: Account,
item_id: Store.Id,
quantity: u64,
price: u64,
created_at: f64,

pub fn parse(store: *Store, obj: std.json.ObjectMap) !GEOrder {
    const id = try json_utils.getStringRequired(obj, "id");
    const seller = try json_utils.getStringRequired(obj, "seller");
    const code = try json_utils.getStringRequired(obj, "code");
    const quantity = try json_utils.getPositiveIntegerRequired(obj, "quantity");
    const price = try json_utils.getPositiveIntegerRequired(obj, "price");
    const created_at = try json_utils.getStringRequired(obj, "created_at");

    return GEOrder{
        .id = try Id.fromSlice(id),
        .seller = try Account.fromSlice(seller),
        .item_id = try store.items.getOrReserveId(code),
        .quantity = quantity,
        .price = price,
        .created_at = parseDateTime(created_at) orelse return error.InvalidDataTime,
    };
}

pub fn parseAndAppend(store: *Store, obj: std.json.ObjectMap) !Store.Id {
    return try store.ge_orders.appendOrUpdate(try parse(store, obj));
}
