class FolderPathBuilder extends BaseComponent {
	constructor (importList) {
		super();
		this._importList = importList;
		this._initialFolderPathSpec = MiscUtil.copy(importList.folderPathSpec);

		this._lock = new VeLock();
		this._childComps = [];
		this._$wrpRows = null;
	}

	render ($parent) {
		$parent.empty();

		const pod = this.getPod();

		this._$wrpRows = $$`<div class="flex-col w-100 h-100 overflow-y-auto relative"></div>`;
		this._childComps.forEach(it => it.render(this._$wrpRows, pod));
		this._render_checkAddEmptyMessage();

		const $btnAdd = $(`<button title="Add Path Part" class="btn btn-5et btn-xs"><span class="fas fa-plus"></span></button>`)
			.click(() => {
				if (this._childComps.length >= 3) return ui.notifications.warn(`Foundry currently supports a maximum of three levels of directory nesting. T-too deep!`);
				this._render_addRow(pod);
			});

		this._initialFolderPathSpec.forEach(state => this._render_addRow(pod, state));

		$$($parent)`
			<div class="w-100 split-v-center mb-1"><div>Folder Path:</div>${$btnAdd}</div>
			${this._$wrpRows}
		`
	}

	async _render_updateParentPath () {
		await (this._lock.pLock());
		await this._importList.pSetFolderPathSpec(this._childComps.map(it => MiscUtil.copy(it._state)));
		this._lock.unlock();
	}

	_render_addRow (pod, state) {
		const folderMeta = this._importList.getFolderPathMeta();
		const comp = new FolderPathBuilderRow(folderMeta);
		if (state) Object.assign(comp.__state, state);

		comp._addHookAll("state", () => this._render_updateParentPath());

		if (!this._childComps.length) this._$wrpRows.empty();

		this._childComps.push(comp);
		comp.render(this._$wrpRows, pod);
		this._render_updateParentPath();
	}

	_swapRowPositions (ixA, ixB) {
		const a = this._childComps[ixA];
		this._childComps[ixA] = this._childComps[ixB];
		this._childComps[ixB] = a;

		this._childComps.forEach(it => it.$row.detach().appendTo(this._$wrpRows));
		this._render_updateParentPath();
	}

	_removeRow (comp) {
		const ix = this._childComps.indexOf(comp);
		if (~ix) {
			this._childComps.splice(ix, 1);
			comp.$row.remove();
			this._render_updateParentPath();
		}

		this._render_checkAddEmptyMessage();
	}

	_render_checkAddEmptyMessage () {
		if (!this._childComps.length) this._$wrpRows.append(`<div class="flex-v-center w-100 my-1"><i>(Directory root)</i></div>`);
	}

	getPod () {
		const pod = super.getPod();
		pod.swapRowPositions = this._swapRowPositions.bind(this);
		pod.removeRow = this._removeRow.bind(this);
		pod.$getChildren = () => this._childComps.map(it => it.$row);
		return pod;
	}
}

class FolderPathBuilderRow extends BaseComponent {
	constructor (folderMeta) {
		super(folderMeta);
		this._folderMeta = folderMeta;
		this._$row = null;
	}

	get $row () { return this._$row; }

	render ($parent, parent) {
		this._parent = parent;

		const $btnToggleFreeText = ComponentUiUtil.$getBtnBool(this, "isFreeText", {$ele: $(`<button class="btn btn-xs mr-1">Custom</button>`)});

		const $iptName = ComponentUiUtil.$getIptStr(this, "text").attr("type", "text");
		const $wrpFreeText = $$`<div class="flex mr-1 w-100">${$iptName}</div>`;

		const folderMetaKeys = Object.keys(this._folderMeta)
			.sort((a, b) => SortUtil.ascSortLower(this._folderMeta[a].label, this._folderMeta[b].label));
		const $selProp = ComponentUiUtil.$getSelEnum(
			this,
			"selectedProp",
			{
				values: folderMetaKeys,
				isAllowNull: true,
				fnDisplay: (k) => this._folderMeta[k].label,
			},
		);
		const $wrpSelProp = $$`<div class="flex mr-1 w-100">${$selProp}</div>`;

		const hookFreeText = () => {
			$wrpFreeText.toggleClass("ve-hidden", !this._state.isFreeText);
			$wrpSelProp.toggleClass("ve-hidden", this._state.isFreeText);
		};
		hookFreeText();
		this._addHookBase("isFreeText", hookFreeText);

		const $btnRemove = $(`<button class="btn btn-danger btn-xs"><span class="fas fa-trash"></span></button>`)
			.click(() => {
				const {removeRow} = this._parent;
				removeRow(this);
			});

		this._$row = $$`<div class="flex-v-center w-100 my-1">
			${$btnToggleFreeText}
			${$wrpFreeText}
			${$wrpSelProp}
			${DragReorderUiUtil.$getDragPad2(() => this._$row, $parent, this._parent)}
			${$btnRemove}
		</div>`.appendTo($parent);
	}

	_getDefaultState () { return {...FolderPathBuilderRow._DEFAULT_STATE}; }

	static getStateFromString (str) {
		const comp = new FolderPathBuilderRow();
		comp.__state.text = str;
		return comp.__state;
	}
}
FolderPathBuilderRow._DEFAULT_STATE = {
	isFreeText: true,
	text: "",
	selectedProp: null,
};

export {FolderPathBuilder, FolderPathBuilderRow};
