jingrow.ui.form.on("User", {
	setup: function (frm) {
		frm.set_query("default_workspace", () => {
			return {
				filters: {
					for_user: ["in", [null, jingrow.session.user]],
					title: ["!=", "Welcome Workspace"],
				},
			};
		});
	},
	before_load: function (frm) {
		let update_tz_options = function () {
			frm.fields_dict.time_zone.set_data(jingrow.all_timezones);
		};

		if (!jingrow.all_timezones) {
			jingrow.call({
				method: "jingrow.core.pagetype.user.user.get_timezones",
				callback: function (r) {
					jingrow.all_timezones = r.message.timezones;
					update_tz_options();
				},
			});
		} else {
			update_tz_options();
		}
	},

	time_zone: function (frm) {
		if (frm.pg.time_zone && frm.pg.time_zone.startsWith("Etc")) {
			frm.set_df_property(
				"time_zone",
				"description",
				__("Note: Etc timezones have their signs reversed.")
			);
		}
	},

	role_profile_name: function (frm) {
		if (frm.pg.role_profile_name) {
			jingrow.call({
				method: "jingrow.core.pagetype.user.user.get_role_profile",
				args: {
					role_profile: frm.pg.role_profile_name,
				},
				callback: function (data) {
					frm.set_value("roles", []);
					$.each(data.message || [], function (i, v) {
						var d = frm.add_child("roles");
						d.role = v.role;
					});
					frm.roles_editor.show();
				},
			});
		}
	},

	module_profile: function (frm) {
		if (frm.pg.module_profile) {
			jingrow.call({
				method: "jingrow.core.pagetype.user.user.get_module_profile",
				args: {
					module_profile: frm.pg.module_profile,
				},
				callback: function (data) {
					frm.set_value("block_modules", []);
					$.each(data.message || [], function (i, v) {
						let d = frm.add_child("block_modules");
						d.module = v.module;
					});
					frm.module_editor && frm.module_editor.show();
				},
			});
		}
	},

	onload: function (frm) {
		frm.can_edit_roles = has_access_to_edit_user();

		if (frm.is_new() && frm.roles_editor) {
			frm.roles_editor.reset();
		}

		if (
			frm.can_edit_roles &&
			!frm.is_new() &&
			["System User", "Website User"].includes(frm.pg.user_type)
		) {
			if (!frm.roles_editor) {
				const role_area = $('<div class="role-editor">').appendTo(
					frm.fields_dict.roles_html.wrapper
				);

				frm.roles_editor = new jingrow.RoleEditor(
					role_area,
					frm,
					frm.pg.role_profile_name ? 1 : 0
				);

				if (frm.pg.user_type == "System User") {
					var module_area = $("<div>").appendTo(frm.fields_dict.modules_html.wrapper);
					frm.module_editor = new jingrow.ModuleEditor(frm, module_area);
				}
			} else {
				frm.roles_editor.show();
			}
		}
	},
	refresh: function (frm) {
		let pg = frm.pg;

		jingrow.xcall("jingrow.apps.get_apps").then((r) => {
			let apps = r?.map((r) => r.name) || [];
			frm.set_df_property("default_app", "options", [" ", ...apps]);
		});

		if (frm.is_new()) {
			frm.set_value("time_zone", jingrow.sys_defaults.time_zone);
		}

		if (
			["System User", "Website User"].includes(frm.pg.user_type) &&
			!frm.is_new() &&
			!frm.roles_editor &&
			frm.can_edit_roles
		) {
			frm.reload_pg();
			return;
		}

		frm.toggle_display(["sb1", "sb3", "modules_access"], false);
		frm.trigger("setup_impersonation");

		if (!frm.is_new()) {
			if (has_access_to_edit_user()) {
				frm.add_custom_button(
					__("Set User Permissions"),
					function () {
						jingrow.route_options = {
							user: pg.name,
						};
						jingrow.set_route("List", "User Permission");
					},
					__("Permissions")
				);

				frm.add_custom_button(
					__("View Permitted Documents"),
					() =>
						jingrow.set_route("query-report", "Permitted Documents For User", {
							user: frm.pg.name,
						}),
					__("Permissions")
				);

				frm.toggle_display(["sb1", "sb3", "modules_access"], true);
			}

			frm.add_custom_button(
				__("Reset Password"),
				function () {
					jingrow.call({
						method: "jingrow.core.pagetype.user.user.reset_password",
						args: {
							user: frm.pg.name,
						},
					});
				},
				__("Password")
			);

			if (jingrow.user.has_role("System Manager")) {
				jingrow.db.get_single_value("LDAP Settings", "enabled").then((value) => {
					if (value === 1 && frm.pg.name != "Administrator") {
						frm.add_custom_button(
							__("Reset LDAP Password"),
							function () {
								const d = new jingrow.ui.Dialog({
									title: __("Reset LDAP Password"),
									fields: [
										{
											label: __("New Password"),
											fieldtype: "Password",
											fieldname: "new_password",
											reqd: 1,
										},
										{
											label: __("Confirm New Password"),
											fieldtype: "Password",
											fieldname: "confirm_password",
											reqd: 1,
										},
										{
											label: __("Logout All Sessions"),
											fieldtype: "Check",
											fieldname: "logout_sessions",
										},
									],
									primary_action: (values) => {
										d.hide();
										if (values.new_password !== values.confirm_password) {
											jingrow.throw(__("Passwords do not match!"));
										}
										jingrow.call(
											"jingrow.integrations.pagetype.ldap_settings.ldap_settings.reset_password",
											{
												user: frm.pg.email,
												password: values.new_password,
												logout: values.logout_sessions,
											}
										);
									},
								});
								d.show();
							},
							__("Password")
						);
					}
				});
			}

			if (
				cint(jingrow.boot.sysdefaults.enable_two_factor_auth) &&
				(jingrow.session.user == pg.name || jingrow.user.has_role("System Manager"))
			) {
				frm.add_custom_button(
					__("Reset OTP Secret"),
					function () {
						jingrow.call({
							method: "jingrow.twofactor.reset_otp_secret",
							args: {
								user: frm.pg.name,
							},
						});
					},
					__("Password")
				);
			}

			frm.trigger("enabled");

			if (frm.roles_editor && frm.can_edit_roles) {
				frm.roles_editor.disable = frm.pg.role_profile_name ? 1 : 0;
				frm.roles_editor.show();
			}

			frm.module_editor && frm.module_editor.show();

			if (jingrow.session.user == pg.name) {
				// update display settings
				if (pg.user_image) {
					jingrow.boot.user_info[jingrow.session.user].image = jingrow.utils.get_file_link(
						pg.user_image
					);
				}
			}
		}
		if (frm.pg.user_emails && jingrow.model.can_create("Email Account")) {
			var found = 0;
			for (var i = 0; i < frm.pg.user_emails.length; i++) {
				if (frm.pg.email == frm.pg.user_emails[i].email_id) {
					found = 1;
				}
			}
			if (!found) {
				frm.add_custom_button(__("Create User Email"), function () {
					frm.events.create_user_email(frm);
				});
			}
		}

		if (jingrow.route_flags.unsaved === 1) {
			delete jingrow.route_flags.unsaved;
			for (let i = 0; i < frm.pg.user_emails.length; i++) {
				frm.pg.user_emails[i].idx = frm.pg.user_emails[i].idx + 1;
			}
			frm.dirty();
		}
		frm.trigger("time_zone");
	},
	validate: function (frm) {
		if (frm.roles_editor) {
			frm.roles_editor.set_roles_in_table();
		}
	},
	enabled: function (frm) {
		var pg = frm.pg;
		if (!frm.is_new() && has_access_to_edit_user()) {
			frm.toggle_display(["sb1", "sb3", "modules_access"], pg.enabled);
			frm.set_df_property("enabled", "read_only", 0);
		}

		if (frm.pg.name !== "Administrator") {
			frm.toggle_enable("email", frm.is_new());
		}
	},
	create_user_email: function (frm) {
		jingrow.call({
			method: "jingrow.core.pagetype.user.user.has_email_account",
			args: {
				email: frm.pg.email,
			},
			callback: function (r) {
				if (!Array.isArray(r.message) || !r.message.length) {
					jingrow.route_options = {
						email_id: frm.pg.email,
						awaiting_password: 1,
						enable_incoming: 1,
					};
					jingrow.model.with_pagetype("Email Account", function (pg) {
						pg = jingrow.model.get_new_pg("Email Account");
						jingrow.route_flags.linked_user = frm.pg.name;
						jingrow.route_flags.delete_user_from_locals = true;
						jingrow.set_route("Form", "Email Account", pg.name);
					});
				} else {
					jingrow.route_flags.create_user_account = frm.pg.name;
					jingrow.set_route("Form", "Email Account", r.message[0]["name"]);
				}
			},
		});
	},
	generate_keys: function (frm) {
		jingrow.call({
			method: "jingrow.core.pagetype.user.user.generate_keys",
			args: {
				user: frm.pg.name,
			},
			callback: function (r) {
				if (r.message) {
					jingrow.msgprint(__("Save API Secret: {0}", [r.message.api_secret]));
					frm.reload_pg();
				}
			},
		});
	},
	after_save: function (frm) {
		/**
		 * Checks whether the effective value has changed.
		 *
		 * @param {Array.<string>} - Tuple with new override, previous override,
		 *   and optionally fallback.
		 * @returns {boolean} - Whether the resulting value has effectively changed
		 */
		const has_effectively_changed = ([new_override, prev_override, fallback = undefined]) => {
			const prev_effective = prev_override || fallback;
			const new_effective = new_override || fallback;
			return new_override !== undefined && prev_effective !== new_effective;
		};

		const pg = frm.pg;
		const boot = jingrow.boot;
		const attr_tuples = [
			[pg.language, boot.user.language, boot.sysdefaults.language],
			[pg.time_zone, boot.time_zone.user, boot.time_zone.system],
			[pg.desk_theme, boot.user.desk_theme], // No system default.
		];

		if (pg.name === jingrow.session.user && attr_tuples.some(has_effectively_changed)) {
			jingrow.msgprint(__("Refreshing..."));
			window.location.reload();
		}
	},
	setup_impersonation: function (frm) {
		if (jingrow.session.user === "Administrator" && frm.pg.name != "Administrator") {
			frm.add_custom_button(__("Impersonate"), () => {
				if (frm.pg.restrict_ip) {
					jingrow.msgprint({
						message:
							"There's IP restriction for this user, you can not impersonate as this user.",
						title: "IP restriction is enabled",
					});
					return;
				}
				jingrow.prompt(
					[
						{
							fieldname: "reason",
							fieldtype: "Small Text",
							label: "Reason for impersonating",
							description: __("Note: This will be shared with user."),
							reqd: 1,
						},
					],
					(values) => {
						jingrow
							.xcall("jingrow.core.pagetype.user.user.impersonate", {
								user: frm.pg.name,
								reason: values.reason,
							})
							.then(() => window.location.reload());
					},
					__("Impersonate as {0}", [frm.pg.name]),
					__("Confirm")
				);
			});
		}
	},
});

jingrow.ui.form.on("User Email", {
	email_account(frm, cdt, cdn) {
		let child_row = locals[cdt][cdn];
		jingrow.model.get_value(
			"Email Account",
			child_row.email_account,
			"auth_method",
			(value) => {
				child_row.used_oauth = value.auth_method === "OAuth";
				frm.refresh_field("user_emails", cdn, "used_oauth");
			}
		);
	},
});

function has_access_to_edit_user() {
	return has_common(jingrow.user_roles, get_roles_for_editing_user());
}

function get_roles_for_editing_user() {
	return (
		jingrow
			.get_meta("User")
			.permissions.filter((perm) => perm.permlevel >= 1 && perm.write)
			.map((perm) => perm.role) || ["System Manager"]
	);
}
