import { formscreen } from "./formscreen.js";
import { edit_request } from "./edit_request.js";
import { searcher } from "./searcher.js";
import { edit_image_request } from "./edit_image_request.js";

export class product_editor extends formscreen {
    #target;
    #name;
    #description;
    #author;
    #barcode;
    #stock_count;
    #image;
    #loaded_image_type;
    #loaded_image;
    #image_preview;

    constructor(target) {
        super();
        
        this.#target = target;
    }

    get target() {
        return this.#target;
    }

    get _name() {
        return _("product-editor");
    }

    _build_form() {
        this.#loaded_image = null;
        this.#loaded_image_type = null;

        this.#name = this._create_input(
            "name", 
            _("name-prompt"),
            _("name-sample"),
            (input) => {
                input.value = this.#target.name;
            }
        );

        this.#description = this._create_input(
            "description",
            _("description-prompt"),
            _("description-sample"),
            (input) => {
                input.value = this.#target.description;
            }
        );

        this.#author = this._create_input(
            "author",
            _("author-prompt"),
            _("author-sample"),
            (input) => {
                input.value = this.#target.author;
            }
        );

        this.#barcode = this._create_input(
            "barcode",
            _("barcode-prompt"),
            _("barcode-sample"),
            (input) => { 
                input.type = "number"; 
                input.value = this.#target.barcode
            }
        );

        this.#stock_count = this._create_input(
            "stock_count",
            _("stock-count-prompt"),
            _("stock-count-sample"),
            (input) => { 
                input.type = "number"; 
                input.value = this.#target.stock_count
            }
        );

        this._create_input(
            "image",
            _("change-product-image"),
            "",
            (input) => {
                this.#image = input;
                input.type = "file";
                input.accept = "image/*";

                input.addEventListener("change", () => {
                    this.#load_image_from_file();
                });
            }
        );

        this.#image_preview = document.createElement("img");
        this.#image_preview.style.opacity = "1";
        this.#image_preview.src = this.#target.image;
        this._append_child(this.#image_preview);
    }
    
    get #ready_image() {
        return this.#loaded_image;
    }

    #update_image_preview() {
        this.#image_preview.src = (
            "data:" 
            + this.#loaded_image_type 
            + ";base64,"
            + this.#loaded_image
        );
        this.#image_preview.style.opacity = "1";
    }

    #reset_image() {
        this.#loaded_image = null;
        this.#loaded_image_type = null;
        this.#image_preview.style.opacity = "0";
        this.#image_preview.src = "";
    }

    async #load_image_from_file() {
        if (this.#image.files.length === 0) {
            this.#reset_image();
        }

        const file = this.#image.files.item(0);
        const buffer = await file.arrayBuffer();
        let as_string = new String();

        new Uint8Array(buffer).forEach(letter => {
            as_string += String.fromCharCode(letter);
        });

        this.#loaded_image = btoa(as_string);
        this.#loaded_image_type = file.type;
        this.#update_image_preview();
    }

    async #submit() {
        const copy = this.#target.copy();
        copy.name = this.#name();
        copy.description = this.#description();
        copy.author = this.#author();
        copy.barcode = this.#barcode();
        copy.stock_count = this.#stock_count();
        
        const request = new edit_request(this.#target, copy);
        const response = await request.connect();

        if (!response.result) {
            throw new Error(response.cause);
        }

        this.#target = copy;
    }   

    async #image_submit() {
        const image = await this.#ready_image;

        if (image === null) {
            return;
        }

        const request = new edit_image_request(this.#target, image);
        const response = await request.connect();

        if (!response.result) {
            throw new Error(response.cause);
        }
    }

    async _process() {
        try {
            this._info = _("updating-product-data");
            await this.#submit();
            this._info = _("processing-image");
            await this.#image_submit();
            this._success = _("uploaded-successfull");

            searcher.reload();

            setTimeout(() => {
                this.hide();
            }, 500);
        } catch (error) {
            this._error = new String(error);
        }
    }
}   
