import { TypeEditor } from "../TypeEditor.js";
import { StringEditor } from "./primitive/StringEditor.js";
import ObservedString from "../../../../src/core/model/ObservedString.js";
import { ObservedStringEditor } from "./ObservedStringEditor.js";
import EmptyView from "../../../../src/view/elements/EmptyView.js";
import LabelView from "../../../../src/view/common/LabelView.js";
import { MouseEvents } from "../../../../src/engine/input/devices/events/MouseEvents.js";
import Signal from "../../../../src/core/events/signal/Signal.js";

/**
 * If path is larger than this - it will be truncated and displayed as non-input
 * @readonly
 * @type {number}
 */
const MAX_PATH_LENGTH_EDITABLE = 256;
/**
 * How long to crop to
 * @readonly
 * @type {number}
 */
const MAX_CROP_LENGTH = 32;

export class LargeStringEditor extends TypeEditor {
    inline = true;

    build(parent, field, registry) {
        let url_editor;

        if (field.type === String) {

            url_editor = new StringEditor();

        } else if (field.type === ObservedString) {

            url_editor = new ObservedStringEditor();

        } else {
            throw new Error(`Unsupported type`);
        }

        let in_focus = false;

        const vEditor = url_editor.build(parent, field, registry);

        const truncated_url = new ObservedString('');
        const vTruncated = new LabelView(truncated_url);

        vTruncated.el.addEventListener(MouseEvents.Click, () => {
            in_focus = true;
            update();
            vEditor.el.focus();
        });
        vEditor.el.addEventListener('focusin', () => {
            in_focus = true;
            update();
        });
        vEditor.el.addEventListener('blur', () => {
            in_focus = false;
            update();
        });

        const r = new EmptyView();

        function update() {
            const url = field.adapter.read(parent, field.name);

            if (typeof url === "string" && url.length > MAX_PATH_LENGTH_EDITABLE && !in_focus) {
                r.removeChild(vEditor);

                truncated_url.set('[...]'+url.slice(0, MAX_CROP_LENGTH));

                if (!r.hasChild(vTruncated)) {
                    r.addChild(vTruncated);
                }

            } else if(!r.hasChild(vEditor)){
                r.removeChild(vTruncated);
                r.addChild(vEditor);
            }
        }

        const input_changed = new Signal();

        vEditor.el.addEventListener('input', () => {

            const value = vEditor.el.value;

            input_changed.send1(value);

            update();
        });
        r.on.linked.add(update);

        return {
            view: r, signals: {
                input_changed
            },
            methods: {
                set_value(v) {
                    field.adapter.write(parent, field.name, v);
                    update();
                    vEditor.el.value = v;
                }
            }
        };
    }
}
