import { Connector, Connection, Node, NodeEditorTestData } from "../index";

export class InputConnector extends Connector{
    
    /**
     * The input element in the dom.
     */
    protected inputElement: HTMLElement;

    /**
     * The connection if connected to an another node, othervise null.
     */
    protected connection: Connection|null;

    constructor(node: Node, key: string, data: Record<string, string>, value: string){     
        super(node, key, data);
        this.element = document.createElement("div");
        this.element.innerHTML = data.name || key;
        this.element.className = "e-node-in";
        this.inputElement = this.createInput(key,data, value);
        this.element.appendChild(this.inputElement);
        
        let circle = document.createElement("div");
        circle.className = "e-node-connector";
        circle.style.background = this.getColor();
        this.element.appendChild(circle);
        this.node.element.appendChild(this.element);
        this.node.inputs[key] = this;
        this.element.addEventListener("mouseup", this.handleMouseUp.bind(this));
        this.element.addEventListener("mousedown", this.handleMouseDown.bind(this));
    }
    
    /**
     * Handles when a drag starts from this connector.
     * @param event The mouse event.
     */
    handleMouseDown(event: MouseEvent){
        if(event.target instanceof HTMLInputElement){
            return;
        }
        if(this.connection){
            new Connection(this.connection.getSource(), null);
            this.connection.remove();
        }else{
            new Connection(null, this);
        }
        event.stopPropagation();
    }
    
    /**
     * Creates the input element
     * @param key Technical name of the input. It will be displayed for the placeholder too.
     * @param data 
     * @param value 
     * @returns 
     */
    public createInput(key: string, data: Record<string, string>, value: string): HTMLElement{
        const input = document.createElement("input");
        if(value){
            input.setAttribute("value", value || '');
        }
        input.setAttribute("placeholder", key);
        return input;
    }
    
    /**
     * Gets the value of the input field.
     * @returns The value set by the user.
     */
    public getValue(){
        return (this.inputElement as HTMLInputElement).value || null;
    }

    public override getTestData(): NodeEditorTestData {
        if(this.connection){
            return this.connection.getSource().getTestData();
        }else{
            return {
                isTrimmed: false,
                value: this.getValue()
            }
        }
    }
    
    public override addConnection(connection: Connection){
        this.element.classList.add('e-node-connected');
        this.connection = connection;
    }
    
    public override removeConnection(connection: Connection){
        if(this.connection === connection){
            this.element.classList.remove('e-node-connected');
            this.connection = null;
        }
    }
    
    public override update(){
        if(this.connection){
            this.connection.update();
        }
    }

    public override remove(): void {
        this.connection?.remove();
    }

    /**
     * Returns the connection if exisits
     * @returns the connection or null
     */
    public getConnection(): Connection|null{
        return this.connection;
    }
}