// element.js

export class Element {
    constructor(elementOrTag) {
        if (typeof elementOrTag === 'string') {
            this.element = document.createElement(elementOrTag);
		} else if (elementOrTag instanceof Element) {
			return elementOrTag;
        } else if (elementOrTag instanceof HTMLElement) {
            this.element = elementOrTag;
        } else {
            throw new Error("Element expects a tag name or an HTMLElement.");
        }

		return this;
    }

    setProperty(propertyName, value) {
        this.element[propertyName] = value;
        return this;
    }

    getProperty(propertyName) {
        return this.element[propertyName];
    }

	setText(text) {
		this.setProperty('innerText', text);
		return this;
	}

	getText() {
		return this.getProperty('innerText');
	}

	getValue() {
		return this.element.value;
	}

	setInnerHtml(html) {
		this.setProperty('innerHTML', html);
		return this;
	}
	
	getHtml() {
		return this.getProperty('innerHTML');
	}

    setAttribute(attributeName, value) {
        this.element.setAttribute(attributeName, value);
        return this;
    }

    removeAttribute(attributeName) {
        this.element.removeAttribute(attributeName);
        return this;
    }

    setId(id) {
        this.element.id = id;
        return this;
    }

    addClass(...classNames) {
		if (classNames.length === 1 && classNames[0] instanceof Array) {
			classNames = classNames[0];
			classNames.forEach(className => this.element.classList.add(className));
		} else {
			this.element.classList.add(...classNames);
		}
			
		return this;
    }

    removeClass(...className) {
		if (className.length === 1 && className[0] instanceof Array) {
			className = className[0];
			className.forEach(c => this.element.classList.remove(c));
		} else {
			console.log(className);
			this.element.classList.remove(...className);
		}

        return this;
    }

    appendChild(child) {
		if (child instanceof Array) {
			child.forEach(c => this.appendChild(c));
		} else if (child instanceof Element) {
			this.element.appendChild(child.element);
		} else if (child instanceof HTMLElement) {
			this.element.appendChild(child);
		} else if (typeof child === 'function') {
			this.element.appendChild(child());
		} else {
			throw new Error('appendChild expects an Element, HTMLElement, or function.');
		}

        return this;
    }

	addEventListener(eventType, listener, options) {
		this.element.addEventListener(eventType, listener, options);
		return this;
	}

	appendTo(parent) {
		if (parent instanceof Element) {
			parent.get().appendChild(this.element);
		} else if (parent instanceof HTMLElement) {
			parent.appendChild(this.element);
		}
		return this;
	}

	prependTo(parent) {
		if (parent instanceof Element) {
			parent.get().prepend(this.element);
		} else if (parent instanceof HTMLElement) {
			parent.prepend(this.element);
		}
		return this;
	}

	classList() {
		return this.element.classList;
	}

	get() {
		return this.element;
	}

	remove() {
		this.element.remove();
	}

	clear() {
		this.element.innerHTML = '';
		return this;
	}

}