import { Meteor } from 'meteor/meteor';
import React, { useState } from 'react';
import { useTracker } from 'meteor/react-meteor-data';
import _ from 'lodash';
import SimpleTable from "/imports/ui/util/SimpleTable";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import {Assets, conditions} from "/imports/api/assets";
import {AssetTypes} from "/imports/api/asset-types";
import {Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Grid, Box} from "@mui/material";

const cssEditorField = {
	margin: '0.6rem 0',
	minWidth: '200px'
}
const cssGridFieldContainer = {
	display: 'grid',
	gridTemplateColumns: "1fr 1fr",
	columnGap: '1rem',
	rowGap: '0.4rem',
	marginBottom: '1.5rem'
}
const cssFieldContainer = {
	display: 'flex',
	flexDirection: 'column',
	backgroundColor: '#DDD',
	padding: '0.5rem',
	border: '1px solid #999',
	borderRadius: '0.2rem',
}
const cssButtonContainer = {
	display: 'flex',
	gap: '1rem',
	justifyContent: 'flex-end'
}

const AssetEditor = ({value, close}) => {
	const [assetId, setAssetId] = useState(value.assetId || "")
	const [serial, setSerial] = useState(value.serial || "")
	const [condition, setCondition] = useState(value.condition || "")
	const [conditionDetails, setConditionDetails] = useState(value.conditionDetails || "")
	const [assetTypeId, setAssetTypeId] = useState(value.assetTypeId || "")
	const assetTypes = AssetTypes.find({}, {sort: {year: -1}});

	const applyChanges = () => {
		close()
		//TODO Should invert this and only close if there was success on the server.
		if(value._id)
			Meteor.call("assets.update", value._id, assetTypeId, assetId, serial, condition, conditionDetails);
		else
			Meteor.call("assets.add", assetTypeId, assetId, serial, condition, conditionDetails);
	}
	const rejectChanges = () => {
		close()
	}

	return (
		<div style={cssFieldContainer}>
			<h1>Asset Editor</h1>
			<div style={cssGridFieldContainer}>
				<TextField style={cssEditorField} select variant="standard" value={assetTypeId} onChange={(e)=>{setAssetTypeId(e.target.value)}} label="Asset Type">
					{assetTypes.map((assetType, i) => {
						return <MenuItem key={i} value={assetType._id}>{assetType.name}</MenuItem>
					})}
				</TextField>
				<TextField style={cssEditorField} variant="standard" label="Asset ID" value={assetId} onChange={(e) => {setAssetId(e.target.value.toUpperCase())}}/>
				<TextField style={cssEditorField} variant="standard" label="Serial" value={serial} onChange={(e) => {setSerial(e.target.value)}}/>
				<TextField style={cssEditorField} select variant="standard" label="Condition" value={condition} onChange={(e)=>{setCondition(e.target.value)}}>
					{conditions.map((condition, i) => {
						return <MenuItem key={i} value={condition}>{condition}</MenuItem>
					})}
				</TextField>
				<TextField style={{gridColumn: '1 / span 2',...cssEditorField}} multiline variant="outlined" rows={4} label="Condition Details" value={conditionDetails} onChange={(e) => {setConditionDetails(e.target.value)}}/>
			</div>
			<div style={cssButtonContainer}>
				<Button variant="contained" style={{gridColumn: '2/2'}} className="button accept-button" onClick={applyChanges}>Accept</Button>
				<Button type="outlined" style={{gridColumn: '3/3'}} className="button reject-button" onClick={rejectChanges}>Reject</Button>
			</div>
		</div>
	)
}

export default () => {
	Meteor.subscribe('assetTypes');
	Meteor.subscribe('assets');
	
	const [removeRow, setRemoveRow] = useState(undefined)
	const [assetId, setAssetId] = useState("")
	const [serial, setSerial] = useState("")
	const [assetTypeId, setAssetTypeId] = useState("")
	const assetTypes = [{name: "All", _id: 0}, ...AssetTypes.find({}, {sort: {year: -1}}).fetch()]
	
	
	const {assets} = useTracker(() => {
		let query = {}
		
		if(assetId) query.assetId = {$regex: assetId, $options: 'i'}
		if(serial) query.serial = {$regex: serial, $options: 'i'}
		if(assetTypeId) query.assetTypeId = assetTypeId
		
		const assets = Assets.find(query).fetch();
		const assetTypes = AssetTypes.find({}, {sort: {year: -1}}).fetch();
		const assetTypeNameMap = assetTypes.reduce((map, obj) => {
			map[obj._id] = obj;
			return map;
		}, {})

		for(let asset of assets) {
			asset.assetType = assetTypeNameMap[asset.assetTypeId]
		}

		return {
			assets
		}
	});
	
	const columns = [
		{
			name: "Asset ID",
			value: (row) => row.assetId,
			descendingComparator: (a, b) => {
				if(a.assetId === b.assetId) return 0
				else if(!a.assetId) return -1
				else if(!b.assetId) return 1
				else if(a.assetId.length < b.assetId.length) return 1
				else if(a.assetId.length > b.assetId.length) return -1
				else if(b.assetId < a.assetId) return -1
				else return 1
			}
		},
		{
			name: "Serial",
			value: (row) => row.serial,
			descendingComparator: (a, b) => {
				if(a.serial === b.serial) return 0
				else if(!a.serial) return -1
				else if(!b.serial) return 1
				else if(a.serial.length < b.serial.length) return 1
				else if(a.serial.length > b.serial.length) return -1
				else if(b.serial < a.serial) return -1
				else return 1
			}
		},
		{
			name: "Condition",
			value: (row) => row.condition,
			descendingComparator: (a, b) => {
				if(b.condition === a.condition) return 0  //Most common case
				// Find the first matching condition in order.
				for(let condition of conditions) {
					if(b.condition === condition) return -1
					else if(a.condition === condition) return 1
				}
				return 0
			}
		},
		{
			name: "AssetType",
			value: (row) => row.assetType ? row.assetType.name : "",
		},
	]
	
	const options = {
		key: (row) => row._id,
		editor: (row, close) => {return (<AssetEditor value={row} close={close}/>)},
		add: true,
		remove: (row) => {setRemoveRow(row)},
		maxHeight: '40rem'
	}
	
	const removeAsset = (asset) => {
		Meteor.call("assets.remove", asset._id);
		setRemoveRow(undefined)
	}

	return (
		<>
			<Dialog open={removeRow ? true : false} onClose={() => setRemoveRow(undefined)}>
				<DialogTitle>Remove Asset?</DialogTitle>
				<DialogContent>
					<DialogContentText>
						Are you certain you want to remove the selected Asset?
					</DialogContentText>
				</DialogContent>
				<DialogActions>
					<Button onClick={() => removeAsset(removeRow)}>Remove Asset</Button>
					<Button onClick={() => setRemoveRow(undefined)}>Cancel</Button>
				</DialogActions>
			</Dialog>
			<Box component="div" sx={{m: 2, p: 2, border: '1px dashed grey'}}>
				<h4 style={{margin: 0, padding: 0}}>Filter</h4>
				<Grid container spacing={2}>
					<Grid item xs={4}>
						<TextField style={cssEditorField} variant="standard" label="Asset ID" value={assetId} onChange={(e) => {setAssetId(e.target.value)}}/>
					</Grid>
					<Grid item xs={4}>
						<TextField style={cssEditorField} variant="standard" label="Serial" value={serial} onChange={(e) => {setSerial(e.target.value)}}/>
					</Grid>
					<Grid item xs={4}>
						<TextField style={cssEditorField} select variant="standard" value={assetTypeId} onChange={(e)=>{setAssetTypeId(e.target.value)}} label="Asset Type">
							{assetTypes.map((assetType, i) => {
								return <MenuItem key={i} value={assetType._id}>{assetType.name}</MenuItem>
							})}
						</TextField>
					</Grid>
				</Grid>
			</Box>
			<SimpleTable rows={assets} columns={columns} options={options}/>
		</>
	)
}