import TiptapTableCell from "@tiptap/extension-table-cell";
import { Plugin } from "@tiptap/pm/state";
import { Decoration, DecorationSet } from "@tiptap/pm/view";

import { getCellsInColumn, isRowSelected, isTableSelected, selectRow, selectTable } from "./utils";

export const TableCell = TiptapTableCell.extend({
	addAttributes() {
		return {
			colspan: {
				default: 1,
				parseHTML: (element) => {
					const colspan = element.getAttribute("colspan");
					const value = colspan ? parseInt(colspan, 10) : 1;

					return value;
				},
			},
			rowspan: {
				default: 1,
				parseHTML: (element) => {
					const rowspan = element.getAttribute("rowspan");
					const value = rowspan ? parseInt(rowspan, 10) : 1;

					return value;
				},
			},
			colwidth: {
				default: null,
				parseHTML: (element) => {
					const colwidth = element.getAttribute("colwidth");
					const value = colwidth ? [parseInt(colwidth, 10)] : null;

					return value;
				},
			},
			style: {
				default: null,
			},
		};
	},
	addProseMirrorPlugins() {
		const { isEditable } = this.editor;

		return [
			new Plugin({
				props: {
					decorations: (state) => {
						if (!isEditable) {
							return DecorationSet.empty;
						}

						const { doc, selection } = state;
						const decorations: Decoration[] = [];
						const cells = getCellsInColumn(0)(selection);

						if (cells) {
							cells.forEach(({ pos }: { pos: number }, index: number) => {
								if (index === 0) {
									decorations.push(
										Decoration.widget(pos + 1, () => {
											const tableSelected = isTableSelected(selection);
											let className = "grip-row-col";
											if (tableSelected) {
												className += " selected";
											}
											const grip = document.createElement("a");
											grip.className = className;
											grip.addEventListener("mousedown", (event) => {
												event.preventDefault();
												event.stopImmediatePropagation();

												this.editor.view.dispatch(selectTable(this.editor.state.tr));
											});

											return grip;
										}),
									);
								}

								decorations.push(
									Decoration.widget(pos + 1, () => {
										const rowSelected = isRowSelected(index)(selection);
										let className = "grip-row";

										if (rowSelected) {
											className += " selected";
										}

										if (index === 0) {
											className += " first";
										}

										if (index === cells.length - 1) {
											className += " last";
										}

										const grip = document.createElement("a");

										grip.className = className;
										grip.addEventListener("mousedown", (event) => {
											event.preventDefault();
											event.stopImmediatePropagation();

											this.editor.view.dispatch(selectRow(index)(this.editor.state.tr));
										});

										return grip;
									}),
								);
							});
						}

						return DecorationSet.create(doc, decorations);
					},
				},
			}),
		];
	},
});

export default TableCell;
