jingrow.provide("jingrow.ui.form");

jingrow.quick_edit = function (pagetype, name) {
	jingrow.db.get_pg(pagetype, name).then((pg) => {
		jingrow.ui.form.make_quick_entry(pagetype, null, null, pg);
	});
};

jingrow.ui.form.make_quick_entry = (pagetype, after_insert, init_callback, pg, force) => {
	var trimmed_pagetype = pagetype.replace(/ /g, "");
	var controller_name = "QuickEntryForm";

	if (jingrow.ui.form[trimmed_pagetype + "QuickEntryForm"]) {
		controller_name = trimmed_pagetype + "QuickEntryForm";
	}

	jingrow.quick_entry = new jingrow.ui.form[controller_name](
		pagetype,
		after_insert,
		init_callback,
		pg,
		force
	);
	return jingrow.quick_entry.setup();
};

jingrow.ui.form.QuickEntryForm = class QuickEntryForm {
	constructor(pagetype, after_insert, init_callback, pg, force) {
		this.pagetype = pagetype;
		this.after_insert = after_insert;
		this.init_callback = init_callback;
		this.pg = pg;
		this.force = force ? force : false;
	}

	setup() {
		return new Promise((resolve) => {
			jingrow.model.with_pagetype(this.pagetype, () => {
				this.check_quick_entry_pg();
				this.set_meta_and_mandatory_fields();
				if (this.is_quick_entry() || this.force) {
					this.render_dialog();
					resolve(this);
				} else {
					// no quick entry, open full form
					jingrow.quick_entry = null;
					jingrow
						.set_route("Form", this.pagetype, this.pg.name)
						.then(() => resolve(this));
					// call init_callback for consistency
					if (this.init_callback) {
						this.init_callback(this.pg);
					}
				}
			});
		});
	}

	set_meta_and_mandatory_fields() {
		this.meta = jingrow.get_meta(this.pagetype);
		let fields = this.meta.fields;

		this.mandatory = fields.filter((df) => {
			return (
				(df.reqd || df.allow_in_quick_entry) &&
				!df.read_only &&
				!df.is_virtual &&
				df.fieldtype !== "Tab Break"
			);
		});
	}

	check_quick_entry_pg() {
		if (!this.pg) {
			this.pg = jingrow.model.get_new_pg(this.pagetype, null, null, true);
		}
	}

	is_quick_entry() {
		if (this.meta.quick_entry != 1) {
			return false;
		}

		this.validate_for_prompt_autoname();

		if (this.has_child_table() || !this.mandatory.length) {
			return false;
		}

		return true;
	}

	too_many_mandatory_fields() {
		if (this.mandatory.length > 7) {
			// too many fields, show form
			return true;
		}
		return false;
	}

	has_child_table() {
		if (
			$.map(this.mandatory, function (d) {
				return d.fieldtype === "Table" ? d : null;
			}).length
		) {
			// has mandatory table, quit!
			return true;
		}
		return false;
	}

	validate_for_prompt_autoname() {
		if (this.meta.autoname && this.meta.autoname.toLowerCase() === "prompt") {
			this.mandatory = [
				{
					fieldname: "__newname",
					label: __("{0} Name", [__(this.meta.name)]),
					reqd: 1,
					fieldtype: "Data",
				},
			].concat(this.mandatory);
		}
	}

	render_dialog() {
		var me = this;
		this.dialog = new jingrow.ui.Dialog({
			title: __("New {0}", [__(this.pagetype)]),
			fields: this.mandatory,
			pg: this.pg,
		});

		this.register_primary_action();
		!this.force && this.render_edit_in_full_page_link();
		// ctrl+enter to save
		this.dialog.wrapper.keydown(function (e) {
			if ((e.ctrlKey || e.metaKey) && e.which == 13) {
				if (!jingrow.request.ajax_count) {
					// not already working -- double entry
					me.dialog.get_primary_btn().trigger("click");
					e.preventDefault();
					return false;
				}
			}
		});

		this.dialog.onhide = () => (jingrow.quick_entry = null);
		this.dialog.show();

		this.dialog.refresh_dependency();
		this.set_defaults();

		if (this.init_callback) {
			this.init_callback(this.dialog);
		}
	}

	register_primary_action() {
		var me = this;
		this.dialog.set_primary_action(__("Save"), function () {
			if (me.dialog.working) {
				return;
			}
			var data = me.dialog.get_values();

			if (data) {
				me.dialog.working = true;
				me.dialog.set_message(__("Saving..."));
				me.insert().then(() => {
					me.dialog.clear_message();
				});
			}
		});
	}

	insert() {
		let me = this;
		return new Promise((resolve) => {
			me.update_pg();
			jingrow.call({
				method: "jingrow.client.save",
				args: {
					pg: me.dialog.pg,
				},
				callback: function (r) {
					if (
						r?.message?.pagestatus === 0 &&
						jingrow.model.can_submit(me.pagetype) &&
						!jingrow.model.has_workflow(me.pagetype)
					) {
						jingrow.run_serially([
							() => (me.dialog.working = true),
							() => {
								me.dialog.set_primary_action(__("Submit"), function () {
									me.submit(r.message);
								});
							},
						]);
					} else {
						me.dialog.hide();
						// delete the old pg
						jingrow.model.clear_pg(me.dialog.pg.pagetype, me.dialog.pg.name);
						me.dialog.pg = r.message;
						if (jingrow._from_link) {
							jingrow.ui.form.update_calling_link(me.dialog.pg);
						} else {
							if (me.after_insert) {
								me.after_insert(me.dialog.pg);
							} else {
								me.open_form_if_not_list();
							}
						}
					}
				},
				error: function () {
					if (!me.skip_redirect_on_error) {
						me.open_pg(true);
					}
				},
				always: function () {
					me.dialog.working = false;
					resolve(me.dialog.pg);
				},
				freeze: true,
			});
		});
	}

	submit(pg) {
		var me = this;
		jingrow.call({
			method: "jingrow.client.submit",
			args: {
				pg: pg,
			},
			callback: function (r) {
				me.dialog.hide();
				// delete the old pg
				jingrow.model.clear_pg(me.dialog.pg.pagetype, me.dialog.pg.name);
				me.dialog.pg = r.message;
				if (jingrow._from_link) {
					jingrow.ui.form.update_calling_link(me.dialog.pg);
				} else {
					if (me.after_insert) {
						me.after_insert(me.dialog.pg);
					} else {
						me.open_form_if_not_list();
					}
				}

				cur_frm && cur_frm.reload_pg();
			},
		});
	}

	open_form_if_not_list() {
		let route = jingrow.get_route();
		let pg = this.dialog.pg;
		if (route && !(route[0] === "List" && route[1] === pg.pagetype)) {
			jingrow.run_serially([() => jingrow.set_route("Form", pg.pagetype, pg.name)]);
		}
	}

	update_pg() {
		var me = this;
		var data = this.dialog.get_values(true);
		$.each(data, function (key, value) {
			if (!is_null(value)) {
				me.dialog.pg[key] = value;
			}
		});
		return this.dialog.pg;
	}

	open_pg(set_hooks) {
		this.dialog.hide();
		this.update_pg();
		if (set_hooks && this.after_insert) {
			jingrow.route_options = jingrow.route_options || {};
			jingrow.route_options.after_save = (frm) => {
				this.after_insert(frm);
			};
		}
		this.pg.__run_link_triggers = false;
		jingrow.set_route("Form", this.pagetype, this.pg.name);
	}

	render_edit_in_full_page_link() {
		var me = this;
		this.dialog.add_custom_action(__("Edit Full Form"), () => me.open_pg(true));
	}

	set_defaults() {
		var me = this;
		// set defaults
		$.each(this.dialog.fields_dict, function (fieldname, field) {
			field.pagetype = me.pg.pagetype;
			field.pagename = me.pg.name;

			if (!is_null(me.pg[fieldname])) {
				field.set_input(me.pg[fieldname]);
			}
		});
	}
};
