import { useStore } from "./store";

export function create_layout(fields) {
	let store = useStore();

	let layout = {
		tabs: [],
	};

	let tab = null,
		section = null,
		column = null;

	function set_tab(df) {
		tab = get_new_tab(df);
		column = null;
		section = null;
		layout.tabs.push(tab);
	}

	function set_section(df) {
		if (!tab) set_tab();

		section = get_new_section(df, tab);
		column = null;
		tab.sections.push(section);
	}

	function set_column(df) {
		if (!section) set_section();

		column = get_new_column(df);
		section.columns.push(column);
	}

	function get_new_tab(df) {
		let _tab = {};
		_tab.df = df || store.get_df("Tab Break", "", __("Details"));
		_tab.sections = [];
		_tab.is_first = !df;
		return _tab;
	}

	function get_new_section(df) {
		let _section = {};
		_section.df = df || store.get_df("Section Break");
		_section.columns = [];
		_section.is_first = !df;
		return _section;
	}

	function get_new_column(df) {
		let _column = {};
		_column.df = df || store.get_df("Column Break");
		_column.fields = [];
		_column.is_first = !df;
		return _column;
	}

	for (let df of fields) {
		if (df.fieldname) {
			// make a copy to avoid mutation bugs
			df = JSON.parse(JSON.stringify(df));
		}

		if (df.fieldtype === "Tab Break") {
			set_tab(df);
		} else if (df.fieldtype === "Section Break") {
			set_section(df);
		} else if (df.fieldtype === "Column Break") {
			set_column(df);
		} else {
			if (!column) set_column();

			let field = { df: df };

			if (df.fieldtype === "Table") {
				field.table_columns = get_table_columns(df);
			}

			column.fields.push(field);
			section.has_fields = true;
		}
	}

	// remove empty sections
	for (let tab of layout.tabs) {
		for (let i = tab.sections.length - 1; i >= 0; --i) {
			let section = tab.sections[i];
			if (!section.has_fields) {
				tab.sections.splice(tab.sections.indexOf(section), 1);
			}
		}
	}

	return layout;
}

export async function load_doctype_model(doctype) {
	await xhiveframework.call("xhiveframework.desk.form.load.getdoctype", { doctype });
}

export async function get_table_columns(df, child_doctype) {
	let table_columns = [];

	if (!xhiveframework.get_meta(df.options)) {
		await load_doctype_model(df.options);
	}
	if (!child_doctype) {
		child_doctype = xhiveframework.get_meta(df.options);
	}

	let table_fields = child_doctype.fields;
	let total_colsize = 1;
	table_columns.push([
		{
			label: __("No."),
		},
		1,
	]);
	for (let tf of table_fields) {
		if (!xhiveframework.model.layout_fields.includes(tf.fieldtype) && tf.in_list_view && tf.label) {
			let colsize;

			if (tf.columns) {
				colsize = tf.columns;
			} else {
				colsize = update_default_colsize(tf);
			}

			if (total_colsize > 11 + colsize) {
				continue;
			} else {
				total_colsize += colsize;
				table_columns.push([
					{
						label: tf.label,
						fieldname: tf.fieldname,
						fieldtype: tf.fieldtype,
					},
					colsize,
				]);
			}
		}
	}

	// adjust by increasing column width
	adjust_column_size(total_colsize, true);

	// adjust by decreasing column width
	adjust_column_size(total_colsize);

	function adjust_column_size(total_colsize, increase) {
		let passes = 0;
		let start_condition = increase ? total_colsize < 11 : total_colsize >= 11;

		while (start_condition && passes < 11) {
			for (var i in table_columns) {
				var _df = table_columns[i][0];
				var colsize = table_columns[i][1];
				if (colsize > 1 && colsize < 11 && xhiveframework.model.is_non_std_field(_df.fieldname)) {
					if (
						passes < 3 &&
						["Int", "Currency", "Float", "Check", "Percent"].indexOf(_df.fieldtype) !==
							-1
					) {
						// don't increase/decrease col size of these fields in first 3 passes
						continue;
					}

					if (increase) {
						table_columns[i][1] += 1;
						total_colsize++;
					} else {
						table_columns[i][1] -= 1;
						total_colsize--;
					}
				}

				if (increase && total_colsize > 9) break;
				if (!increase && total_colsize < 11) break;
			}
			passes++;
		}
	}

	function update_default_colsize(_df) {
		let colsize = 2;
		switch (_df.fieldtype) {
			case "Text":
				break;
			case "Small Text":
				colsize = 3;
				break;
			case "Check":
				colsize = 1;
		}
		return colsize;
	}
	return table_columns;
}

export function evaluate_depends_on_value(expression, doc) {
	let store = useStore();
	if (!doc) return;

	let out = null;
	let parent = store.doc;

	if (typeof expression === "boolean") {
		out = expression;
	} else if (typeof expression === "function") {
		out = expression(doc);
	} else if (expression.substr(0, 5) == "eval:") {
		try {
			out = xhiveframework.utils.eval(expression.substr(5), { doc, parent });
			if (parent && parent.istable && expression.includes("is_submittable")) {
				out = true;
			}
		} catch (e) {
			xhiveframework.throw(__('Invalid "depends_on" expression'));
		}
	} else {
		var value = doc[expression];
		if ($.isArray(value)) {
			out = !!value.length;
		} else {
			out = !!value;
		}
	}

	return out;
}

export function section_boilerplate() {
	let store = useStore();

	return {
		df: store.get_df("Section Break"),
		columns: [
			{
				df: store.get_df("Column Break"),
				fields: [],
			},
		],
	};
}

export function move_children_to_parent(props, parent, child, current_container) {
	let store = useStore();

	let children = props[parent][child + "s"];
	let index = children.indexOf(props[child]);

	if (index > 0) {
		const name = parent.charAt(0).toUpperCase() + parent.slice(1);
		// move current children and children after that to a new column
		let new_parent = {
			df: store.get_df(name + " Break"),
			[child + "s"]: children.splice(index),
		};

		// add new parent after current parent
		let parents = current_container[parent + "s"];
		let parent_index = parents.indexOf(props[parent]);
		parents.splice(parent_index + 1, 0, new_parent);

		// remove current child and after that
		children.splice(index + 1);

		return new_parent.df.name;
	}
}

export function scrub_field_names(fields) {
	fields.forEach((d) => {
		if (d.fieldtype) {
			if (!d.fieldname) {
				if (d.label) {
					d.fieldname = d.label.trim().toLowerCase().replaceAll(" ", "_");
					if (d.fieldname.endsWith("?")) {
						d.fieldname = d.fieldname.slice(0, -1);
					}
					if (xhiveframework.model.restricted_fields.includes(d.fieldname)) {
						d.fieldname = d.fieldname + "1";
					}
					if (d.fieldtype == "Section Break") {
						d.fieldname = d.fieldname + "_section";
					} else if (d.fieldtype == "Column Break") {
						d.fieldname = d.fieldname + "_column";
					} else if (d.fieldtype == "Tab Break") {
						d.fieldname = d.fieldname + "_tab";
					}
				} else {
					d.fieldname =
						d.fieldtype.toLowerCase().replaceAll(" ", "_") +
						"_" +
						xhiveframework.utils.get_random(4);
				}
			} else {
				if (xhiveframework.model.restricted_fields.includes(d.fieldname)) {
					xhiveframework.throw(__("Fieldname {0} is restricted", [d.fieldname]));
				}
			}
			let regex = new RegExp(/['",./%@()<>{}]/g);
			d.fieldname = d.fieldname.replace(regex, "");
			// fieldnames should be lowercase
			d.fieldname = d.fieldname.toLowerCase();
		}

		// unique is automatically an index
		if (d.unique) {
			d.search_index = 0;
		}
	});

	return fields;
}

export function clone_field(field) {
	let cloned_field = JSON.parse(JSON.stringify(field));
	cloned_field.df.name = xhiveframework.utils.get_random(8);
	return cloned_field;
}

export function confirm_dialog(
	title,
	message,
	primary_action,
	primary_action_label,
	secondary_action,
	secondary_action_label
) {
	let d = new xhiveframework.ui.Dialog({
		title: title,
		primary_action_label: primary_action_label || __("Yes"),
		primary_action: () => {
			primary_action && primary_action();
			d.hide();
		},
		secondary_action_label: secondary_action_label || __("No"),
		secondary_action: () => {
			secondary_action && secondary_action();
			d.hide();
		},
	});
	d.show();
	d.set_message(message);
}

export function is_touch_screen_device() {
	return "ontouchstart" in document.documentElement;
}
