(function ($) {
	"use strict";

	var Table = function (element, options) {
		this.options = options;
		this.$element = element;
		this.table;

		this.$element.on(
			"click",
			function (event) {
				if (options.isAddCheckbox) {
					var $td = $(event.target).closest("td");
					var $checkbox = $td.find("input[type='checkbox']");
					this.onToggleCheckbox($td, $checkbox);
				} else {
					var $row = $(event.target).closest("tr");
					this.onRowClick(event, $row);
				}
			}.bind(this)
		);

		if (options.isEditable) {
			options.rowsGroup = null;
		}

		if (options.isAddCheckbox) {
			options.columnDefs = [
				{
					targets: 0,
					orderable: false,
					searchable: false,
					data: null,
					defaultContent: "",
					className: "select-checkbox"
				},
				{ targets: 1, aDataSort: [1] }
			].concat(options.columnDefs);

			options.columns = [
				{
					data: null,
					title: $('<input type="checkbox" name="checkall" />')[0].outerHTML,
					render: function () {
						return $('<input type="checkbox" class="editor-active" name="checkbox" />')[0].outerHTML;
					},
					orderable: false,
					className: "dt-body-center"
				}
			].concat(options.columns);

			options.select = { style: "multi", selector: "td:first-child" };
		}
	};

	Table.prototype = {
		constructor: Table,

		onToggleCheckAll: function (element) {
			if (!element) {
				return false;
			}
			console.log("onToggleCheckAll => ", element);
			var tr = this.table.rows({ filter: "applied" }).nodes();
			var isChecked = $(element).prop("checked");

			if (isChecked) {
				this.table.rows({ filter: "applied" }).select();
			} else {
				this.table.rows({ filter: "applied" }).deselect();
			}

			$.each(tr, function () {
				$(this).find('input[type="checkbox"]').prop("checked", isChecked);
			});

			// 사용자 정의 이벤트 발생
			this.$element.trigger("checkbox.toggle.checkAll", [ element, !isChecked]);
		},

		onToggleCheckbox: function ($td, $checkbox) {
			var $row = $td.closest("tr");
			var isChecked = $row.hasClass("selected");

			if (!$checkbox.length) return;

			$checkbox.prop("checked", !isChecked);
			$row.toggleClass("selected");

			// 사용자 정의 이벤트 발생
			this.$element.trigger("checkbox.toggle.table", [this.getData($row), $row, !isChecked]);
		},

		onRowClick: function (event, $row) {
			if (!this.options.select) return;

			console.log("onRowClick => ", $row);
			this.selectedData = this.table.row($row).data();

			if ($row.hasClass("selected")) {
				var event = $.Event("deselect.table", { target: event.target });
				console.log("deselect.table => ", event);
				this.$element.trigger(event, [this.selectedData, $row]);
			} else {
				var event = $.Event("select.table", { target: event.target });
				console.log("selected");
				this.table.$("tr.selected").removeClass("selected");
				this.$element.trigger(event, [this.selectedData, $row]);
			}

			$row.toggleClass("selected");
		},

		dataTableBuild: function () {
			var self = this;

			this.table = this.$element.DataTable(this.options);

			var tableWrapper = this.$element.closest(".dataTables_wrapper");

			$.fn.dataTable.ext.errMode = function () {
				jError("Notification : <strong>Ajax Error</strong>, retry plz !");
			};

			if (this.options.isAddCheckbox) {
				tableWrapper.on("change", 'input[name="checkall"]', function () {
					self.onToggleCheckAll(this);
				});
			}

			if (this.options.isEditable) {
				tableWrapper.find(".dataTables_filter").append(
					$("<button class='btn btn-sm btn-warning' data-locale='asset_migration.datatable.instance.addBtn'/>")
						.css({ marginLeft: "10px" })
						.text(this.options.editBtn)
						.click(function () {
							var rowData = self.options.columns.reduce(function (columnList, column) {
								return $.extend({}, columnList, { [column.data]: null });
							}, {});

							self.addRows([rowData]);
						})
				);
			}
		},

		clear: function () {
			this.table.clear();
		},

		addRows: function (rows) {
			this.table.rows.add(rows).draw(true); // 현재 페이지를 유지하면서 테이블을 다시 그림.
			this.table.columns.adjust().responsive.recalc();
		},

		reDraw: function (rows) {
			this.clear();
			this.addRows(rows);
		},

		reSize: function () {
			this.table.columns.adjust().responsive.recalc();
		},

		empty: function () {
			this.table.destroy();
			this.$element.empty();
			this.$element.data("arms.table", null);
		},

		removeRows: function (callback) {
			var selectedRow = this.table.rows({ selected: true });
			var selectedData = selectedRow.data().toArray();

			selectedRow.remove().draw();

			if ($.isFunction(callback)) {
				callback(selectedData);
			}
		},

		getSelectedData: function () {
			return this.options.select.style === "multi"
				? this.table.rows({ selected: true }).data().toArray()
				: this.table.row({ selected: true }).data();
		},

		getColumns: function () {
			return this.options.columns;
		},

		getData: function ($row) {
			return this.table.row($row).data();
		},

		getDatas: function () {
			return this.table.rows().data().toArray();
		}
	};

	$.fn.table = function (option) {
		var $this = $(this);
		var table = $this.data("arms.table");

		if (typeof option === "string") {
			if (!table) return false;
			return table[option]();
		}
		if (!table || (typeof option === "object" && option !== null)) {
			var options = $.extend({}, $.fn.table.defaults, option);

			$this.data("arms.table", (table = new Table(this, options)));
			table.dataTableBuild();
		}

		return table;
	};

	$.fn.table.defaults = {
		data: [],
		stateSave: false,
		destroy: true,
		processing: true,
		serverSide: false,
		scrollX: true,
		scrollY: true,
		scrollCollapse: true,
		responsive: false,
		columns: [],
		rowsGroup: null,
		columnDefs: [
			{
				targets: "_all", // 모든 컬럼에 적용
				createdCell: function (td) {
					var $td = $(td);

					if ($.isNumeric($td.text())) {
						$(td).addClass("dt-body-right");
					}
				}
			}
		],
		isAddCheckbox: false,
		isEditable: false,
		editBtn: "로우 추가",
		select: true,
		pagingType: "simple_numbers",
		order: [[0, "asc"]],
		buttons: [
			"copy",
			{
				extend: "csv",
				charset: "UTF-8",
				bom: true
			},
			"excel",
			"print",
			{
				extend: "pdfHtml5",
				orientation: "landscape",
				pageSize: "LEGAL"
			}
		],
		language: {
			processing: "",
			loadingRecords:
				"<span class='spinner' style='font-size: 14px !important;'><i class='fa fa-spinner fa-spin'></i> 데이터를 처리 중입니다.</span>",
			paginate: {
				next: "<i class='fa fa-chevron-right'></i>",
				previous: "<i class='fa fa-chevron-left'></i>"
			}
		},
		pageLength: 10
	};

	$.fn.table.Constructor = Table;
})(jQuery);
