export default class ListSettings {
	constructor({ listview, doctype, meta, settings }) {
		if (!doctype) {
			xhiveframework.throw("DocType required");
		}

		this.listview = listview;
		this.doctype = doctype;
		this.meta = meta;
		this.settings = settings;
		this.dialog = null;
		this.fields =
			this.settings && this.settings.fields ? JSON.parse(this.settings.fields) : [];
		this.subject_field = null;

		xhiveframework.model.with_doctype("List View Settings", () => {
			this.make();
			this.get_listview_fields(meta);
			this.setup_fields();
			this.setup_remove_fields();
			this.add_new_fields();
			this.show_dialog();
		});
	}

	make() {
		let me = this;

		let list_view_settings = xhiveframework.get_meta("List View Settings");

		me.dialog = new xhiveframework.ui.Dialog({
			title: __("{0} Settings", [__(me.doctype)]),
			fields: list_view_settings.fields,
		});
		me.dialog.set_values(me.settings);
		me.dialog.set_primary_action(__("Save"), () => {
			let values = me.dialog.get_values();

			xhiveframework.show_alert({
				message: __("Saving"),
				indicator: "green",
			});

			xhiveframework.call({
				method: "xhiveframework.desk.doctype.list_view_settings.list_view_settings.save_listview_settings",
				args: {
					doctype: me.doctype,
					listview_settings: values,
					removed_listview_fields: me.removed_fields || [],
				},
				callback: function (r) {
					me.listview.refresh_columns(r.message.meta, r.message.listview_settings);
					me.dialog.hide();
				},
			});
		});

		me.dialog.fields_dict["total_fields"].df.onchange = () => me.refresh();
	}

	refresh() {
		let me = this;

		me.setup_fields();
		me.add_new_fields();
		me.setup_remove_fields();
	}

	show_dialog() {
		let me = this;

		if (!this.settings.fields) {
			me.update_fields();
		}

		if (!me.dialog.get_value("total_fields")) {
			let field_count = me.fields.length;

			if (field_count < 4) {
				field_count = 4;
			} else if (field_count > 10) {
				field_count = 10;
			}

			me.dialog.set_value("total_fields", field_count);
		}

		me.dialog.show();
	}

	setup_fields() {
		function is_status_field(field) {
			return field.fieldname === "status_field";
		}

		let me = this;

		let fields_html = me.dialog.get_field("fields_html");
		let wrapper = fields_html.$wrapper[0];
		let fields = ``;
		let total_fields = me.dialog.get_values().total_fields || me.settings.total_fields;

		for (let idx in me.fields) {
			if (idx == parseInt(total_fields)) {
				break;
			}
			let is_sortable = idx == 0 ? `` : `sortable`;
			let show_sortable_handle = idx == 0 ? `hide` : ``;
			let can_remove = idx == 0 || is_status_field(me.fields[idx]) ? `hide` : ``;

			fields += `
				<div class="control-input flex align-center form-control fields_order ${is_sortable}"
					style="display: block; margin-bottom: 5px;" data-fieldname="${me.fields[idx].fieldname}"
					data-label="${me.fields[idx].label}" data-type="${me.fields[idx].type}">

					<div class="row">
						<div class="col-1">
							${xhiveframework.utils.icon("drag", "xs", "", "", "sortable-handle " + show_sortable_handle)}
						</div>
						<div class="col-10" style="padding-left:0px;">
							${me.fields[idx].label}
						</div>
						<div class="col-1 ${can_remove}">
							<a class="text-muted remove-field" data-fieldname="${me.fields[idx].fieldname}">
								${xhiveframework.utils.icon("delete", "xs")}
							</a>
						</div>
					</div>
				</div>`;
		}

		fields_html.html(`
			<div class="form-group">
				<div class="clearfix">
					<label class="control-label" style="padding-right: 0px;">Fields</label>
				</div>
				<div class="control-input-wrapper">
				${fields}
				</div>
				<p class="help-box small text-muted">
					<a class="add-new-fields text-muted">
						+ Add / Remove Fields
					</a>
				</p>
			</div>
		`);

		new Sortable(wrapper.getElementsByClassName("control-input-wrapper")[0], {
			handle: ".sortable-handle",
			draggable: ".sortable",
			onUpdate: () => {
				me.update_fields();
				me.refresh();
			},
		});
	}

	add_new_fields() {
		let me = this;

		let fields_html = me.dialog.get_field("fields_html");
		let add_new_fields = fields_html.$wrapper[0].getElementsByClassName("add-new-fields")[0];
		add_new_fields.onclick = () => me.column_selector();
	}

	setup_remove_fields() {
		let me = this;

		let fields_html = me.dialog.get_field("fields_html");
		let remove_fields = fields_html.$wrapper[0].getElementsByClassName("remove-field");

		for (let idx = 0; idx < remove_fields.length; idx++) {
			remove_fields.item(idx).onclick = () =>
				me.remove_fields(remove_fields.item(idx).getAttribute("data-fieldname"));
		}
	}

	remove_fields(fieldname) {
		let me = this;
		let existing_fields = me.fields.map((f) => f.fieldname);

		for (let idx in me.fields) {
			let field = me.fields[idx];

			if (field.fieldname == fieldname) {
				me.fields.splice(idx, 1);
				break;
			}
		}
		me.set_removed_fields(
			me.get_removed_listview_fields(
				me.fields.map((f) => f.fieldname),
				existing_fields
			)
		);
		me.refresh();
		me.update_fields();
	}

	update_fields() {
		let me = this;

		let fields_html = me.dialog.get_field("fields_html");
		let wrapper = fields_html.$wrapper[0];

		let fields_order = wrapper.getElementsByClassName("fields_order");
		me.fields = [];

		for (let idx = 0; idx < fields_order.length; idx++) {
			me.fields.push({
				fieldname: fields_order.item(idx).getAttribute("data-fieldname"),
				label: fields_order.item(idx).getAttribute("data-label"),
			});
		}

		me.dialog.set_value("fields", JSON.stringify(me.fields));
		me.dialog.get_value("fields");
	}

	column_selector() {
		let me = this;

		let d = new xhiveframework.ui.Dialog({
			title: __("{0} Fields", [__(me.doctype)]),
			fields: [
				{
					label: __("Reset Fields"),
					fieldtype: "Button",
					fieldname: "reset_fields",
					click: () => me.reset_listview_fields(d),
				},
				{
					label: __("Select Fields"),
					fieldtype: "MultiCheck",
					fieldname: "fields",
					options: me.get_doctype_fields(
						me.meta,
						me.fields.map((f) => f.fieldname)
					),
					columns: 2,
				},
			],
		});
		d.set_primary_action(__("Save"), () => {
			let values = d.get_values().fields;

			me.set_removed_fields(
				me.get_removed_listview_fields(
					values,
					me.fields.map((f) => f.fieldname)
				)
			);

			me.fields = [];
			me.set_subject_field(me.meta);
			me.set_status_field();

			for (let idx in values) {
				let value = values[idx];

				if (me.fields.length === parseInt(me.dialog.get_values().total_fields)) {
					break;
				} else if (value != me.subject_field.fieldname) {
					let field = xhiveframework.meta.get_docfield(me.doctype, value);
					if (field) {
						me.fields.push({
							label: field.label,
							fieldname: field.fieldname,
						});
					}
				}
			}

			me.refresh();
			me.dialog.set_value("fields", JSON.stringify(me.fields));
			d.hide();
		});
		d.show();
	}

	reset_listview_fields(dialog) {
		let me = this;

		xhiveframework
			.xcall(
				"xhiveframework.desk.doctype.list_view_settings.list_view_settings.get_default_listview_fields",
				{
					doctype: me.doctype,
				}
			)
			.then((fields) => {
				let field = dialog.get_field("fields");
				field.df.options = me.get_doctype_fields(me.meta, fields);
				dialog.refresh();
			});
	}

	get_listview_fields(meta) {
		let me = this;

		if (!me.settings.fields) {
			me.set_list_view_fields(meta);
		} else {
			me.fields = JSON.parse(this.settings.fields);
		}

		me.fields.uniqBy((f) => f.fieldname);
	}

	set_list_view_fields(meta) {
		let me = this;

		me.set_subject_field(meta);
		me.set_status_field();

		meta.fields.forEach((field) => {
			if (
				field.in_list_view &&
				!xhiveframework.model.no_value_type.includes(field.fieldtype) &&
				me.subject_field.fieldname != field.fieldname
			) {
				me.fields.push({
					label: field.label,
					fieldname: field.fieldname,
				});
			}
		});
	}

	set_subject_field(meta) {
		let me = this;

		me.subject_field = {
			label: "ID",
			fieldname: "name",
		};

		if (meta.title_field) {
			let field = xhiveframework.meta.get_docfield(me.doctype, meta.title_field.trim());

			me.subject_field = {
				label: field.label,
				fieldname: field.fieldname,
			};
		}

		me.fields.push(me.subject_field);
	}

	set_status_field() {
		let me = this;

		if (xhiveframework.has_indicator(me.doctype)) {
			me.fields.push({
				type: "Status",
				label: "Status",
				fieldname: "status_field",
			});
		}
	}

	get_doctype_fields(meta, fields) {
		let multiselect_fields = [];

		meta.fields.forEach((field) => {
			if (!xhiveframework.model.no_value_type.includes(field.fieldtype)) {
				multiselect_fields.push({
					label: field.label,
					value: field.fieldname,
					checked: fields.includes(field.fieldname),
				});
			}
		});

		return multiselect_fields;
	}

	get_removed_listview_fields(new_fields, existing_fields) {
		let me = this;
		let removed_fields = [];

		if (xhiveframework.has_indicator(me.doctype)) {
			new_fields.push("status_field");
		}

		existing_fields.forEach((column) => {
			if (!new_fields.includes(column)) {
				removed_fields.push(column);
			}
		});

		return removed_fields;
	}

	set_removed_fields(fields) {
		let me = this;

		if (me.removed_fields) {
			me.removed_fields = me.removed_fields.concat(fields);
		} else {
			me.removed_fields = fields;
		}
	}
}
