import type { Ref, ComputedRef } from 'vue'
import type { CellPosition, ColumnConfig, Row, SpreadsheetChange } from '../types'
import { formatCellValue, parseValueForFormat } from '../utils'

export function useSpreadsheetClipboard(
	localRows: Ref<Row[]>,
	columns: ComputedRef<ColumnConfig[]>,
	selectionStart: Ref<CellPosition | null>,
	selectionEnd: Ref<CellPosition | null>,
	saveState: (type: SpreadsheetChange['type']) => void,
	isCellEditable: (key: string) => boolean,
	createEmptyRow: () => Row,
	emitUpdate: () => void,
) {
	async function copySelection() {
		if (!selectionStart.value || !selectionEnd.value) { return }

		const startRow = Math.min(selectionStart.value.row, selectionEnd.value.row)
		const endRow = Math.max(selectionStart.value.row, selectionEnd.value.row)
		const startCol = Math.min(selectionStart.value.col, selectionEnd.value.col)
		const endCol = Math.max(selectionStart.value.col, selectionEnd.value.col)

		const tsv = Array.from({ length: endRow - startRow + 1 }, (_, ri) => {
			return Array.from({ length: endCol - startCol + 1 }, (_, ci) => {
				const col = columns.value[startCol + ci]
				return formatCellValue(localRows.value[startRow + ri][col.key], col.format)
			}).join('\t')
		}).join('\n')

		try {
			await navigator.clipboard.writeText(tsv)
		} catch (err) {
			console.error('Failed to copy:', err)
		}
	}

	async function pasteSelection() {
		if (!selectionStart.value) { return }

		try {
			const text = await navigator.clipboard.readText()
			const pasteRows = text.split('\n').map(r => r.split('\t'))

			saveState('paste')

			const startRow = selectionStart.value.row
			const startCol = selectionStart.value.col

			const neededRows = startRow + pasteRows.length - localRows.value.length
			for (let i = 0; i < neededRows; i++) {
				localRows.value.push(createEmptyRow())
			}

			pasteRows.forEach((rowData, ri) => {
				rowData.forEach((cellValue, ci) => {
					const targetCol = startCol + ci
					if (targetCol >= columns.value.length) { return }
					const col = columns.value[targetCol]
					if (!isCellEditable(col.key)) { return }
					localRows.value[startRow + ri][col.key] = parseValueForFormat(cellValue, col.format)
				})
			})

			emitUpdate()
		} catch (err) {
			console.error('Failed to paste:', err)
		}
	}

	return { copySelection, pasteSelection }
}
