// <select> widget with all fields of a pagetype as options
jingrow.ui.FieldSelect = class FieldSelect {
	// opts parent, pagetype, filter_fields, with_blank, select
	constructor(opts) {
		var me = this;
		$.extend(this, opts);
		this.fields_by_name = {};
		this.options = [];
		this.$input = $('<input class="form-control">')
			.appendTo(this.parent)
			.on("click", function () {
				$(this).select();
			});
		this.input_class && this.$input.addClass(this.input_class);
		this.select_input = this.$input.get(0);
		this.awesomplete = new Awesomplete(this.select_input, {
			minChars: 0,
			maxItems: 99,
			autoFirst: true,
			list: me.options,
			item(item) {
				return $(repl('<li class="filter-field-select"><p>%(label)s</p></li>', item))
					.data("item.autocomplete", item)
					.get(0);
			},
		});
		this.$input.on("awesomplete-select", function (e) {
			var o = e.originalEvent;
			var value = o.text.value;
			var item = me.awesomplete.get_item(value);
			me.selected_pagetype = item.pagetype;
			me.selected_fieldname = item.fieldname;
			if (me.select) me.select(item.pagetype, item.fieldname);
		});
		this.$input.on("awesomplete-selectcomplete", function (e) {
			var o = e.originalEvent;
			var value = o.text.value;
			var item = me.awesomplete.get_item(value);
			me.$input.val(item.label);
		});

		if (this.filter_fields) {
			for (var i in this.filter_fields) this.add_field_option(this.filter_fields[i]);
		} else {
			this.build_options();
		}
		this.set_value(this.pagetype, "name");
	}
	get_value() {
		return this.selected_pagetype
			? this.selected_pagetype + "." + this.selected_fieldname
			: null;
	}
	val(value) {
		if (value === undefined) {
			return this.get_value();
		} else {
			this.set_value(value);
		}
	}
	clear() {
		this.selected_pagetype = null;
		this.selected_fieldname = null;
		this.$input.val("");
	}
	set_value(pagetype, fieldname) {
		var me = this;
		this.clear();
		if (!pagetype) return;

		// old style
		if (pagetype.indexOf(".") !== -1) {
			var parts = pagetype.split(".");
			pagetype = parts[0];
			fieldname = parts[1];
		}

		$.each(this.options, function (i, v) {
			if (v.pagetype === pagetype && v.fieldname === fieldname) {
				me.selected_pagetype = pagetype;
				me.selected_fieldname = fieldname;
				me.$input.val(v.label);
				return false;
			}
		});
	}
	build_options() {
		var me = this;
		me.table_fields = [];
		var std_filters = $.map(jingrow.model.std_fields, function (d) {
			var opts = { parent: me.pagetype };
			if (d.fieldname == "name") opts.options = me.pagetype;
			return $.extend(copy_dict(d), opts);
		});

		// add parenttype column
		var pagetype_obj = locals["PageType"][me.pagetype];
		if (pagetype_obj && cint(pagetype_obj.istable)) {
			std_filters = std_filters.concat([
				{
					fieldname: "parent",
					fieldtype: "Data",
					label: "Parent",
					parent: me.pagetype,
				},
			]);
		}

		// blank
		if (this.with_blank) {
			this.options.push({
				label: "",
				value: "",
			});
		}

		// main table
		var main_table_fields = std_filters.concat(jingrow.meta.pagefield_list[me.pagetype]);
		$.each(jingrow.utils.sort(main_table_fields, "label", "string"), function (i, df) {
			let pagetype =
				jingrow.get_meta(me.pagetype).istable && me.parent_pagetype
					? me.parent_pagetype
					: me.pagetype;

			// show fields where user has read access and if report hide flag is not set
			if (jingrow.perm.has_perm(pagetype, df.permlevel, "read")) me.add_field_option(df);
		});

		// child tables
		$.each(me.table_fields, function (i, table_df) {
			if (table_df.options) {
				let child_table_fields = [].concat(jingrow.meta.pagefield_list[table_df.options]);

				if (table_df.fieldtype === "Table MultiSelect") {
					const link_field = jingrow.meta
						.get_pagefields(table_df.options)
						.find((df) => df.fieldtype === "Link");
					child_table_fields = link_field ? [link_field] : [];
				}

				$.each(jingrow.utils.sort(child_table_fields, "label", "string"), function (i, df) {
					let pagetype =
						jingrow.get_meta(me.pagetype).istable && me.parent_pagetype
							? me.parent_pagetype
							: me.pagetype;

					// show fields where user has read access and if report hide flag is not set
					if (jingrow.perm.has_perm(pagetype, df.permlevel, "read"))
						me.add_field_option(df);
				});
			}
		});
	}

	add_field_option(df) {
		let me = this;

		if (df.fieldname == "pagestatus" && !jingrow.model.is_submittable(me.pagetype)) return;

		if (jingrow.model.table_fields.includes(df.fieldtype)) {
			me.table_fields.push(df);
			return;
		}

		let label = null;
		let table = null;

		if (me.pagetype && df.parent == me.pagetype) {
			label = __(df.label, null, df.parent);
			table = me.pagetype;
		} else {
			label = __(df.label, null, df.parent) + " (" + __(df.parent) + ")";
			table = df.parent;
		}

		if (
			jingrow.model.no_value_type.indexOf(df.fieldtype) == -1 &&
			!(me.fields_by_name[df.parent] && me.fields_by_name[df.parent][df.fieldname])
		) {
			this.options.push({
				label: label,
				value: table + "." + df.fieldname,
				fieldname: df.fieldname,
				pagetype: df.parent,
			});
			if (!me.fields_by_name[df.parent]) me.fields_by_name[df.parent] = {};
			me.fields_by_name[df.parent][df.fieldname] = df;
		}
	}
};
