import React, { useState, useEffect} from 'react';

/* 
 * It works a little something like this:
 * Choose what source and destination action you want
 * Select the source field to be used for a required destination field OR 
 * write a static value for the field (FIXME) OR
 * run a generator action for the field (FIXME, these should be e.g. run workflow and get result)
 */

import Grid from '@material-ui/core/Grid';
import Dialog from '@material-ui/core/Dialog';
import DialogTitle from '@material-ui/core/DialogTitle';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';

import ButtonBase from '@material-ui/core/ButtonBase';
import TextField from '@material-ui/core/TextField';
import MenuItem from '@material-ui/core/MenuItem';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
import InputLabel from '@material-ui/core/InputLabel';
import Table from '@material-ui/core/Table';
import InputAdornment from '@material-ui/core/InputAdornment';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableRow from '@material-ui/core/TableRow';

import SearchIcon from '@material-ui/icons/Search';
import DeleteIcon from '@material-ui/icons/Delete';

import Downshift from 'downshift';
import deburr from 'lodash/deburr';

const EditSchedule = (props) => {
  	const { globalUrl } = props;

	const [tmpSrcApp, setTmpSrcApp] = useState({})
	const [tmpDstApp, setTmpDstApp] = useState({})
	const [srcApp, setSrcApp] = useState({})
	const [srcAppConfig, setSrcAppConfig] = useState([])
	const [srcAppConfigOpen, setSrcAppConfigOpen] = useState(false)
	const [srcAppAction, setSrcAppAction] = useState("")

	const [dstApp, setDstApp] = useState({})
	const [dstAppAction, setDstAppAction] = useState("")
	const [dstAppConfig, setDstAppConfig] = useState([])
	const [dstAppConfigOpen, setDstAppConfigOpen] = useState(false)

	// Lets set the real data here
	const [selectedSrc, setSelectedSrc] = React.useState("");
	const [, setSelectedSrcData] = React.useState({});
	const [selectedDst, setSelectedDst] = React.useState([]);

	// FIXME
	const [suggestions, setSuggestions] = React.useState([]);
	const [inputappdata, setInputAppData] = React.useState({});

	const [scheduleConfig, setScheduleConfig] = React.useState({})
	const [selectedSrcParameters, setSelectedSrcParameters] = React.useState([])

	const getCurrentSchedule = () => {
		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'GET',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			setScheduleConfig(responseJson)
    	})
		.catch(error => {
    		console.log(error)
		});
	}

	const loadAppSuggestions = () => {
		fetch(globalUrl+"/api/v1/schedules/apps", {
    	  	method: 'GET',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			setSuggestions(responseJson.apps)
    	})
		.catch(error => {
    		console.log(error)
		});
	}

	// FIXME - this is generated from app selection input with required items
	useEffect(() => {
		if (Object.getOwnPropertyNames(scheduleConfig).length <= 0) {
			getCurrentSchedule()
		}

		// Load apps if destination or source is 
		if (suggestions.length === 0) {
			loadAppSuggestions()
		}

		// Load everything else
		if (Object.getOwnPropertyNames(scheduleConfig).length > 0 && Object.getOwnPropertyNames(scheduleConfig.appinfo.sourceapp).length > 0 && Object.getOwnPropertyNames(srcApp).length <= 0) {
			if (scheduleConfig.appinfo.sourceapp.name.length > 0) {
				setSrcApp(scheduleConfig.appinfo.sourceapp)
				setSrcAppAction(scheduleConfig.appinfo.sourceapp.action)
			}
		}


				// Use sourceapp.name&version and sourceapp.action and look for name in inputappdata
		// Basically fix everything in this one lol
		if (suggestions.length > 0 && srcAppAction.length > 0 && Object.getOwnPropertyNames(scheduleConfig).length > 0 && Object.getOwnPropertyNames(inputappdata).length <= 0) {
			// Loops all apps and finds current
			for (var key in suggestions) {
				var curapp = suggestions[key]
				if (curapp.name === srcApp.name) {
					break
				}
			}

			setInputAppData(curapp)

			// Loops the apps actions to find current 
			for (key in curapp.output) {
				var curappaction = curapp.output[key]
				if (curappaction.name === srcAppAction) {
					break
				}
			}

			setSelectedSrcParameters(curappaction.outputparameters)
			if (curappaction.config !== null && curappaction.config !== undefined) {
				setSrcAppConfig(curappaction.config)
			}

			// FIXME - set src of all translator nodes to curappaction.outputparameters[0] if not defined
			//value={scheduleConfig.translator[count].src.name}
			
			//console.log(scheduleConfig)
			var newtranslator = []
			for (key in scheduleConfig.translator) {
				var curtranslator = scheduleConfig.translator[key]

				// Overwrite issues
				if (curtranslator.src.name === "") {
					curtranslator.src = curappaction.outputparameters[0]
				}

				newtranslator.push(curtranslator)
			}

			scheduleConfig.translator = newtranslator
			setScheduleConfig(scheduleConfig)
		}

		if (suggestions.length > 0 && dstAppAction.length <= 0 && Object.getOwnPropertyNames(scheduleConfig).length > 0) {
			// Loops all apps and finds current
			for (key in suggestions) {
				curapp = suggestions[key]
				if (curapp.name === dstApp.name) {
					break
				}
			}

			const curAction = scheduleConfig.appinfo.destinationapp.action

			// Loops the apps actions to find current 
			for (key in curapp.output) {
				curappaction = curapp.output[key]
				if (curappaction.name === curAction) {
					break
				}
			}

			setDstAppAction(curappaction.name)
			if (curappaction.config !== null && curappaction.config !== undefined) {
				setDstAppConfig(curappaction.config)
			}
		}


	})

	const getSuggestions = (value, type, { showEmpty = false } = {}) => {
	  	const inputValue = deburr(value.trim()).toLowerCase();
	  	const inputLength = inputValue.length;
	  	let count = 0;

	  	return inputLength === 0 && !showEmpty
	    	? []
	    	: suggestions.filter(suggestion => {
	        const keep = 
				count < 5 && 
				suggestion.types &&
				suggestion.types.includes(type) &&
				suggestion.name.slice(0, inputLength).toLowerCase() === inputValue;
	
	        if (keep) {
	          count += 1;
	        }
	
	        return keep;
	      });
		}

	const setSrcAppWrapper = (currentapps) => {
		setSrcApp(currentapps[0])
		if (currentapps[0].output.length > 0) {
			selectSrcAction(currentapps[0].output[0].name)
		} 
	}

	const setDstAppWrapper = (currentapps) => {
		setDstApp(currentapps[0])
		if (currentapps[0].input.length > 0) {
			selectInitialDstAction(currentapps)
		} 
	}

	const renderInput = (type, inputProps) => {
  		const { InputProps, classes, ref, ...other } = inputProps;

		// Sets the srcapp if string is matching exactly for name
		if (InputProps["aria-activedescendant"] === null && InputProps["value"].length > 0) {
			const currentapps = suggestions.filter(data => data.name === InputProps["value"])
			if (currentapps.length === 1) {
				if (type === "output") {
					if (currentapps[0].name !== srcApp.name) {
						setSrcAppWrapper(currentapps)
					}
				} else if (type === "input") {
					if (currentapps[0].name !== dstApp.name) {
						setDstAppWrapper(currentapps)
					}
				}
			}
		}

  		return (
			<div>
  		  	<TextField
			    id="standard-search"
				type="search"
				inputStyle={{ fontSize: '10rem' }}
  		    	InputProps={{
					disableUnderline: true,
  		    		inputRef: ref,
  		    	  	...InputProps,
					startAdornment: (
						<InputAdornment position="start">
							<SearchIcon />
						</InputAdornment>
					),
  		    	}}
  		    	{...other}
  		  	/>
			</div>
  		);
	}

	const renderSuggestion = (suggestionProps) => {
  		const { suggestion, index, itemProps, highlightedIndex, selectedItem } = suggestionProps;
  		const isHighlighted = highlightedIndex === index;
  		const isSelected = (selectedItem || '').indexOf(suggestion.name) > -1;

  		return (
  		  <MenuItem
  		    {...itemProps}
  		    key={suggestion.name}
  		    selected={isHighlighted}
  		    component="div"
  		    style={{
  		      fontWeight: isSelected ? 500 : 400,
  		    }}
  		  >
  		    {suggestion.name}
  		  </MenuItem>
  		);
	}	

	const bodyDivStyle = {
		marginLeft: "20px", 
		marginTop: "50px", 
		marginRight: "20px", 
		margin: "auto",
		width: "1350px",
		display: "flex",
	}

	const appActionStyle = {
		height: "50px",
		marginTop: "10px",
	}

	// FIXME - set this
	//const setRelationshipsFromSource = () => {

	//}

	//// FIXME - set this
	//const setRelationshipsFromGenerator = () => {

	//}

	const selectDstAppAction = (event) => {
		if (event.target.value === dstAppAction) {
			return
		}

		setDstAppAction(event.target.value)
		refactorTranslations(event.target.value)
	}

	const refactorTranslations = (action) => {
		// dstapp is chosen
		var found = false
		for (var key in dstApp.input) {
			var curinput = dstApp.input[key]
			if (curinput.name === action) {
				found = true
				break
			}
		}

		// Should never happen..
		if (!found) {
			return
		}

		var tmprelationships = []
		for (key in curinput.inputparameters) {
			var curRelation = {"dst": curinput.inputparameters[key], "src": {}}
			tmprelationships.push(curRelation)
		}

		scheduleConfig["translator"] = tmprelationships
		setScheduleConfig(scheduleConfig)
	}

	const selectInitialDstAction = (value) => {
		var action = value[0].input[0].name
		setDstAppAction(action)

		var found = false
		for (var key in value) {
			var curinput = value[0].input[key]
			if (curinput.name === action) {
				found = true
				break
			}
		}

		// Should never happen..
		if (!found) {
			return
		}

		var tmprelationships = []
		for (key in curinput.inputparameters) {
			var curRelation = {"dst": curinput.inputparameters[key], "src": {}}
			tmprelationships.push(curRelation)
		}

		scheduleConfig["translator"] = tmprelationships
		setScheduleConfig(scheduleConfig)
	}


  	const selectSrcAction = (value) => {
		// FIXME - load the config for this action
		var found = false

		setSrcAppAction(value)

		var curitem = {}
		for (var key in inputappdata.output) {
			curitem = inputappdata.output[key]
			if (curitem.name === value) {
				found = true
				break
			}
		}

		if (!found) {
			setSelectedSrcParameters([])
			return
		}
		
		// Generate this for every relation?
		setSelectedSrcParameters(curitem.outputparameters)

		//FIXME - check if source has the right attribute
		var tmprelationships = []
		key = 0
		for (key in scheduleConfig.translator) {
			var curRelation = scheduleConfig.translator[key]
			curRelation["src"] = curitem.outputparameters[0]
			tmprelationships.push(curRelation)
		}

		scheduleConfig["translator"] = tmprelationships
		setScheduleConfig(scheduleConfig)
	}

	// Wrapper to handle event click
	const selectSrcActionWrapper = (event) => {
		return selectSrcAction(event.target.value)
	}

	const srcappaction = Object.getOwnPropertyNames(srcApp).length > 0 && srcApp.output ? 
		<div>
			<FormControl variant="outlined" style={{marginTop: "10px"}}>
		    	<InputLabel htmlFor="outlined-age-simple">
					Actions	
				</InputLabel>
				<Select
					value={srcAppAction}
					onChange={selectSrcActionWrapper}
					style={appActionStyle}
				>
					{srcApp.output.map(data => (
						<MenuItem value={data.name}>
							{data.name}
						</MenuItem>
					))}
				</Select>
			</FormControl>
		</div> 
		: null

	const dstappaction = Object.getOwnPropertyNames(dstApp).length > 0 ? 
		<div>
			<FormControl fullWidth="true" variant="outlined" style={{marginTop: "20px"}}>
		    	<InputLabel htmlFor="outlined-age-simple">
					Actions	
				</InputLabel>
				<Select
					value={dstAppAction}
					onChange={selectDstAppAction}
					style={appActionStyle}
				>
					{dstApp.input.map(data => (
						<MenuItem value={data.name}>
							{data.name}
						</MenuItem>
					))}
				</Select>
			</FormControl>
		</div> 
		: null

	const downshiftStyle = {
		//marginLeft: "20px", 
		//marginTop: "20px", 
		//marginRight: "20px", 
		display: "flex",
		width: "100%",
	}

	const submitDisabled = selectedSrc.length > 0 && selectedDst.length > 0
	const submitButtonClick = () => {
		var newtranslations = []
		var tobeadded = []
		var tobechanged = []

		// Go find the information again in testdata

		//newrelationship["translator"] = {"src": {}, "dst": {}} 
		//newrelationship["static"] = {}

		// Reformat relationships
		// clean up old relationships
		//
	
		if (Object.getOwnPropertyNames(scheduleConfig.Translator).length <= 0) {
			return
		}

		// Clean up old translations for specified elements
		// FIXME - maybe just send a request with relationships and fix in backend? 
		// FIXME - there is an issue here for some multifield stuff
		// Literally have to verify every single one anyway..
		for (var selected in selectedDst) {
			var found = false
			var index = 0
			for (var key in scheduleConfig["translator"]) {
				if (scheduleConfig["translator"][key]["dst"]["name"] === selectedDst[selected]) {
					index = key
					found = true
					break
				} 
			}

			if (!found) {
				tobeadded.push(selectedDst[selected])
			} else {
				// Dst can be the 
				tobechanged.push(index)
			}
		}

		var tmprelationships = scheduleConfig 

		key = 0
		for (key in scheduleConfig["translator"]) {
			if (tobechanged.includes(key)) {
				var tmprel = scheduleConfig["translator"][key]
				tmprel["src"] = {"name": selectedSrc}
				tmprelationships["translator"].splice(key, 1)
				newtranslations.push(tmprel)
			}
		}

		key = 0
		for (key in tobeadded) {
			tmprel = {"src": {"name": selectedSrc}, "dst": {"name": tobeadded[key]}}
			newtranslations.push(tmprel)
		}

		// delete deletable keys from copy (new)
		// 
		key = 0
		for (key in newtranslations) {
			tmprelationships["translator"].push(newtranslations[key])
		}

		setSelectedSrc("")
		setSelectedDst([])
		setSelectedSrcData({})

		// FIXME - does this work?
		scheduleConfig["translator"] = tmprelationships["translator"]
		setScheduleConfig(scheduleConfig)
	}

	// When it's set, need to find the destination in the row and set static
	const setStaticValue = (event, row) => {
		console.log("HI")
		// FIXME - modify the row first
		// FIXME - set generator and source to "nothing"
		
		console.log(row.dst.name)
		console.log(row)
		console.log(event.target.value)
		var newsrcrow = {"name": "static", "description": "Static value set", "type": "static", "value": event.target.value, "schema": {"type": "string"}}

		var relationshipclone = JSON.parse(JSON.stringify(scheduleConfig));
		for (var key in scheduleConfig["translator"]) {
			var curItem = scheduleConfig["translator"][key]
			if (curItem.dst.name === row.dst.name) {
				break
			}
		}

		relationshipclone["translator"][key]["src"] = newsrcrow 

		scheduleConfig["translator"] = relationshipclone["translator"]
		console.log(scheduleConfig)

		// Fuck this :( 
		// DO DIS IN FRONTEND AND HAVE A SUBMIT BUTTON :(
		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
				body: JSON.stringify(scheduleConfig),
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			setScheduleConfig({})
    	})
		.catch(error => {
    		console.log(error)
		});
	}

	// Rewrites relationships clientside
	const setCurrentSrcPropRelation = (event, rowkey) => {
		console.log(event, rowkey)
		var found = false

		for (var key in selectedSrcParameters) {
			var curItem = selectedSrcParameters[key]
			if (curItem.name === event.target.value) {
				found = true
				break
			}
		}

		// No idea how this would ever happen, but but (:
		if (!found) {
			return
		}
		
		var row = scheduleConfig.translator[rowkey]
		var rowclone = JSON.parse(JSON.stringify(row));
		rowclone.src = curItem

		var relationshipclone = JSON.parse(JSON.stringify(scheduleConfig));
		for (key in scheduleConfig["translator"]) {
			curItem = scheduleConfig["translator"][key]
			if (curItem.dst.name === row.dst.name) {
				break
			}
		}

		relationshipclone["translator"][key] = rowclone 

		scheduleConfig["translator"] = relationshipclone["translator"]
		console.log(scheduleConfig)

		// Fuck this :( 
		// DO DIS IN FRONTEND AND HAVE A SUBMIT BUTTON :(
		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
				body: JSON.stringify(scheduleConfig),
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			setScheduleConfig({})
    	})
		.catch(error => {
    		console.log(error)
		});
		return 
	}



	const relationshipBody = Object.getOwnPropertyNames(scheduleConfig).length > 0 && scheduleConfig["translator"] !== undefined && scheduleConfig.translator.length > 0 ?
		<Table style={{marginBottom: "30px"}}>
			<TableBody>
				<TableRow key="header">
					<TableCell component="th" scope="row">
					 	Action 	
					</TableCell>
					<TableCell component="th" scope="row">
						Source Field
					</TableCell>
					<TableCell component="th" scope="row">
						Destination	Field
					</TableCell>
					<TableCell component="th" scope="row">
						Field Type	
					</TableCell>
					<TableCell component="th" scope="row">
						Required	
					</TableCell>
					<TableCell component="th" scope="row">
						Static	
					</TableCell>
					<TableCell component="th" scope="row">
						Generator	
					</TableCell>
					<TableCell component="th" scope="row">
						Transform	
					</TableCell>
				</TableRow>
        		{scheduleConfig.translator.map((row, count) => {
					var buttonIcon = <DeleteIcon />
					if (!row.dst.required) {
						buttonIcon = <Button 
							disabled={!submitDisabled} 
							onClick={submitButtonClick} 
							variant="outlined" 
							color="primary"
						>REMOVEME</Button>
					}

					const srcpropsSelector = (Object.getOwnPropertyNames(selectedSrcParameters).length > 0  || Object.getOwnPropertyNames(scheduleConfig.translator).length > 0) && Object.getOwnPropertyNames(srcApp).length > 0  ? 
						<Select
							value={scheduleConfig.translator[count].src.name}
							style={appActionStyle}
							onChange={(e) => {setCurrentSrcPropRelation(e, count)}}
						>
							{selectedSrcParameters.map(data => (
								<MenuItem value={data.name}>
									{data.name}
								</MenuItem>
							))}
						</Select> : <div>No defined fields</div>

					const placeholderValue = row.src.type === "static" ? row.src.value : "... Set a static value"

					return(
						<TableRow>
							<TableCell component="th" scope="row">
								{buttonIcon}	
							</TableCell>
							<TableCell>{srcpropsSelector}</TableCell>
							<TableCell>{row.dst.name}</TableCell>
							<TableCell>{row.dst.schema.type}</TableCell>
							<TableCell>{row.dst.required}</TableCell>
							<TableCell>
								<TextField
									color="primary"
									name="searchtext"
									placeholder={placeholderValue}
									InputProps={{
										disableUnderline: true,
									}}
									onKeyPress={(event) => {
										if (event.key === 'Enter') {
											event.preventDefault();
											console.log(`Pressed keyCode ${event.key}`);
											setStaticValue(event, row)
										}
									}}
       		        			/>
							</TableCell>
							<TableCell>INSERT SCRIPT THINGY - Cortex responder?</TableCell>
						</TableRow>
					)
				})}
			</TableBody>
		</Table> : null


	// FIXME - use this
	//const submitRelationships = () => {
	//	// Make an API-call to the backend for verification
	//	// Return with failures etc, and mark row issues?
	//	
	//	var apiUrl = "http://localhost:5000"
	//	fetch(apiUrl+"/api/v1/schedules",
	//			{
	//				method: "POST",
	//				headers: {"content-type": "application/json"},
	//				body: JSON.stringify(scheduleConfig),
	//			}
	//	)
	//	.then((response) => response.json())
	//	.then((responseJson) => {
	//		console.log(responseJson)
	//	})
	//	.catch((error) => {
	//		console.log(error);
	//	});
	//}

	const executeSchedule = () => {
		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key+"/execute", {
    	  	method: 'GET',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			console.log(responseJson)
    	})
		.catch(error => {
    		console.log(error)
		});
	}


	const submitButton = 
		<div style={{margin: "auto", marginTop: "20px"}}> 
			<Button 
				onClick={executeSchedule} 
				variant="outlined" 
				color="primary"
			>
				Execute
			</Button>
		</div>

	// Requires src or dst as input
	// FIXME - use this shit to edit an app or something
	//const editButtonFix = (app, apptype) => {
	//	if (apptype === "src") {

	//	} else if (apptype === "dst") {

	//	}
	//}

	const editSrcApp = (event) => {
		// if tmpsrcapp, show RESET (can be an X or something too)
		// if reset is clicked, set source app back to the original
		setTmpSrcApp(scheduleConfig.appinfo.sourceapp)

		var tmpscheduleConfig = scheduleConfig
		tmpscheduleConfig.appinfo.sourceapp = {} 

		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
				body: JSON.stringify(tmpscheduleConfig),
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			setScheduleConfig({})
			setSrcApp({})
			setSrcAppAction("")
    	})
		.catch(error => {
    		console.log(error)
		});
	}

	const editDstApp = (event) => {
		// if tmpsrcapp, show RESET (can be an X or something too)
		// if reset is clicked, set source app back to the original
		setTmpDstApp(scheduleConfig.appinfo.destinationapp)

		var tmpscheduleConfig = scheduleConfig
		tmpscheduleConfig.appinfo.destinationapp = {} 

		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
				body: JSON.stringify(tmpscheduleConfig),
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			setScheduleConfig({})
			setDstApp({})
			setDstAppAction("")
    	})
		.catch(error => {
    		console.log(error)
		});
	}

	const scheduleApp = (app, actiondata) => {
		const editButton = actiondata === "src" ? 
			<Button 
				onClick={(event) => {editSrcApp(event)}} 
				style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
				variant="outlined" 
				color="primary"
			>Edit</Button>
			: 
			<Button 
				onClick={(event) => {editDstApp(event)}} 
				style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
				variant="outlined" 
				color="primary"
			>Edit</Button>

		
			
		const configureButton = actiondata === "src" ? 
			<Button 
				disabled={srcAppConfig.length === 0} 
				style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
				onClick={() => setSrcAppConfigOpen(true)} 
				variant="outlined" 
				color="primary"
			>Config</Button>
			: <Button 
				disabled={dstAppConfig.length === 0} 
				style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
				onClick={() => setDstAppConfigOpen(true)} 
				variant="outlined" 
				color="primary"
			>Config</Button>

		// FIXME - set src vs dst 
		return(
			<Grid container spacing={2} style={{margin: "10px 10px 10px 10px"}}>
				<Grid item>
					<ButtonBase>
						<img alt="" style={{width: "100px", height: "100px"}} />
					</ButtonBase>
				</Grid>
				{splitter}
				<Grid item xs={12} sm container style={{marginLeft: "10px"}}>
					<Grid item xs container direction="column" spacing={2}>
						<Grid item xs>
							<div>
								<h2>{app.name}</h2> 
							</div>
							<div>
								{app.description}	
							</div>
						</Grid>
						<Grid item>
							{app.action}		
              			</Grid>
					</Grid>
					{splitter}
					<Grid item style={{marginLeft: "10px", display: "flex", flexDirection: "column"}}>
						<div style={{flex: "1"}}>
							{editButton}
						</div>
						<div style={{flex: "1"}}>
							{configureButton}
						</div>
					</Grid>
				</Grid>
			</Grid>
		)
	}

	const splitter = <div style={{width: "1px", backgroundColor: "grey", margin:"5px 5px 5px 5px"}} />

	const dstDownshift = 
		<Downshift style={downshiftStyle}>
			{({
			  getInputProps,
			  getItemProps,
			  getMenuProps,
			  highlightedIndex,
			  inputValue,
			  isOpen,
			  selectedItem,
			}) => (
			  <div style={{flex: "1"}}>
				{renderInput("input", {
					fullWidth: true,
					InputProps: getInputProps({
						placeholder: 'Search destination apps',
				  }),
				})}

				<div>
					<div {...getMenuProps()}>
					  {isOpen ? (
						<Paper  square>
						  {getSuggestions(inputValue, "input").map((suggestion, index) =>
							renderSuggestion({
							  suggestion,
							  index,
							  itemProps: getItemProps({ item: suggestion.name }),
							  highlightedIndex,
							  selectedItem,
							}),
						  )}
						</Paper>
					  ) : null}
					</div>
					{dstappaction}
				</div>
			  </div>
			)}
		</Downshift>


	const srcDownshift = 
		<Downshift style={downshiftStyle}>
			{({
			  getInputProps,
			  getItemProps,
			  getMenuProps,
			  highlightedIndex,
			  inputValue,
			  isOpen,
			  selectedItem,
			}) => (
			  <div style={{flex: "1"}}>
				{renderInput("output", {
					fullWidth: true,
					InputProps: getInputProps({
						placeholder: 'Search source apps',
				  }),
				})}

				<div>
					<div {...getMenuProps()}>
					  {isOpen ? (
						<Paper  square>
						  {getSuggestions(inputValue, "output").map((suggestion, index) =>
							renderSuggestion({
							  suggestion,
							  index,
							  itemProps: getItemProps({ item: suggestion.name }),
							  highlightedIndex,
							  selectedItem,
							}),
						  )}
						</Paper>
					  ) : null}
					</div>
					{srcappaction}
				</div>
			  </div>
			)}
		</Downshift>

	const submitDstApp = (event) => {
		var packagedSrc = {
			name: dstApp.name,
			id: dstApp.id,
			description: dstApp.description,
			action: dstAppAction,
		}

		var tmpscheduleConfig = scheduleConfig

		tmpscheduleConfig.appinfo.destinationapp = packagedSrc

		// Hmm, do this here? Idk
		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
				body: JSON.stringify(tmpscheduleConfig),
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			setScheduleConfig({})
    	})
		.catch(error => {
    		console.log(error)
		});
	}

	const submitSrcApp = (event) => {
		var packagedSrc = {
			name: srcApp.name,
			id: srcApp.id,
			description: srcApp.description,
			action: srcAppAction,
		}

		var tmpscheduleConfig = scheduleConfig

		// FIXME - future fred
		//
		tmpscheduleConfig.appinfo.sourceapp = packagedSrc

		// Hmm, do this here? Idk
		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
				body: JSON.stringify(tmpscheduleConfig),
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			setScheduleConfig({})
    	})
		.catch(error => {
    		console.log(error)
		});
	}

	const resetDstApp = (event) => {
		var tmpscheduleConfig = scheduleConfig
		tmpscheduleConfig.appinfo.destinationapp = tmpDstApp

		// Hmm, do this here? Idk
		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
				body: JSON.stringify(tmpscheduleConfig),
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			setScheduleConfig({})
			setDstApp(tmpSrcApp)
			setDstAppAction(tmpDstApp.action)
			setTmpDstApp({})
    	})
		.catch(error => {
    		console.log(error)
		});

	}

	const resetSrcApp = (event) => {
		var tmpscheduleConfig = scheduleConfig
		tmpscheduleConfig.appinfo.sourceapp = tmpSrcApp

		// Hmm, do this here? Idk
		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
				body: JSON.stringify(tmpscheduleConfig),
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			setScheduleConfig({})
			setSrcApp(tmpSrcApp)
			setSrcAppAction(tmpSrcApp.action)
			setTmpSrcApp({})
    	})
		.catch(error => {
    		console.log(error)
		});

	}

	// Based on some srcthing
	const searchGridSrc =
		<Grid container spacing={2} style={{margin: "10px 10px 10px 10px"}}>
			<Grid item style={{width: "100px", height: "100px"}}>
				Choose Source app (FIXME) - clickable 
			</Grid>
			{splitter}
			<Grid item xs={12} sm container style={{marginLeft: "10px"}}>
				<Grid item xs container direction="column" spacing={2}>
					<Grid item xs>
						<div>
							{srcDownshift}
						</div>
					</Grid>
				</Grid>
				{splitter}
				<Grid item style={{marginLeft: "10px", display: "flex", flexDirection: "column"}}>
					<div style={{flex: "1"}}>
						<Button 
							disabled={Object.getOwnPropertyNames(srcApp).length === 0} 
							onClick={(event) => {submitSrcApp(event)}} 
							style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
							variant="outlined" 
							color="primary"
						>Submit</Button>
					</div>
					<div style={{flex: "1"}}>
						<Button 
							disabled={Object.getOwnPropertyNames(tmpSrcApp).length === 0} 
							onClick={resetSrcApp} 
							style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
							variant="outlined" 
							color="primary"
						>Reset</Button>
					</div>
				</Grid>
			</Grid>
		</Grid>

	const searchGridDst =
		<Grid container spacing={2} style={{margin: "10px 10px 10px 10px"}}>
			<Grid item style={{width: "100px", height: "100px"}}>
				Choose Source app (FIXME) - clickable 
			</Grid>
			{splitter}
			<Grid item xs={12} sm container style={{marginLeft: "10px"}}>
				<Grid item xs container direction="column" spacing={2}>
					<Grid item xs>
						<div>
							{dstDownshift}
						</div>
					</Grid>
				</Grid>
				{splitter}
				<Grid item style={{marginLeft: "10px", display: "flex", flexDirection: "column"}}>
					<div style={{flex: "1"}}>
						<Button 
							disabled={Object.getOwnPropertyNames(dstApp).length === 0} 
							onClick={(event) => {submitDstApp(event)}} 
							style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
							variant="outlined" 
							color="primary"
						>Submit</Button>
					</div>
					<div style={{flex: "1"}}>
						<Button 
							disabled={Object.getOwnPropertyNames(tmpDstApp).length === 0} 
							onClick={resetDstApp} 
							style={{left: "50%", top: "50%", transform: "translate(-50%, -50%)"}}
							variant="outlined" 
							color="primary"
						>Reset</Button>
					</div>
				</Grid>
			</Grid>
		</Grid>


	const srcField = (Object.getOwnPropertyNames(scheduleConfig).length > 0 && Object.getOwnPropertyNames(scheduleConfig.appinfo.sourceapp).length > 0 && scheduleConfig.appinfo.sourceapp.name.length > 0) ? 
		<div style={{marginLeft: "20px", margintop: "20px", marginRight: "20px", flex:"1"}}>
			<Paper style={{maxWidth: "100%", display: "flex", padding: "10px 10px 10px 10px"}}>
				{scheduleApp(scheduleConfig.appinfo.sourceapp, "src")}
			</Paper>
		</div>
		:
		<div style={{marginLeft: "20px", margintop: "20px", marginRight: "20px", flex:"1"}}>
			<Paper style={{minHeight: "136px", maxHeight: "136px", maxWidth: "100%", display: "flex", padding: "10px 10px 10px 10px"}}>
				{searchGridSrc}
			</Paper>
		</div>

	const dstField = (Object.getOwnPropertyNames(scheduleConfig).length > 0 && Object.getOwnPropertyNames(scheduleConfig.appinfo.destinationapp).length > 0 && scheduleConfig.appinfo.destinationapp.name.length > 0) ? 
		<div style={{marginLeft: "20px", margintop: "20px", marginRight: "20px", flex:"1"}}>
			<Paper style={{maxWidth: "100%", display: "flex", padding: "10px 10px 10px 10px"}}>
				{scheduleApp(scheduleConfig.appinfo.destinationapp, "dst")}
			</Paper>
		</div>
		:
		<div style={{marginLeft: "20px", margintop: "20px", marginRight: "20px", flex:"1"}}>
			<Paper style={{minHeight: "136px", maxHeight: "136px", maxWidth: "100%", display: "flex", padding: "10px 10px 10px 10px"}}>
				{searchGridDst}
			</Paper>
		</div>

	// Have to use array cus of datastore lol (no map[string]string)
	const srcModalData = []
	const buildSrcModal = (event, fieldname) => {
		var fieldfound = false
		for (var key in srcModalData) {
			if (srcModalData[key]["key"] === fieldname)   {
				fieldfound = true
				srcModalData[key]["value"] = event.target.value
				break
			}
		}

		if (!fieldfound) {
			srcModalData.push({"key": fieldname, "value": event.target.value})
		}
		console.log(srcModalData)
	}

	// FIXME - verify required fields?
	const submitSrcConfig = () => {
		scheduleConfig.appinfo.sourceapp.config = srcModalData
		setScheduleConfig(scheduleConfig)
		setSrcAppConfigOpen(false)

		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
				body: JSON.stringify(scheduleConfig),
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			console.log(responseJson)
    	})
		.catch(error => {
    		console.log(error)
		});
	}

	const dstModalData = []
	const buildDstModal = (event, fieldname) => {
		var fieldfound = false
		for (var key in dstModalData) {
			if (dstModalData[key]["key"] === fieldname)   {
				fieldfound = true
				dstModalData[key]["value"] = event.target.value
				break
			}
		}

		if (!fieldfound) {
			dstModalData.push({"key": fieldname, "value": event.target.value})
		}
		console.log(dstModalData)
	}

	// FIXME - verify required fields
	const submitDstConfig = () => {
		scheduleConfig.appinfo.destinationapp.config = dstModalData
		setScheduleConfig(scheduleConfig)
		setDstAppConfigOpen(false)

		fetch(globalUrl+"/api/v1/schedules/"+props.match.params.key, {
    	  	method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'Accept': 'application/json',
				},
				body: JSON.stringify(scheduleConfig),
    		})
		.then((response) => response.json())
    	.then((responseJson) => {
			console.log(responseJson)
    	})
		.catch(error => {
    		console.log(error)
		});
	}

	const dstConfigModal = dstAppConfigOpen ?
		<Dialog modal 
			open={dstAppConfigOpen} 
			onClose={() => {setDstAppConfigOpen(false)}}
		>
			<DialogTitle>Source configuration</DialogTitle>
			<DialogContent>
				Configure {dstApp.name}'s required fields
				{dstAppConfig.map(data => (
					<TextField
      	 				onChange={(event) => {buildDstModal(event, data.name)}}
						autofocus
						color="primary"
						name="searchtext"
						placeholder={data.name}
						margin="dense"
						id={data.name}
						label={data.name}
						fullWidth
					  />
				))}
			</DialogContent>
			<DialogActions>
	          	<Button onClick={() => setDstAppConfigOpen(false)} color="primary">
	            	Cancel
	          	</Button>
	          	<Button onClick={() => submitDstConfig()} color="primary">
	            	Submit	
	          	</Button>
	        </DialogActions>
		</Dialog> : null


	// FIXME - load the actual fields!
	const srcConfigModal = srcAppConfigOpen ?
		<Dialog modal 
			open={srcAppConfigOpen} 
			onClose={() => {setSrcAppConfigOpen(false)}}
		>
			<DialogTitle>Source configuration</DialogTitle>
			<DialogContent>
				Configure {srcApp.name}'s required fields
				{srcAppConfig.map(data => (
					<TextField
      	 				onChange={(event) => {buildSrcModal(event, data.name)}}
						autofocus
						color="primary"
						name="searchtext"
						placeholder={data.name}
						margin="dense"
						id={data.name}
						label={data.name}
						fullWidth
					  />
				))}
			</DialogContent>
			<DialogActions>
	          	<Button onClick={() => setSrcAppConfigOpen(false)} color="primary">
	            	Cancel
	          	</Button>
	          	<Button onClick={() => submitSrcConfig()} color="primary">
	            	Submit	
	          	</Button>
	        </DialogActions>
		</Dialog> : null

	return(
		<div>
			{srcConfigModal}
			{dstConfigModal}
			<div style={bodyDivStyle}>
				{srcField}
				{dstField}
			</div>
			
			<div style={bodyDivStyle}>
				{submitButton}
			</div>
			<div style={bodyDivStyle}>
				{relationshipBody}	
			</div>
		</div>
	)
}

export default EditSchedule 
