// Copyright (c) 2015, JINGROW and Contributors
// MIT License. See license.txt

jingrow.provide("jingrow.customize_form");

jingrow.ui.form.on("Customize Form", {
	setup: function (frm) {
		// save the last setting if refreshing
		window.addEventListener("beforeunload", () => {
			if (frm.pg.pg_type && frm.pg.pg_type != "undefined") {
				localStorage["customize_pagetype"] = frm.pg.pg_type;
			}
		});
	},

	onload: function (frm) {
		frm.set_query("pg_type", function () {
			return {
				filters: [
					["PageType", "issingle", "=", 0],
					["PageType", "custom", "=", 0],
					["PageType", "name", "not in", jingrow.model.core_pagetypes_list],
					["PageType", "restrict_to_domain", "in", jingrow.boot.active_domains],
				],
			};
		});

		frm.set_query("default_print_format", function () {
			return {
				filters: {
					print_format_type: ["!=", "JS"],
					pg_type: ["=", frm.pg.pg_type],
				},
			};
		});

		$(frm.wrapper).on("grid-row-render", function (e, grid_row) {
			if (grid_row.pg && grid_row.pg.fieldtype == "Section Break") {
				$(grid_row.row).css({ "font-weight": "bold" });
			}

			grid_row.row.removeClass("highlight");

			if (
				grid_row.pg.is_custom_field &&
				!grid_row.row.hasClass("highlight") &&
				!grid_row.pg.is_system_generated
			) {
				grid_row.row.addClass("highlight");
			}
		});
	},

	pg_type: function (frm) {
		if (frm.pg.pg_type) {
			return frm.call({
				method: "fetch_to_customize",
				pg: frm.pg,
				freeze: true,
				callback: function (r) {
					if (r) {
						if (r._server_messages && r._server_messages.length) {
							frm.set_value("pg_type", "");
						} else {
							frm.refresh();
							frm.trigger("add_customize_child_table_button");
							frm.trigger("setup_default_views");
						}
					}
					localStorage["customize_pagetype"] = frm.pg.pg_type;
				},
			});
		} else {
			frm.refresh();
		}
	},

	is_calendar_and_gantt: function (frm) {
		frm.trigger("setup_default_views");
	},

	add_customize_child_table_button: function (frm) {
		frm.pg.fields.forEach(function (f) {
			if (!["Table", "Table MultiSelect"].includes(f.fieldtype)) return;

			frm.add_custom_button(
				__(f.options),
				() => frm.set_value("pg_type", f.options),
				__("Customize Child Table")
			);
		});
	},

	refresh: function (frm) {
		frm.disable_save(true);
		frm.page.clear_icons();

		if (frm.pg.pg_type) {
			jingrow.model.with_pagetype(frm.pg.pg_type).then(() => {
				frm.page.set_title(__("Customize Form - {0}", [__(frm.pg.pg_type)]));
				jingrow.customize_form.set_primary_action(frm);

				frm.add_custom_button(
					__("Go to {0} List", [__(frm.pg.pg_type)]),
					function () {
						jingrow.set_route("List", frm.pg.pg_type);
					},
					__("Actions")
				);

				frm.add_custom_button(
					__("Set Permissions"),
					function () {
						jingrow.set_route("permission-manager", frm.pg.pg_type);
					},
					__("Actions")
				);

				frm.add_custom_button(
					__("Reload"),
					function () {
						frm.script_manager.trigger("pg_type");
					},
					__("Actions")
				);

				frm.add_custom_button(
					__("Reset Layout"),
					() => {
						frm.trigger("reset_layout");
					},
					__("Actions")
				);

				frm.add_custom_button(
					__("Reset All Customizations"),
					function () {
						jingrow.customize_form.confirm(__("Remove all customizations?"), frm);
					},
					__("Actions")
				);

				frm.add_custom_button(
					__("Trim Table"),
					function () {
						frm.trigger("trim_table");
					},
					__("Actions")
				);

				const is_autoname_autoincrement = frm.pg.autoname === "autoincrement";
				frm.set_df_property("naming_rule", "hidden", is_autoname_autoincrement);
				frm.set_df_property("autoname", "read_only", is_autoname_autoincrement);
				frm.toggle_display(
					["queue_in_background"],
					jingrow.get_meta(frm.pg.pg_type).is_submittable || 0
				);

				render_form_builder(frm);
				frm.get_field("form_builder").tab.set_active();
			});
		}

		frm.events.setup_export(frm);
		frm.events.setup_sort_order(frm);
		frm.events.set_default_pg_type(frm);
	},

	set_default_pg_type(frm) {
		let pg_type;
		if (jingrow.route_options && jingrow.route_options.pg_type) {
			pg_type = jingrow.route_options.pg_type;
			jingrow.route_options = null;
			localStorage.removeItem("customize_pagetype");
		}
		if (!pg_type) {
			pg_type = localStorage.getItem("customize_pagetype");
		}
		if (pg_type) {
			setTimeout(() => frm.set_value("pg_type", pg_type, false, true), 1000);
		}
	},

	reset_layout(frm) {
		jingrow.confirm(
			__("Layout will be reset to standard layout, are you sure you want to do this?"),
			() => {
				return frm.call({
					pg: frm.pg,
					method: "reset_layout",
					callback: function (r) {
						if (!r.exc) {
							jingrow.show_alert({
								message: __("Layout Reset"),
								indicator: "green",
							});
							jingrow.customize_form.clear_locals_and_refresh(frm);
						}
					},
				});
			}
		);
	},

	async trim_table(frm) {
		let dropped_columns = await jingrow.xcall(
			"jingrow.custom.pagetype.customize_form.customize_form.get_orphaned_columns",
			{ pagetype: frm.pg.pg_type }
		);

		if (!dropped_columns?.length) {
			jingrow.toast(__("This pagetype has no orphan fields to trim"));
			return;
		}
		let msg = __(
			"Warning: DATA LOSS IMMINENT! Proceeding will permanently delete following database columns from pagetype {0}:",
			[frm.pg.pg_type.bold()]
		);
		msg += "<ol>" + dropped_columns.map((col) => `<li>${col}</li>`).join("") + "</ol>";
		msg += __("This action is irreversible. Do you wish to continue?");

		jingrow.confirm(msg, () => {
			return frm.call({
				pg: frm.pg,
				method: "trim_table",
				callback: function (r) {
					if (!r.exc) {
						jingrow.show_alert({
							message: __("Table Trimmed"),
							indicator: "green",
						});
						jingrow.customize_form.clear_locals_and_refresh(frm);
					}
				},
			});
		});
	},

	setup_export(frm) {
		if (jingrow.boot.developer_mode) {
			frm.add_custom_button(
				__("Export Customizations"),
				function () {
					jingrow.prompt(
						[
							{
								fieldtype: "Link",
								fieldname: "module",
								options: "Module Def",
								label: __("Module to Export"),
								reqd: 1,
							},
							{
								fieldtype: "Check",
								fieldname: "sync_on_migrate",
								label: __("Sync on Migrate"),
								default: 1,
							},
							{
								fieldtype: "Check",
								fieldname: "with_permissions",
								label: __("Export Custom Permissions"),
								description: __(
									"Exported permissions will be force-synced on every migrate overriding any other customization."
								),
								default: 0,
							},
						],
						function (data) {
							jingrow.call({
								method: "jingrow.modules.utils.export_customizations",
								args: {
									pagetype: frm.pg.pg_type,
									module: data.module,
									sync_on_migrate: data.sync_on_migrate,
									with_permissions: data.with_permissions,
								},
							});
						},
						__("Select Module")
					);
				},
				__("Actions")
			);
		}
	},

	setup_sort_order(frm) {
		// sort order select
		if (frm.pg.pg_type) {
			var fields = $.map(frm.pg.fields, function (df) {
				return jingrow.model.is_value_type(df.fieldtype) ? df.fieldname : null;
			});
			fields = ["", "name", "creation", "modified"].concat(fields);
			frm.set_df_property("sort_field", "options", fields);
		}
	},

	setup_default_views(frm) {
		jingrow.model.set_default_views_for_pagetype(frm.pg.pg_type, frm);
	},
});

// can't delete standard fields
jingrow.ui.form.on("Customize Form Field", {
	before_fields_remove: function (frm, pagetype, name) {
		const row = jingrow.get_pg(pagetype, name);

		if (row.is_system_generated) {
			jingrow.throw(
				__(
					"Cannot delete system generated field <strong>{0}</strong>. You can hide it instead.",
					[__(row.label) || row.fieldname]
				)
			);
		}

		if (!(row.is_custom_field || row.__islocal)) {
			jingrow.throw(
				__("Cannot delete standard field <strong>{0}</strong>. You can hide it instead.", [
					__(row.label) || row.fieldname,
				])
			);
		}
	},
	fields_add: function (frm, cdt, cdn) {
		var f = jingrow.model.get_pg(cdt, cdn);
		f.is_system_generated = false;
		f.is_custom_field = true;
		frm.trigger("setup_default_views");
	},

	form_render(frm, pagetype, pagename) {
		frm.trigger("setup_fetch_from_fields", pagetype, pagename);
	},
});

let parenttype, parent; // used in the form events for the child tables: links, actions and states

// can't delete standard links
jingrow.ui.form.on("PageType Link", {
	before_links_remove: function (frm, pagetype, name) {
		let row = jingrow.get_pg(pagetype, name);
		parenttype = row.parenttype; // used in the event links_remove
		parent = row.parent; // used in the event links_remove
		if (!(row.custom || row.__islocal)) {
			jingrow.msgprint(__("Cannot delete standard link. You can hide it if you want"));
			throw "cannot delete standard link";
		}
	},
	links_add: function (frm, cdt, cdn) {
		let f = jingrow.model.get_pg(cdt, cdn);
		f.custom = 1;
	},
	links_remove: function (frm, pagetype, name) {
		// replicate the changed rows from the browser's copy of the parent pg to the current 'Customize Form' pg
		let parent_pg = locals[parenttype][parent];
		frm.pg.links = parent_pg.links;
	},
});

// can't delete standard actions
jingrow.ui.form.on("PageType Action", {
	before_actions_remove: function (frm, pagetype, name) {
		let row = jingrow.get_pg(pagetype, name);
		parenttype = row.parenttype; // used in the event actions_remove
		parent = row.parent; // used in the event actions_remove
		if (!(row.custom || row.__islocal)) {
			jingrow.msgprint(__("Cannot delete standard action. You can hide it if you want"));
			throw "cannot delete standard action";
		}
	},
	actions_add: function (frm, cdt, cdn) {
		let f = jingrow.model.get_pg(cdt, cdn);
		f.custom = 1;
	},
	actions_remove: function (frm, pagetype, name) {
		// replicate the changed rows from the browser's copy of the parent pg to the current 'Customize Form' pg
		let parent_pg = locals[parenttype][parent];
		frm.pg.actions = parent_pg.actions;
	},
});

// can't delete standard states
jingrow.ui.form.on("PageType State", {
	before_states_remove: function (frm, pagetype, name) {
		let row = jingrow.get_pg(pagetype, name);
		parenttype = row.parenttype; // used in the event states_remove
		parent = row.parent; // used in the event states_remove
		if (!(row.custom || row.__islocal)) {
			jingrow.msgprint(__("Cannot delete standard document state."));
			throw "cannot delete standard document state";
		}
	},
	states_add: function (frm, cdt, cdn) {
		let f = jingrow.model.get_pg(cdt, cdn);
		f.custom = 1;
	},
	states_remove: function (frm, pagetype, name) {
		// replicate the changed rows from the browser's copy of the parent pg to the current 'Customize Form' pg
		let parent_pg = locals[parenttype][parent];
		frm.pg.states = parent_pg.states;
	},
});

jingrow.customize_form.save_customization = function (frm) {
	if (frm.pg.pg_type) {
		return frm.call({
			pg: frm.pg,
			freeze: true,
			freeze_message: __("Saving Customization..."),
			btn: frm.page.btn_primary,
			method: "save_customization",
			callback: function (r) {
				if (!r.exc) {
					jingrow.customize_form.clear_locals_and_refresh(frm);
					frm.script_manager.trigger("pg_type");
				}
			},
		});
	}
};

jingrow.customize_form.update_fields_from_form_builder = function (frm) {
	let form_builder = jingrow.form_builder;
	if (form_builder?.store) {
		let fields = form_builder.store.update_fields();

		// if fields is a string, it means there is an error
		if (typeof fields === "string") {
			jingrow.throw(fields);
		}
		frm.refresh_fields();
	}
};

jingrow.customize_form.set_primary_action = function (frm) {
	frm.page.set_primary_action(__("Update"), () => {
		this.update_fields_from_form_builder(frm);
		this.save_customization(frm);
	});
};

jingrow.customize_form.confirm = function (msg, frm) {
	if (!frm.pg.pg_type) return;

	var d = new jingrow.ui.Dialog({
		title: "Reset To Defaults",
		fields: [
			{
				fieldtype: "HTML",
				options: __("All customizations will be removed. Please confirm."),
			},
		],
		primary_action: function () {
			return frm.call({
				pg: frm.pg,
				method: "reset_to_defaults",
				callback: function (r) {
					if (r.exc) {
						jingrow.msgprint(r.exc);
					} else {
						d.hide();
						jingrow.show_alert({
							message: __("Customizations Reset"),
							indicator: "green",
						});
						jingrow.customize_form.clear_locals_and_refresh(frm);
					}
				},
			});
		},
	});

	jingrow.customize_form.confirm.dialog = d;
	d.show();
};

jingrow.customize_form.clear_locals_and_refresh = function (frm) {
	delete frm.pg.__unsaved;
	// clear pagetype from locals
	jingrow.model.clear_pg("PageType", frm.pg.pg_type);
	delete jingrow.meta.pagefield_copy[frm.pg.pg_type];
	frm.refresh();
};

function render_form_builder(frm) {
	if (jingrow.form_builder && jingrow.form_builder.pagetype === frm.pg.pg_type) {
		jingrow.form_builder.setup_page_actions();
		jingrow.form_builder.store.fetch();
		return;
	}

	if (jingrow.form_builder) {
		jingrow.form_builder.wrapper = $(frm.fields_dict["form_builder"].wrapper);
		jingrow.form_builder.frm = frm;
		jingrow.form_builder.pagetype = frm.pg.pg_type;
		jingrow.form_builder.customize = true;
		jingrow.form_builder.init(true);
		jingrow.form_builder.store.fetch();
	} else {
		jingrow.require("form_builder.bundle.js").then(() => {
			jingrow.form_builder = new jingrow.ui.FormBuilder({
				wrapper: $(frm.fields_dict["form_builder"].wrapper),
				frm: frm,
				pagetype: frm.pg.pg_type,
				customize: true,
			});
		});
	}
}

extend_cscript(cur_frm.cscript, new jingrow.model.PageTypeController({ frm: cur_frm }));
