// Copyright (c) 2015, JINGROW and Contributors
// MIT License. See license.txt
import "./linked_with";
import "./form_viewers";
import { ReminderManager } from "./reminders";

jingrow.ui.form.Toolbar = class Toolbar {
	constructor(opts) {
		$.extend(this, opts);
		this.refresh();
		this.add_update_button_on_dirty();
		this.setup_editable_title();
	}
	refresh() {
		this.make_menu();
		this.set_title();
		this.page.clear_user_actions();
		this.show_title_as_dirty();
		this.set_primary_action();

		if (this.frm.meta.hide_toolbar) {
			this.page.hide_menu();
		} else {
			if (this.frm.pg.__islocal) {
				this.page.hide_menu();
				this.print_icon && this.print_icon.addClass("hide");
			} else {
				this.page.show_menu();
				this.print_icon && this.print_icon.removeClass("hide");
			}
		}
	}
	set_title() {
		let title;
		if (this.frm.is_new()) {
			title = __("New {0}", [__(this.frm.meta.name)]);
		} else if (this.frm.meta.title_field) {
			let title_field = (this.frm.pg[this.frm.meta.title_field] || "").toString().trim();
			title = strip_html(title_field || this.frm.pagename);
			if (
				this.frm.pg.__islocal ||
				title === this.frm.pagename ||
				this.frm.meta.autoname === "hash"
			) {
				this.page.set_title_sub("");
			} else {
				this.page.set_title_sub(this.frm.pagename);
				this.page.$sub_title_area.css("cursor", "copy");
				this.page.$sub_title_area.on("click", (event) => {
					event.stopImmediatePropagation();
					jingrow.utils.copy_to_clipboard(this.frm.pagename);
				});
			}
		} else {
			title = this.frm.pagename;
		}

		var me = this;
		title = __(title);
		this.page.set_title(title);
		if (this.frm.meta.title_field) {
			jingrow.utils.set_title(title + " - " + this.frm.pagename);
		}
		this.page.$title_area.toggleClass(
			"editable-title",
			!!(this.is_title_editable() || this.can_rename())
		);

		this.set_indicator();
	}
	is_title_editable() {
		let title_field = this.frm.meta.title_field;
		let pg_field = this.frm.get_pagefield(title_field);

		if (
			this.frm.meta.naming_rule === "By fieldname" &&
			this.frm.meta.autoname === "field:" + title_field &&
			!this.frm.meta.allow_rename
		) {
			return false;
		}

		if (
			title_field &&
			this.frm.perm[0].write &&
			!this.frm.pg.__islocal &&
			pg_field.fieldtype === "Data" &&
			!pg_field.read_only &&
			!pg_field.set_only_once
		) {
			return true;
		} else {
			return false;
		}
	}
	can_rename() {
		return this.frm.perm[0].write && this.frm.meta.allow_rename && !this.frm.pg.__islocal;
	}
	show_unchanged_document_alert() {
		jingrow.show_alert({
			indicator: "info",
			message: __("Unchanged"),
		});
	}
	rename_document_title(input_name, input_title, merge = false) {
		let confirm_message = null;
		const pagename = this.frm.pg.name;
		const title_field = this.frm.meta.title_field || "";
		const pagetype = this.frm.pagetype;
		let queue;
		if (this.frm.__rename_queue) {
			queue = this.frm.__rename_queue;
		}

		if (input_name) {
			const warning = __("This cannot be undone");
			const message = __("Are you sure you want to merge {0} with {1}?", [
				pagename.bold(),
				input_name.bold(),
			]);
			confirm_message = `${message}<br><b>${warning}<b>`;
		}

		let rename_document = () => {
			if (input_name != pagename) jingrow.realtime.pagetype_subscribe(pagetype, input_name);
			return jingrow
				.xcall("jingrow.model.rename_pg.update_document_title", {
					pagetype,
					pagename,
					name: input_name,
					title: input_title,
					enqueue: true,
					merge,
					freeze: true,
					freeze_message: __("Updating related fields..."),
					queue,
				})
				.then((new_pagename) => {
					const reload_form = (input_name) => {
						$(document).trigger("rename", [pagetype, pagename, input_name]);
						if (locals[pagetype] && locals[pagetype][pagename])
							delete locals[pagetype][pagename];
						this.frm.reload_pg();
					};

					// handle document renaming queued action
					if (input_name != pagename) {
						jingrow.realtime.on("list_update", (data) => {
							if (data.pagetype == pagetype && data.name == input_name) {
								reload_form(input_name);
								jingrow.show_alert({
									message: __("Page renamed from {0} to {1}", [
										pagename.bold(),
										input_name.bold(),
									]),
									indicator: "success",
								});
							}
						});
						jingrow.show_alert(
							__("Document renaming from {0} to {1} has been queued", [
								pagename.bold(),
								input_name.bold(),
							])
						);
					}

					// handle document sync rename action
					if (input_name && (new_pagename || input_name) != pagename) {
						reload_form(new_pagename || input_name);
					}
				});
		};

		return new Promise((resolve, reject) => {
			if (input_title === this.frm.pg[title_field] && input_name === pagename) {
				this.show_unchanged_document_alert();
				resolve();
			} else if (merge) {
				jingrow.confirm(
					confirm_message,
					() => {
						rename_document().then(resolve).catch(reject);
					},
					reject
				);
			} else {
				rename_document().then(resolve).catch(reject);
			}
		});
	}
	setup_editable_title() {
		let me = this;

		this.page.$title_area.find(".title-text").on("click", () => {
			let fields = [];
			let pagename = me.frm.pg.name;
			let title_field = me.frm.meta.title_field || "";

			// check if title is updatable
			if (me.is_title_editable()) {
				let title_field_label = me.frm.get_pagefield(title_field).label;

				fields.push({
					label: __("New {0}", [__(title_field_label)]),
					fieldname: "title",
					fieldtype: "Data",
					reqd: 1,
					default: me.frm.pg[title_field],
				});
			}

			let is_title_field_same_as_autoname = false;

			// check if pagename is updatable
			if (me.can_rename()) {
				let label = __("New Name");
				if (me.frm.meta.autoname && me.frm.meta.autoname.startsWith("field:")) {
					let fieldname = me.frm.meta.autoname.split(":")[1];
					label = __("New {0}", [me.frm.get_pagefield(fieldname).label]);
					is_title_field_same_as_autoname = fieldname === title_field;
				}

				if (!is_title_field_same_as_autoname) {
					fields.push(
						...[
							{
								label: label,
								fieldname: "name",
								fieldtype: "Data",
								reqd: 1,
								default: pagename,
							},
						]
					);
				}

				fields.push(
					...[
						{
							label: __("Merge with existing"),
							fieldname: "merge",
							fieldtype: "Check",
							default: 0,
						},
					]
				);
			}

			// create dialog
			if (fields.length > 0) {
				let d = new jingrow.ui.Dialog({
					title: __("Rename"),
					fields: fields,
				});
				d.show();
				d.set_primary_action(__("Rename"), (values) => {
					d.disable_primary_action();
					d.hide();

					if (is_title_field_same_as_autoname) {
						values.name = values.title;
					}

					this.rename_document_title(values.name, values.title, values.merge)
						.then(() => {
							d.hide();
						})
						.catch(() => {
							d.enable_primary_action();
						});
				});
			}
		});
	}
	get_dropdown_menu(label) {
		return this.page.add_dropdown(label);
	}
	set_indicator() {
		var indicator = jingrow.get_indicator(this.frm.pg);
		if (
			this.frm.save_disabled &&
			indicator &&
			[__("Saved"), __("Not Saved")].includes(indicator[0])
		) {
			return;
		}
		if (indicator) {
			this.page.set_indicator(indicator[0], indicator[1]);
		} else {
			this.page.clear_indicator();
		}
	}
	make_menu() {
		this.page.clear_icons();
		this.page.clear_menu();

		if (jingrow.boot.desk_settings.form_sidebar) {
			this.make_navigation();
			this.make_menu_items();
		}
	}

	make_navigation() {
		// Navigate
		if (!this.frm.is_new() && !this.frm.meta.issingle) {
			this.page.add_action_icon(
				"es-line-left-chevron",
				() => {
					this.frm.navigate_records(1);
				},
				"prev-pg",
				__("Previous Document")
			);
			this.page.add_action_icon(
				"es-line-right-chevron",
				() => {
					this.frm.navigate_records(0);
				},
				"next-pg",
				__("Next Document")
			);
		}
	}

	make_menu_items() {
		// Print
		const me = this;
		const p = this.frm.perm[0];
		const pagestatus = cint(this.frm.pg.pagestatus);
		const is_submittable = jingrow.model.is_submittable(this.frm.pg.pagetype);

		const print_settings = jingrow.model.get_pg(":Print Settings", "Print Settings");
		const allow_print_for_draft = cint(print_settings.allow_print_for_draft);
		const allow_print_for_cancelled = cint(print_settings.allow_print_for_cancelled);

		if (
			!is_submittable ||
			pagestatus == 1 ||
			(allow_print_for_cancelled && pagestatus == 2) ||
			(allow_print_for_draft && pagestatus == 0)
		) {
			if (jingrow.model.can_print(null, me.frm) && !this.frm.meta.issingle) {
				this.page.add_menu_item(
					__("Print"),
					function () {
						me.frm.print_pg();
					},
					true
				);
				this.print_icon = this.page.add_action_icon(
					"printer",
					function () {
						me.frm.print_pg();
					},
					"",
					__("Print")
				);
			}
		}

		// email
		if (jingrow.model.can_email(null, me.frm) && me.frm.pg.pagestatus < 2) {
			this.page.add_menu_item(
				__("Email"),
				function () {
					me.frm.email_pg();
				},
				true,
				{
					shortcut: "Ctrl+E",
					condition: () => !this.frm.is_new(),
				}
			);
		}

		// go to field modal
		this.page.add_menu_item(
			__("Jump to field"),
			function () {
				me.show_jump_to_field_dialog();
			},
			true,
			"Ctrl+J"
		);

		// Linked With
		if (!me.frm.meta.issingle) {
			this.page.add_menu_item(
				__("Links"),
				function () {
					me.show_linked_with();
				},
				true
			);
		}

		// duplicate
		if (jingrow.boot.user.can_create.includes(me.frm.pagetype) && !me.frm.meta.allow_copy) {
			this.page.add_menu_item(
				__("Duplicate"),
				function () {
					me.frm.copy_pg();
				},
				true,
				"Shift+D"
			);
		}

		// copy pg to clipboard
		this.page.add_menu_item(
			__("Copy to Clipboard"),
			function () {
				jingrow.utils.copy_to_clipboard(JSON.stringify(me.frm.pg));
			},
			true
		);

		// rename
		if (this.can_rename()) {
			this.page.add_menu_item(
				__("Rename"),
				function () {
					me.frm.rename_pg();
				},
				true
			);
		}

		// reload
		this.page.add_menu_item(
			__("Reload"),
			function () {
				me.frm.reload_pg();
			},
			true
		);

		// delete
		if (
			cint(me.frm.pg.pagestatus) != 1 &&
			!me.frm.pg.__islocal &&
			!jingrow.model.is_single(me.frm.pagetype) &&
			jingrow.model.can_delete(me.frm.pagetype)
		) {
			this.page.add_menu_item(
				__("Delete"),
				function () {
					me.frm.savetrash();
				},
				true,
				{
					shortcut: "Shift+Ctrl+D",
					condition: () => !this.frm.is_new(),
				}
			);
		}

		this.page.add_menu_item(
			__("Remind Me"),
			() => {
				let reminder_maanger = new ReminderManager({ frm: this.frm });
				reminder_maanger.show();
			},
			true,
			{
				shortcut: "Shift+R",
				condition: () => !this.frm.is_new(),
			}
		);
		//
		// Undo and redo
		this.page.add_menu_item(
			__("Undo"),
			() => {
				this.frm.undo_manager.undo();
			},
			true,
			{
				shortcut: "Ctrl+Z",
				condition: () => !this.frm.is_form_builder(),
				description: __("Undo last action"),
			}
		);
		this.page.add_menu_item(
			__("Redo"),
			() => {
				this.frm.undo_manager.redo();
			},
			true,
			{
				shortcut: "Ctrl+Y",
				condition: () => !this.frm.is_form_builder(),
				description: __("Redo last action"),
			}
		);

		this.make_customize_buttons();

		// Auto Repeat
		if (this.can_repeat()) {
			this.page.add_menu_item(
				__("Repeat"),
				function () {
					jingrow.utils.new_auto_repeat_prompt(me.frm);
				},
				true
			);
		}

		// New
		if (p[CREATE] && !this.frm.meta.issingle && !this.frm.meta.in_create) {
			this.page.add_menu_item(
				__("New {0}", [__(me.frm.pagetype)]),
				function () {
					jingrow.new_pg(me.frm.pagetype, true);
				},
				true,
				{
					shortcut: "Ctrl+B",
					condition: () => !this.frm.is_new(),
				}
			);
		}
	}

	make_customize_buttons() {
		let is_pagetype_form = this.frm.pagetype === "PageType";
		if (
			jingrow.model.can_create("Custom Field") &&
			jingrow.model.can_create("Property Setter")
		) {
			let pagetype = is_pagetype_form ? this.frm.pagename : this.frm.pagetype;
			let is_pagetype_custom = is_pagetype_form ? this.frm.pg.custom : false;

			if (pagetype != "PageType" && !is_pagetype_custom && this.frm.meta.issingle === 0) {
				this.page.add_menu_item(
					__("Customize"),
					() => {
						if (this.frm.meta && this.frm.meta.custom) {
							jingrow.set_route("Form", "PageType", pagetype);
						} else {
							jingrow.set_route("Form", "Customize Form", {
								pg_type: pagetype,
							});
						}
					},
					true
				);
			}
		}

		if (jingrow.model.can_create("PageType")) {
			if (jingrow.boot.developer_mode === 1 && !is_pagetype_form) {
				// edit pagetype
				this.page.add_menu_item(
					__("Edit PageType"),
					() => {
						jingrow.set_route("Form", "PageType", this.frm.pagetype);
					},
					true
				);
			}
		}
	}

	can_repeat() {
		return this.frm.meta.allow_auto_repeat && !this.frm.is_new() && !this.frm.pg.auto_repeat;
	}
	can_save() {
		return this.get_pagestatus() === 0;
	}
	can_submit() {
		return (
			this.get_pagestatus() === 0 &&
			!this.frm.pg.__islocal &&
			!this.frm.pg.__unsaved &&
			this.frm.perm[0].submit &&
			!this.has_workflow()
		);
	}
	can_update() {
		return (
			this.get_pagestatus() === 1 &&
			!this.frm.pg.__islocal &&
			this.frm.perm[0].submit &&
			this.frm.pg.__unsaved
		);
	}
	can_cancel() {
		return this.get_pagestatus() === 1 && this.frm.perm[0].cancel && !this.read_only;
	}
	can_amend() {
		return this.get_pagestatus() === 2 && this.frm.perm[0].amend && !this.read_only;
	}
	has_workflow() {
		if (this._has_workflow === undefined)
			this._has_workflow = jingrow.get_list("Workflow", {
				document_type: this.frm.pagetype,
			}).length;
		return this._has_workflow;
	}
	get_pagestatus() {
		return cint(this.frm.pg.pagestatus);
	}
	show_linked_with() {
		if (!this.frm.linked_with) {
			this.frm.linked_with = new jingrow.ui.form.LinkedWith({
				frm: this.frm,
			});
		}
		this.frm.linked_with.show();
	}
	set_primary_action(dirty) {
		if (!dirty) {
			// don't clear actions menu if dirty
			this.page.clear_user_actions();
		}

		var status = this.get_action_status();
		if (status) {
			// When moving from a page with status amend to another page with status amend
			// We need to check if document is already amend specifically and hide
			// or clear the menu actions accordingly

			if (status !== this.current_status && status === "Amend") {
				let pg = this.frm.pg;
				jingrow
					.xcall("jingrow.client.is_document_amended", {
						pagetype: pg.pagetype,
						pagename: pg.name,
					})
					.then((is_amended) => {
						if (is_amended) {
							this.page.clear_actions();
							return;
						}
						this.set_page_actions(status);
					});
			} else {
				this.set_page_actions(status);
			}
		} else {
			this.page.clear_actions();
			this.current_status = null;
		}
	}
	get_action_status() {
		var status = null;
		if (this.frm.page.current_view_name === "print" || this.frm.hidden) {
			status = "Edit";
		} else if (this.can_submit()) {
			status = "Submit";
		} else if (this.can_save()) {
			if (!this.frm.save_disabled) {
				//Show the save button if there is no workflow or if there is a workflow and there are changes
				if (this.has_workflow() ? this.frm.pg.__unsaved : true) {
					status = "Save";
				}
			}
		} else if (this.can_update()) {
			status = "Update";
		} else if (this.can_cancel()) {
			status = "Cancel";
		} else if (this.can_amend()) {
			status = "Amend";
		}
		return status;
	}
	set_page_actions(status) {
		var me = this;
		this.page.clear_actions();

		if (status !== "Edit") {
			var perm_to_check = this.frm.action_perm_type_map[status];
			if (!this.frm.perm[0][perm_to_check]) {
				return;
			}
		}

		if (status === "Edit") {
			this.page.set_primary_action(
				__("Edit"),
				function () {
					me.frm.page.set_view("main");
				},
				"edit"
			);
		} else if (status === "Cancel") {
			let add_cancel_button = () => {
				this.page.set_secondary_action(__(status), function () {
					me.frm.savecancel(this);
				});
			};
			if (this.has_workflow()) {
				jingrow
					.xcall("jingrow.model.workflow.can_cancel_document", {
						pagetype: this.frm.pg.pagetype,
					})
					.then((can_cancel) => {
						if (can_cancel) {
							add_cancel_button();
						}
					});
			} else {
				add_cancel_button();
			}
		} else {
			var click = {
				Save: function () {
					return me.frm.save("Save", null, this);
				},
				Submit: function () {
					return me.frm.savesubmit(this);
				},
				Update: function () {
					return me.frm.save("Update", null, this);
				},
				Amend: function () {
					return me.frm.amend_pg();
				},
			}[status];

			var icon = {
				Update: "edit",
			}[status];

			this.page.set_primary_action(__(status), click, icon);
		}

		this.current_status = status;
	}
	add_update_button_on_dirty() {
		var me = this;
		$(this.frm.wrapper).on("dirty", function () {
			me.show_title_as_dirty();

			// clear workflow actions
			me.frm.page.clear_actions_menu();

			// enable save action
			if (!me.frm.save_disabled) {
				me.set_primary_action(true);
			}
		});
	}
	show_title_as_dirty() {
		if (this.frm.save_disabled && !this.frm.set_dirty) return;

		if (this.frm.is_dirty()) {
			this.page.set_indicator(__("Not Saved"), "orange");
		}

		$(this.frm.wrapper).attr("data-state", this.frm.is_dirty() ? "dirty" : "clean");
	}

	show_jump_to_field_dialog() {
		let visible_fields_filter = (f) =>
			!["Section Break", "Column Break", "Tab Break"].includes(f.df.fieldtype) &&
			!f.df.hidden &&
			f.disp_status !== "None";

		let fields = this.frm.fields
			.filter(visible_fields_filter)
			.map((f) => ({ label: __(f.df.label), value: f.df.fieldname }));

		let dialog = new jingrow.ui.Dialog({
			title: __("Jump to field"),
			fields: [
				{
					fieldtype: "Autocomplete",
					fieldname: "fieldname",
					label: __("Select Field"),
					options: fields,
					reqd: 1,
				},
			],
			primary_action_label: __("Go"),
			primary_action: ({ fieldname }) => {
				dialog.hide();
				this.frm.scroll_to_field(fieldname);
			},
			animate: false,
		});

		dialog.show();
	}
};
