import { import_process_fail } from "./import_process_fail.js";
import { product_base } from "./product_base";

export class database {
    #content;
    #processed;
    #on_skip;

    constructor(content) {
        this.#content = content
        this.#processed = new Map();
        this.#on_skip = null;
    }

    #append(target) {
        if (this.#processed.has(target.barcode)) {
            this.#processed.get(target.barcode).stock_count += 1;
            return;
        }

        this.#processed.set(target.barcode, target)
    }

    #validate(target) {
        if (!("id" in target)) {
            throw new Error("One of item has no ID.");
        }

        if (!("title" in target)) {
            throw new Error("Product " + target.barcode + " has no title.")
        }

        if (!("author" in target)) {
            throw new Error("Product " + target.barcode + " has no author.")
        }
    }

    #convert(target) {
        this.#validate(target);

        const product = new product_base();
        product.name = target.title;
        product.description = "";
        product.author = target.author;
        product.stock_count = 1;
        product.barcode = target.id;

        return product;
    }

    on_skip(target) {
        this.#on_skip = target;
        return this;
    }

    process() {
        this.#processed.clear();

        if (!(this.#content instanceof Array)) {
            throw new Error("Database woud be array of objects.")
        }

        this.#content.forEach(count => {
            try {
                const product = this.#convert(count);
                this.#append(product);
            } catch (error) {
                if (this.#on_skip === null) {
                    return ;
                }

                try {
                    this.#on_skip(new import_process_fail(count, error));
                } catch (fail) {
                    console.log(fail);
                }
            }
        });

        return this;
    }

    results() {
        return Array.from(this.#processed.values());
    }
}