import React, { useState, } from "react";
import { makeStyles, createStyles } from "@mui/styles";
import { toast } from "react-toastify" 

import { 
	Tooltip,
	Typography,

	Avatar,
	AvatarGroup,
} from "@mui/material"

import {
	green,
	yellow,
	red,
} from "../views/AngularWorkflow.jsx"

import { validateJson, GetIconInfo } from "../views/Workflows.jsx";
import theme from "../theme.jsx";
const itemHeight = 40

export const getParentNodes = (workflow, action) => {
    if (action === undefined || action === null) {
      return []
    }

	if (workflow.actions === undefined || workflow.actions === null) {
		workflow.actions = []
	}

	if (workflow.triggers === undefined || workflow.triggers === null) {
		workflow.triggers = []
	}

	if (workflow.branches === undefined || workflow.branches === null) {
		workflow.branches = []
	}

    var allkeys = [action.id];
    var handled = [];
    var results = [];

    // maxiter = max amount of parent nodes to loop
    // also handles breaks if there are issues
    var iterations = 0;
    var maxiter = 10;
    while (true) {
      for (let parentkey in allkeys) {
		if (allkeys[parentkey] === undefined) {
			continue
		}

		var currentnode = workflow.actions.find((element) => element.id === allkeys[parentkey])
		if (currentnode === undefined) {
			currentnode = workflow.triggers.find((element) => element.id === allkeys[parentkey])

			if (currentnode === undefined) {
				console.log("Could not find parent node for: ", allkeys[parentkey])
				continue
			}
		}

	    if (handled.includes(currentnode.id)) {
	      continue
	    } else {
	      handled.push(currentnode.id);
	      results.push(currentnode);
	    }

        // Get the name / label here too?
        if (currentnode.length === 0) {
          continue;
        }

		// FIXME: This part is only handling first level,
		// but needs to recurse 
		var incomingEdges = []
		for (var branchkey in workflow.branches) {
			const branch = workflow.branches[branchkey]
			if (branch.destination_id !== currentnode.id) {
				continue
			}

			// Go up in the levels
			const parents = getParentNodes(workflow, {
				id: branch.source_id,
			})
			if (parents.length > 0) {
				incomingEdges = incomingEdges.concat(parents)
			}

			incomingEdges.push(branch)
		}

        for (let i = 0; i < incomingEdges.length; i++) {
          var tmp = incomingEdges[i];
          if (tmp.decorator === true) {
            continue
          }

          if (!allkeys.includes(tmp.source_id)) {
            allkeys.push(tmp.source_id)
          }
        }
      }

      if (results.length === allkeys.length || iterations === maxiter) {
        break
      }

      iterations += 1
    }

    // Remove on the end as we don't want to remove everything
    results = results.filter((data) => data.id !== action.id)
    results = results.filter((data) => data.type === "ACTION" || data.app_name === "Shuffle Workflow" || data.app_name === "User Input" || data.app_name === "shuffle-subflow")
    results.push({ label: "Execution Argument", type: "INTERNAL" })

    return results
}

const WorkflowValidationTimeline = (props) => {
	const { workflow, originalWorkflow, apps, getParents, execution} = props


	if (workflow === undefined || workflow === null) {
		return null
	}

	if (workflow.validation === undefined || workflow.validation === null) {
		return null
	}

	if (workflow.actions === undefined || workflow.actions === null) {
		workflow.actions = []
	}

	if (workflow.triggers === undefined || workflow.triggers === null) {
		workflow.triggers = []
	
	}

	if (workflow.branches === undefined || workflow.branches === null) {
		workflow.branches = []
	
	}

	var results = []
	if (execution !== undefined) {
		results = execution.results
	}

	// 1. Find startnode
	// 2. Map childnodes from it
	const startnodeId = workflow.start	

	// Find parent of startnodeId and if it's a webhook
	var relevantactions = []
	for (var key in workflow.branches) {
		const branch = workflow.branches[key]
		if (branch.destination_id !== startnodeId) {
			continue
		}

		for (var triggerkey in workflow.triggers) {
			const trigger = workflow.triggers[triggerkey]
			if (trigger.trigger_type !== "WEBHOOK") {
				continue
			}

			if (trigger.id === branch.source_id) {
				trigger.order = -1
				relevantactions.push(trigger)
				break
			}
		}
	}


	if (getParents !== undefined) {
		for (var key in workflow.actions) {
			const action = workflow.actions[key]
			if (action.id === startnodeId) {
				action.order = 0
				relevantactions.push(action)
				continue
			}

			const parents = getParents(action)
			//const parents = getParentNodes(workflow, action)
			//console.log("PARENTS", key, parents)
			if (parents !== undefined && parents !== null) {
				const parentfound = parents.find((element) => element.id === startnodeId)
				if (parentfound !== undefined) {

					// FIXME: add order here based on how many steps away from the startnode
					// This just has the parent count
					action.order = parents.length

					relevantactions.push(action)
				}
			}
		}
	} else {
		for (var key in workflow.triggers) {
			const trigger = workflow.triggers[key]
			if (trigger.trigger_type !== "SUBFLOW" && trigger.trigger_type !== "USERINPUT") {
				continue
			}

			if (workflow.actions.find((element) => element.id === trigger.id) === undefined) {
				workflow.actions.push(trigger)
			}
		}

		relevantactions = workflow.actions
	}

	// Sort according to how many parents a node has. MAY be wrong~
	relevantactions.sort((a, b) => {
		if (a.order === undefined) {
			return 1
		}

		if (b.order === undefined) {
			return -1
		}

		return a.order - b.order
	})

	// FIXME: Add other relevant items as well from subflows (?)
	var nodecolor = "grey"
	var branchcolor = "grey"
	var skipped = false

	var previousTools = false

	return (
		<div style={{border: workflow.validation.valid ? `2px solid ${green}` : "1px solid rgba(255,255,255,0.4)", padding: "10px 20px 10px 20px", borderRadius: theme.palette.borderRadius, }}>
			<div style={{display: "flex", justifyContent: "center", alignItems: "center"}}> 
			  {relevantactions.map((action, index) => {
				action.result = {}
				if (results !== undefined) {
					const foundResult = results.find((element) => element.action.id === action.id)
					if (foundResult !== undefined) {
						action.result = foundResult

						action.status = foundResult.status
					} 
				}

				const lastitem = index === relevantactions.length - 1
				if (!lastitem) {
					if (action.app_name === "Shuffle Tools") {
						if (action.status === "SUCCESS") {
							branchcolor = red

							// Check action.result for the actual status
							const validate = validateJson(action.result.result)
    						if (validate.valid) {
								if (validate.result.success === true) {
									branchcolor = green
								} else {
									branchcolor = "grey" 
								}
							}


						} else if (action.status === "SKIPPED") {
							branchcolor = "grey"
						} else {
							if (action.status === undefined) {
								branchcolor = green
							} else {
								branchcolor = red
							}
						}

						previousTools = true 
						return null
					} else {
						if (action.status === "SUCCESS") {
							nodecolor = green
						} else if (action.status === "SKIPPED") {
							nodecolor = "grey"
						} else {
							if (action.status === undefined) {
								nodecolor = green
							} else {
								nodecolor = red
							}
						}
					}
				} else {
					nodecolor = "grey"
				}

				if (action.status === "SKIPPED") {
					skipped = true
				}

				var image = ""
				if (action.large_image !== undefined && action.large_image !== null && action.large_image !== "") {
					image = action.large_image
				} else {
					if (originalWorkflow !== undefined) {
						for (var key in originalWorkflow.actions) {
							if (originalWorkflow.actions[key].id === action.id) {
								image = originalWorkflow.actions[key].large_image
								break
							}
						}

						if (image === "") {
							for (var key in originalWorkflow.triggers) {
								if (originalWorkflow.triggers[key].id === action.id) {
									image = originalWorkflow.triggers[key].large_image
									break
								}
							}

						}
					}
				}

				var founderror = ""
				if (workflow.validation !== undefined && workflow.validation !== null && workflow.validation.errors !== undefined && workflow.validation.errors !== null) {
					const foundError = workflow.validation.errors.find((element) => element.action_id === action.id)
					if (foundError !== undefined) {
						founderror = foundError.error
						nodecolor = yellow 
						branchcolor = yellow
					}
				}

				if (skipped && !lastitem) {
					nodecolor = "grey"
					branchcolor = "grey"
				}

				if (previousTools) {
					previousTools = false
				} else {
					branchcolor = nodecolor
				}

				var appgroup = []
				if (action.trigger_type === "WEBHOOK") {
					nodecolor = green
					branchcolor = green
				} else if (action.app_name === "shuffle-subflow") {
					if (action.status === "SUCCESS") {
						nodecolor = green
						branchcolor = green
					}

					for (var subflowkey in workflow.validation.subflow_apps) {
						const subflowApp = workflow.validation.subflow_apps[subflowkey]
						if (subflowApp.error === action.id) {
							appgroup.push(subflowApp)
						}
					}

				}

				var flex = index !== 0 && index !== relevantactions.length - 1 ? 1 : 3
				const branchTooltip = branchcolor === yellow ? "Check nodes for errors" : ""

				return (
					<div style={{display: "flex", flex: flex, justifyContent: "right", }}> 
						{lastitem ? 
							<Tooltip title={branchTooltip}>
								<div style={{marginLeft: 0, marginRight: 0, marginTop: 20, height: 3, width: "100%", backgroundColor: branchcolor, }} />
							</Tooltip>
						: null}

						{appgroup.length > 0 ? 
							<AvatarGroup max={4} style={{height: itemHeight+8, }}> 
								{appgroup.map((subflowApp, subflowIndex) => {
									var appimage = ""
									if (apps !== undefined && apps !== null && apps.length > 0) {
										for (var key in apps) {
											const app = apps[key]
											if (app.name === subflowApp.app_name) {
												appimage = apps[key].large_image
												break
											}
										}
									}

									return ( 
										<Tooltip title={`App: ${subflowApp.app_name} - subflow app`}>
										<Avatar
											style={{ 
												border: `4px solid ${nodecolor}`,
											}}
											src={appimage}
										/>
										</Tooltip>
									)
								})}
							</AvatarGroup>
						: 
							<Tooltip title={
								<Typography variant="body1" style={{margin: 5, color: "white", }}>
									{founderror.length > 0 ? founderror : ``} 
								</Typography>
							} placement="top">

								<Avatar
									variant="round"
									sx={{ backgroundColor: nodecolor, width: itemHeight, height: itemHeight, borderRadius: 50, border: `4px solid ${nodecolor}`,}}
								>
									{image !== "" ? 
										<img 
											src={image} 
											style={{
												width: itemHeight, 
												height: itemHeight,  
											}} 
										/> 
									: null}
								</Avatar>
							</Tooltip>
						}

						{lastitem ? null :
							<Tooltip title={branchTooltip}>
								<div style={{marginLeft: 0, marginRight: 0, marginTop: 20, height: 3, width: "100%", backgroundColor: branchcolor, }} />
							</Tooltip>
						}
					</div>
				)
			  })}
			</div>

		</div>
	)
}

export default WorkflowValidationTimeline
