import { WorkflowAction, WorkflowState, WorkflowVersion } from '../Models/WorkflowManager';
import { NodeModel } from '../GoJs/reducers/diagramReducer';
import { LinkModel, DiagramModel } from 'react-gojs';

export class WorkflowGoJsConverter {
    private _initialModel = {
        nodeDataArray: new Array<NodeModel>(),
        linkDataArray: new Array<LinkModel>()
    };

    constructor() {
        let startNode = this.createStartNode(null);
        this._initialModel.nodeDataArray.push(startNode); 
    }
    
    private getStates(model:DiagramModel<NodeModel, LinkModel>,states:WorkflowState[]):DiagramModel<NodeModel, LinkModel>{
        states.forEach((state:WorkflowState)=>{
            let stateNode = this.createStateNode(state);
            model.nodeDataArray.push(stateNode);  
            if(state.Actions){
                state.Actions.forEach((action:WorkflowAction)=>{
                    let actionNode = this.createActionNode(action);
                    model.nodeDataArray.push(actionNode);
                    if(model.linkDataArray.filter((link:LinkModel)=>{
                        return ((link.from == stateNode.key && link.to == actionNode.key)||
                        (link.from == actionNode.key && link.to == stateNode.key));
                    }).length==0){
                        model.linkDataArray.push({from:stateNode.key,to:actionNode.key});  
                    }
                    model = this.getStates(model,action.States)
                })
            }
        })

        return model;
    }
    private getActions(model:DiagramModel<NodeModel, LinkModel>,actions:WorkflowAction[]):DiagramModel<NodeModel, LinkModel>{
        actions.forEach((action:WorkflowAction)=>{
            let actionNode = this.createActionNode(action);
            model.nodeDataArray.push(actionNode);  
            if(action.States){
                action.States.forEach((state:WorkflowState)=>{
                    let stateNode = this.createStateNode(state);
                    model.nodeDataArray.push(stateNode);
                    if(model.linkDataArray.filter((link:LinkModel)=>{
                        return ((link.from == stateNode.key && link.to == actionNode.key)||
                        (link.from == actionNode.key && link.to == stateNode.key));
                    }).length==0){
                        model.linkDataArray.push({from:actionNode.key,to:stateNode.key});    
                    }
                    model = this.getActions(model,state.Actions)                    
                })
            }
        })
        
        return model;
    }
    convertWorkflowVersionToDiagramModel(workflowVersion:WorkflowVersion|null): DiagramModel<NodeModel, LinkModel>|null {
        let model = this._initialModel;        
        
        if (workflowVersion ==null)
            return model;

        if(workflowVersion.DefaultState){
            let defaultStateNode = this.createStateNode(workflowVersion.DefaultState);        
            model.nodeDataArray.push(defaultStateNode);  
            model.linkDataArray.push({from:model.nodeDataArray[0].key,to:defaultStateNode.key}); 
        }

        model = this.getStates(model,workflowVersion.States);
        model = this.getActions(model,workflowVersion.Actions);        
            
        return model; 
    }

    convertDiagramModelToWorkflowVersion(model:DiagramModel<NodeModel, LinkModel>|null,workflowId:number,workflowVersionId:number): WorkflowVersion|null {
        if (model ==null)
            return null;

        let workflowVersion = new WorkflowVersion();
        workflowVersion.IsDraft=true;
        workflowVersion.WorkflowId = workflowId;
        workflowVersion.Id = workflowVersionId;
        workflowVersion.Actions = [];
        let actions =model.nodeDataArray.filter((node:NodeModel) => node.category=="Action");
        if(actions){
            actions.forEach((action)=>{
                workflowVersion.Actions.push(action.tag);
            })
        }
        workflowVersion.States = [];
        let states = model.nodeDataArray.filter((node:NodeModel) => node.category=="State");
        if(states){
            //debugger;
            states.forEach((state)=>{
                workflowVersion.States.push(state.tag);
            })
            workflowVersion.DefaultState = states[0].tag;
        }
        return workflowVersion; 
    }

    createStartNode(tag:any){
        return { category:"Start",key: "-1", color: 'lightblue',text:"Start",tag:tag };
    }

    createConditionalNode(key:string,text:string){
        return { category:"Conditional",key: key, color: 'lightgreen',text:text };
    }
    

    createActionNode(action:WorkflowAction){
        let key = "action_"+ action.Id.toString();
        if(action.Id == 0){
            key = new Date().toString();
        }

        if(!action.Name){
            action.Name = "Action";
        }
        return { category:"Action",key: key, color: 'pink',text:action.Name,tag:action};
    }

    createStateNode(state:WorkflowState){
        let key = "state_"+ state.Id.toString();
        if(state.Id == 0){
            key = new Date().getMilliseconds().toString();
        }
        if(!state.Name){
            state.Name = "State";
        }
        return { category:"state",key: key, color: 'orange',text:state.Name,tag:state,contextMenuItems:[],portId:""  };
    }
    removeStateNode(){
        
    }
    createEndNode(){
        
        return { category:"End",key: "-2", color: 'red',text:"End",tag:null };
    }
}