import type { EditorState } from '../richTextTypes'

export function insertTable(rows: number, cols: number, state: EditorState) {
	if (!state.doc) { return }
	const table = state.doc.createElement('table')
	table.style.width = '100%'
	table.style.borderCollapse = 'collapse'
	table.style.marginBottom = '1rem'

	// Add a header row
	const thead = state.doc.createElement('thead')
	const headerRow = thead.insertRow()
	for (let j = 0; j < cols; j++) {
		const th = state.doc.createElement('th')
		th.innerHTML = `Header ${j + 1}`
		th.style.padding = '8px'
		th.style.border = '1px solid var(--border-color, #ddd)'
		th.style.backgroundColor = 'var(--bgl-gray-light, #f4f4f4)'
		headerRow.appendChild(th)
	}
	table.appendChild(thead)

	// Add body rows
	const tbody = state.doc.createElement('tbody')
	for (let i = 0; i < rows; i++) {
		const row = tbody.insertRow()
		for (let j = 0; j < cols; j++) {
			const cell = row.insertCell()
			cell.innerHTML = '&nbsp;'
			cell.style.padding = '8px'
			cell.style.border = '1px solid var(--border-color, #ddd)'
		}
	}
	table.appendChild(tbody)

	// Insert the table at the current selection
	const { range } = state
	if (range) {
		range.insertNode(table)

		// Move cursor inside first cell for convenience
		if (state.doc.getSelection()) {
			const firstCell = table.querySelector('td')
			if (firstCell) {
				range.selectNodeContents(firstCell)
				range.collapse(true)
				const selection = state.doc.getSelection()
				if (selection) {
					selection.removeAllRanges()
					selection.addRange(range)
				}
			}
		}
	} else {
		state.doc.body.appendChild(table)
	}
	state.content = state.doc.body.innerHTML
}

export function mergeCells(range: Range, doc: Document) {
	const cells = Array.from(range.cloneContents().querySelectorAll('td'))
	if (cells.length < 2) { return }

	const firstCell = range.startContainer.parentElement?.closest('td')
	if (!firstCell) { return }

	firstCell.colSpan = cells.length
	firstCell.innerHTML = cells.map(cell => cell.innerHTML).join(' ')

	cells.slice(1).forEach((cell) => {
		const actualCell = doc.getElementById(cell.id)
		actualCell?.remove()
	})

	// Update state content
	const state = (doc as any).editorState as EditorState
	if (state) {
		state.content = doc.body.innerHTML
	}
}

export function splitCell(range: Range, doc: Document) {
	const cell = range.startContainer.parentElement?.closest('td')
	if (!cell || !cell.colSpan || cell.colSpan === 1) { return }

	const newCells = new Array(cell.colSpan - 1).fill(0).map(() => {
		const newCell = doc.createElement('td')
		newCell.style.border = '1px solid var(--border-color)'
		newCell.style.padding = '8px'
		newCell.innerHTML = '&nbsp;'
		return newCell
	})

	cell.colSpan = 1
	cell.insertAdjacentElement('afterend', newCells[0])
	newCells.slice(1).forEach((newCell) => {
		newCells[0].insertAdjacentElement('afterend', newCell)
	})

	// Update state content
	const state = (doc as any).editorState as EditorState
	if (state) {
		state.content = doc.body.innerHTML
	}
}

export function addRow(position: 'before' | 'after', range: Range, doc: Document) {
	const cell = range.startContainer.parentElement?.closest('td')
	if (!cell) { return }

	const row = cell.parentElement
	const table = row?.parentElement
	if (!row || !table) { return }

	const newRow = row.cloneNode(true) as HTMLTableRowElement
	Array.from(newRow.cells).forEach(cell => cell.innerHTML = '&nbsp;')

	row.insertAdjacentElement(position === 'before' ? 'beforebegin' : 'afterend', newRow)

	// Update state content
	const state = (doc as any).editorState as EditorState
	if (state) {
		state.content = doc.body.innerHTML
	}
}

export function deleteRow(range: Range) {
	const cell = range.startContainer.parentElement?.closest('td')
	if (!cell) { return }

	const row = cell.parentElement
	if (!row) { return }

	const doc = row.ownerDocument
	row.remove()

	// Update state content
	const state = (doc as any).editorState as EditorState
	if (state) {
		state.content = doc.body.innerHTML
	}
}

export function deleteTable(range: Range) {
	const cell = range.startContainer.parentElement?.closest('td')
	if (!cell) { return }

	const table = cell.closest('table')
	if (!table) { return }

	const doc = table.ownerDocument
	table.remove()

	// Update state content
	const state = (doc as any).editorState as EditorState
	if (state) {
		state.content = doc.body.innerHTML
	}
}

export function insertColumn(position: 'before' | 'after', range: Range) {
	const cell = range.startContainer.parentElement?.closest('td')
	if (!cell) { return }

	const table = cell.closest('table')
	if (!table) { return }

	const columnIndex = cell.cellIndex
	const { rows } = table

	for (let i = 0; i < rows.length; i++) {
		const newCell = rows[i].insertCell(position === 'after' ? columnIndex + 1 : columnIndex)
		newCell.innerHTML = '&nbsp;'
		newCell.style.border = '1px solid var(--border-color)'
		newCell.style.padding = '8px'
	}

	// Update state content
	const state = (table.ownerDocument as any).editorState as EditorState
	if (state) {
		state.content = table.ownerDocument.body.innerHTML
	}
}

export function deleteColumn(range: Range) {
	const cell = range.startContainer.parentElement?.closest('td')
	if (!cell) { return }

	const table = cell.closest('table')
	if (!table) { return }

	const columnIndex = cell.cellIndex
	const { rows } = table
	const doc = table.ownerDocument

	for (let i = 0; i < rows.length; i++) {
		rows[i].deleteCell(columnIndex)
	}

	// If no columns left, remove the table
	if (rows[0].cells.length === 0) {
		table.remove()
	}

	// Update state content
	const state = (doc as any).editorState as EditorState
	if (state) {
		state.content = doc.body.innerHTML
	}
}

export function alignColumn(range: Range, alignment: 'start' | 'center' | 'end' | 'justify') {
	const cell = range.startContainer.parentElement?.closest('td')
	if (!cell) { return }

	const table = cell.closest('table')
	if (!table) { return }

	const columnIndex = cell.cellIndex
	const { rows } = table

	for (let i = 0; i < rows.length; i++) {
		const cell = rows[i].cells[columnIndex]
		if (cell) {
			cell.style.textAlign = alignment
		}
	}

	// Update state content
	const state = (table.ownerDocument as any).editorState as EditorState
	if (state) {
		state.content = table.ownerDocument.body.innerHTML
	}
}
