
import { Meteor } from 'meteor/meteor';
import React, { useState } from 'react';
import { useTracker } from 'meteor/react-meteor-data';
import _ from 'lodash';



//{columns.map((column) => <td>{column.value(row)}</td>)}
const WholeRow = ({row, columns}) => {
	return <tr><td>Test</td></tr>
}

const ColumnHeader = ({column}) => {
	// console.log("Rendering column header")
	return <td>
		{column.isActions ?
			"TODO: Add widgets"
			:
			column.title
		}
	</td>
}

const Row = ({columns, row, getRowKey, editedRowKey, editor, setEdited}) => {
	return <tr><td>Test</td></tr>
}
/*
<tr>
		{!editedRowKey || getRowKey(row) !== editedRowKey ?
			columns.map((column, i) => <Cell column={column} row={row}/>)
			:
			editor
		}
	</tr>
 */
// onDoubleClick={(e) => {(!editedRowKey || getRowKey(row) !== editedRowKey) && setEdited(row)}}
const Cell = ({row, column}) => {
	return <td>test</td>
}
/*
<td>
		{column.isActions ?
			"TODO"
			:
			column.value(row)
		}
	</td>
 */

/**
 * Example: 
 *     import {useState} from 'react';
 *     const[edited, setEdited] = useState(undefined);
 *     <GridTable setEdited={setEdited} edited={edited} rows={rows} columns={columnns} actions={actions}>
 *         <!-- Editor JSX here. -->
 *     </GridTable>
 *     
 * export let rows;
	export let columns;
	export let rowKey;  //Must only be null/undefined if the row is a new object (not associated with a row in the table).  Should not change.
	export let edited;
	export let actions;
	export let selection;
 * @param props
 * @returns {JSX.Element}
 */
export default ({columns, rows, actions, getRowKey, edited, setEdited, children}) => {
	// Setup a width for each column.
	columns.forEach(column => {
		let min = column.minWidth ? Math.max(10, column.minWidth) : 10;
		let weight = column.weight ? Math.max(1, column.weight) : 1;
		column.width = 'minmax(' + min + 'px, ' + weight + 'fr)';
		column.isActions = false;
	});
	
	// Add the actions column to the end.
	// TODO: Allow it to be positioned.
	if(actions) {
		// TODO: make this fixed width based on the possible widget widths.
		actions.width = 'minmax(10px, 1fr)';
		actions.isActions = true;
		columns[columns.length] = actions;
	}

	// Collect the column widths for the layout.
	let gridTemplateColumns = columns.map(({width}) => width).join(' ');

	// Resize column code.
	let headerBeingResized = null;
	let horizontalScrollOffset = 0;
	const initResize = ({target}) => {
		headerBeingResized = target.parentNode;
		window.addEventListener('mousemove', onMouseMove);
		window.addEventListener('mouseup', completeResize);
		headerBeingResized.classList.add('header--being-resized');
	};
	const completeResize = () => {
		window.removeEventListener('mousemove', onMouseMove);
		window.removeEventListener('mouseup', completeResize);
		headerBeingResized.classList.remove('header--being-resized');
		headerBeingResized = null;
	};
	const onMouseMove = e => {
		try {
			// Calculate the desired width.
			horizontalScrollOffset = document.documentElement.scrollLeft;
			let parentX = Math.round(headerBeingResized.getBoundingClientRect().x);
			const width = horizontalScrollOffset + (e.clientX - parentX);
			// Update the column object with the new size value.
			const column = columns.find(({element}) => element === headerBeingResized);
			column.width = Math.max(column.minWidth, width) + "px";
			// Ensure all the column widths are converted to fixed sizes.
			columns.forEach((column, index) => {
				if((index < columns.length - 1) && (column.width.startsWith('minmax'))) {
					column.width = parseInt(column.element.clientWidth, 10) + 'px';
				}
			});
			// Render the new column sizes.
			gridTemplateColumns = columns.map(({width}) => width).join(' ');
		} catch(e) {console.log(e);}
	}
	
	// Select row code.
	let selectedRowElement = null;
	const selectRow = (e, row) => {
		let element = e.target;

		while(element && element.nodeName !== "TR") element = element.parentNode;

		if(selectedRowElement) {
			selectedRowElement.classList.remove('selected');
		}

		selectedRowElement = element;
		element.classList.add('selected');
		dispatch('selection', selectedRowElement.dataset.key);
	}
	
	// Edit row code.
	let editorContainer;
	let editorTable;
	// Listen for changes to the edited variable.  Move the editor row and display it when there is a value.
	// Relies on the table row being hidden when the edited value matches the row's value.
	useTracker(() => {
		if(editorContainer) {
			if(edited) {
				let id = rowKey($edited);
				let hiddenRow = editorTable.querySelector('tbody tr[data-key="' + id + '"]');

				if(!hiddenRow) {
					let body = editorTable.querySelector('tbody');
					body.firstChild ? body.insertBefore(editorContainer, body.firstChild) : body.appendChild(editorContainer);
					editorContainer.classList.remove('hidden');
				}
				else {
					//let editor = hiddenRow.querySelector('.editor');
					let body = editorTable.querySelector('tbody');
					let next = hiddenRow.nextSibling;
					//editor.appendChild(editorContainer);
					next ? body.insertBefore(editorContainer, next) : body.appendChild(editorContainer);
					editorContainer.classList.remove('hidden');
				}
			}
			else {
				console.log("Edited cleared");
				editorContainer.classList.add('hidden');
			}
		}
	});
	
	let editedRowKey = edited ? getRowKey(edited) : undefined;
	console.log("Rendering grid table")
	
	// let contents = "";
	//
	// for(let row of rows) {
	// 	contents += <WholeRow row={row} columns={columns}/>
	// 	// contents += <tr>
	// 	// for(let column of columns) {
	// 	// 	contents += <CellValue row={row} column={column}></CellValue>
	// 	// }
	// 	// contents += </tr>
	// }
	
	return <div className={'grid-table-container'}>
		<table style={{gridTemplateColumns}}>
			<thead>
			<tr>
				{columns.map((column, i) => <ColumnHeader key={column.key} column={column}/>)}
			</tr>
			</thead>
			<tbody>
				{/*{rows.map((row, i) => <Row key={getRowKey(row)} row={row} columns={columns} getRowKey={getRowKey} editedRowKey={editedRowKey} editor={children} setEdited={setEdited}/>)}*/}
				{rows.map((row)=><WholeRow row={row} columns={columns}/>)}
			</tbody>
		</table>
	</div>
}