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

jingrow.provide("jingrow.meta.pagefield_map");
jingrow.provide("jingrow.meta.pagefield_copy");
jingrow.provide("jingrow.meta.pagefield_list");
jingrow.provide("jingrow.meta.pagetypes");
jingrow.provide("jingrow.meta.precision_map");

jingrow.get_meta = function (pagetype) {
	return locals["PageType"] ? locals["PageType"][pagetype] : null;
};

$.extend(jingrow.meta, {
	sync: function (pg) {
		$.each(pg.fields, function (i, df) {
			jingrow.meta.add_field(df);
		});
		jingrow.meta.sync_messages(pg);
		if (pg.__print_formats) jingrow.model.sync(pg.__print_formats);
		if (pg.__workflow_pgs) jingrow.model.sync(pg.__workflow_pgs);
	},

	// build pagefield_map and pagefield_list
	add_field: function (df) {
		jingrow.provide("jingrow.meta.pagefield_map." + df.parent);
		jingrow.meta.pagefield_map[df.parent][df.fieldname || df.label] = df;

		if (!jingrow.meta.pagefield_list[df.parent]) jingrow.meta.pagefield_list[df.parent] = [];

		// check for repeat
		for (var i in jingrow.meta.pagefield_list[df.parent]) {
			var d = jingrow.meta.pagefield_list[df.parent][i];
			if (df.fieldname == d.fieldname) return; // no repeat
		}
		jingrow.meta.pagefield_list[df.parent].push(df);
	},

	make_pagefield_copy_for: function (pagetype, pagename, pagefield_list = null) {
		var c = jingrow.meta.pagefield_copy;
		if (!c[pagetype]) c[pagetype] = {};
		if (!c[pagetype][pagename]) c[pagetype][pagename] = {};

		pagefield_list = pagefield_list || jingrow.meta.pagefield_list[pagetype] || [];
		for (var i = 0, j = pagefield_list.length; i < j; i++) {
			var df = pagefield_list[i];
			c[pagetype][pagename][df.fieldname || df.label] = copy_dict(df);
		}
	},

	get_field: function (pagetype, fieldname, name) {
		var out = jingrow.meta.get_pagefield(pagetype, fieldname, name);

		// search in standard fields
		if (!out) {
			jingrow.model.std_fields.every(function (d) {
				if (d.fieldname === fieldname) {
					out = d;
					return false;
				} else {
					return true;
				}
			});
		}
		return out;
	},

	get_pagefield: function (pagetype, fieldname, name) {
		var fields_dict = jingrow.meta.get_pagefield_copy(pagetype, name);
		return fields_dict ? fields_dict[fieldname] : null;
	},

	set_formatter: function (pagetype, fieldname, name, formatter) {
		jingrow.meta.get_pagefield(pagetype, fieldname, name).formatter = formatter;
	},

	set_indicator_formatter: function (pagetype, fieldname, name, get_text, get_color) {
		jingrow.meta.get_pagefield(pagetype, fieldname, name).formatter = function (
			value,
			df,
			options,
			pg
		) {
			return repl('<span class="indicator %(color)s">%(name)s</span>', {
				color: get_color(),
				name: get_text(),
			});
		};
	},

	get_pagefields: function (pagetype, name, filters) {
		var pagefield_map = jingrow.meta.get_pagefield_copy(pagetype, name);

		var pagefields = jingrow.meta.sort_pagefields(pagefield_map);

		if (filters) {
			pagefields = jingrow.utils.filter_dict(pagefields, filters);
		}

		return pagefields;
	},

	get_linked_fields: function (pagetype) {
		return $.map(jingrow.get_meta(pagetype).fields, function (d) {
			return d.fieldtype == "Link" ? d.options : null;
		});
	},

	get_fields_to_check_permissions: function (pagetype) {
		var fields = $.map(jingrow.meta.get_pagefields(pagetype, name), function (df) {
			return df.fieldtype === "Link" && df.ignore_user_permissions !== 1 ? df : null;
		});
		fields = fields.concat({ label: "ID", fieldname: name, options: pagetype });
		return fields;
	},

	sort_pagefields: function (pgs) {
		return $.map(pgs, function (d) {
			return d;
		}).sort(function (a, b) {
			return a.idx - b.idx;
		});
	},

	get_pagefield_copy: function (pagetype, name) {
		if (!name) return jingrow.meta.pagefield_map[pagetype];

		if (!(jingrow.meta.pagefield_copy[pagetype] && jingrow.meta.pagefield_copy[pagetype][name])) {
			jingrow.meta.make_pagefield_copy_for(pagetype, name);
		}

		return jingrow.meta.pagefield_copy[pagetype][name];
	},

	get_fieldnames: function (pagetype, name, filters) {
		return $.map(
			jingrow.utils.filter_dict(jingrow.meta.pagefield_map[pagetype], filters),
			function (df) {
				return df.fieldname;
			}
		);
	},

	has_field: function (dt, fn) {
		let pagefield_map = jingrow.meta.pagefield_map[dt];
		return pagefield_map && pagefield_map[fn];
	},

	get_table_fields: function (dt) {
		return $.map(jingrow.meta.pagefield_list[dt], function (d) {
			return jingrow.model.table_fields.includes(d.fieldtype) ? d : null;
		});
	},

	get_pagetype_for_field: function (pagetype, key) {
		var out = null;
		if (jingrow.model.std_fields_list.includes(key)) {
			// standard
			out = pagetype;
		} else if (jingrow.meta.has_field(pagetype, key)) {
			// found in parent
			out = pagetype;
		} else {
			jingrow.meta.get_table_fields(pagetype).every(function (d) {
				if (
					jingrow.meta.has_field(d.options, key) ||
					jingrow.model.child_table_field_list.includes(key)
				) {
					out = d.options;
					return false;
				}
				return true;
			});

			if (!out) {
				console.log(
					__("Warning: Unable to find {0} in any table related to {1}", [
						key,
						__(pagetype),
					])
				);
			}
		}
		return out;
	},

	get_parentfield: function (parent_dt, child_dt) {
		var df = (jingrow.get_pg("PageType", parent_dt).fields || []).filter(
			(df) => jingrow.model.table_fields.includes(df.fieldtype) && df.options === child_dt
		);
		if (!df.length) throw "parentfield not found for " + parent_dt + ", " + child_dt;
		return df[0].fieldname;
	},

	get_label: function (dt, fn, dn) {
		var standard = {
			name: __("ID"),
			creation: __("Created On"),
			pagestatus: __("Document Status"),
			idx: __("Index"),
			modified: __("Last Updated On"),
			modified_by: __("Last Updated By"),
			owner: __("Created By"),
			_user_tags: __("Tags"),
			_liked_by: __("Liked By"),
			_comments: __("Comments"),
			_assign: __("Assigned To"),
		};
		if (standard[fn]) {
			return standard[fn];
		} else {
			var df = this.get_pagefield(dt, fn, dn);
			return (df ? df.label : "") || fn;
		}
	},

	get_print_sizes: function () {
		return [
			"A0",
			"A1",
			"A2",
			"A3",
			"A4",
			"A5",
			"A6",
			"A7",
			"A8",
			"A9",
			"B0",
			"B1",
			"B2",
			"B3",
			"B4",
			"B5",
			"B6",
			"B7",
			"B8",
			"B9",
			"B10",
			"C5E",
			"Comm10E",
			"DLE",
			"Executive",
			"Folio",
			"Ledger",
			"Legal",
			"Letter",
			"Tabloid",
			"Custom",
		];
	},

	get_print_formats: function (pagetype) {
		var print_format_list = ["Standard"];
		var default_print_format = locals.PageType[pagetype].default_print_format;
		let enable_raw_printing = jingrow.model.get_pg(
			":Print Settings",
			"Print Settings"
		).enable_raw_printing;
		var print_formats = jingrow
			.get_list("Print Format", { pg_type: pagetype })
			.sort(function (a, b) {
				return a > b ? 1 : -1;
			});
		$.each(print_formats, function (i, d) {
			if (
				!print_format_list.includes(d.name) &&
				d.print_format_type !== "JS" &&
				(cint(enable_raw_printing) || !d.raw_printing)
			) {
				print_format_list.push(d.name);
			}
		});

		if (default_print_format && default_print_format != "Standard") {
			var index = print_format_list.indexOf(default_print_format);
			print_format_list.splice(index, 1).sort();
			print_format_list.unshift(default_print_format);
		}

		return print_format_list;
	},

	sync_messages: function (pg) {
		if (pg.__messages) {
			$.extend(jingrow._messages, pg.__messages);
		}
	},

	get_field_currency: function (df, pg) {
		var currency = jingrow.boot.sysdefaults.currency || "USD";
		if (!pg && cur_frm) pg = cur_frm.pg;

		if (df && df.options) {
			if (df.options.indexOf(":") != -1) {
				var options = df.options.split(":");
				if (options.length == 3) {
					let pagename = null;
					if (pg) {
						// get reference record e.g. Company
						pagename = pg[options[1]];
						if (!pagename && cur_frm) {
							pagename = cur_frm.pg[options[1]];
						}
					} else {
						// Try to get default value, useful for cases like Company overridden in session defaults
						pagename = jingrow.defaults.get_user_default(options[1]);
					}
					currency =
						jingrow.model.get_value(options[0], pagename, options[2]) ||
						jingrow.model.get_value(":" + options[0], pagename, options[2]) ||
						currency;
				}
			} else if (pg && pg[df.options]) {
				currency = pg[df.options];
			} else if (cur_frm && cur_frm.pg[df.options]) {
				currency = cur_frm.pg[df.options];
			}
		}
		return currency;
	},

	get_field_precision: function (df, pg) {
		var precision = null;
		if (df && df.precision) {
			precision = cint(df.precision);
		} else if (df && df.fieldtype === "Currency") {
			precision = cint(jingrow.defaults.get_default("currency_precision"));
			if (!precision) {
				var number_format = get_number_format();
				var number_format_info = get_number_format_info(number_format);
				precision = number_format_info.precision;
			}
		} else {
			precision = cint(jingrow.defaults.get_default("float_precision")) || 3;
		}
		return precision;
	},
});
