"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const t = require("@babel/types");
const utils_1 = require("../utils/utils");
let actionName = '';
// let _pageVar;
let _pageName;
let _entitiesData;
let _dataBindingVars;
let varInfo;
const getVarExp = v => {
    let valueExp = t.nullLiteral();
    if (v.defaultValue) {
        switch (v.type) {
            case 'Text':
                valueExp = t.stringLiteral(v.defaultValue);
                break;
            case 'Integer':
                valueExp = t.numericLiteral(Number(v.defaultValue));
                break;
            case 'Boolean':
                valueExp = t.booleanLiteral(v.defaultValue !== 'false');
                break;
            case 'Array':
                valueExp = t.arrayExpression();
                break;
            case 'Object':
                valueExp = t.objectExpression([]);
                break;
            default:
                if (v.defaultValue === '{}') {
                    valueExp = t.objectExpression([]);
                }
                if (v.defaultValue === '[]') {
                    valueExp = t.arrayExpression();
                }
                break;
        }
    }
    return valueExp;
};
const getActionVarExp = value => {
    let varExp = t.nullLiteral();
    const varType = varInfo[value];
    const actValue = value;
    if (varType.indexOf('action-') !== -1) {
        varExp = (0, utils_1.objValueStr2AST)(actValue);
    }
    else if (varType === 'page-path') {
        varExp = (0, utils_1.objValueStr2AST)(`this.props.match.params.${actValue}`);
    }
    else if (varType === 'page-variable') {
        varExp = (0, utils_1.objValueStr2AST)(`this.state.${actValue}`);
    }
    else if (varType === 'page-parameter') {
        varExp = (0, utils_1.objValueStr2AST)(`this.props.match.params.${actValue}`);
    }
    else if (varType === 'graphql-response') {
        varExp = (0, utils_1.objValueStr2AST)(actValue);
    }
    else if (varType === 'commonSql-response') {
        if (actValue.indexOf('.Current') !== -1) {
            const varArr = actValue.split('.List.Current');
            varExp = (0, utils_1.objValueStr2AST)(`${varArr[0]}.list[0]${varArr[1]}`);
        }
        else {
            const varArr = actValue.split('.List');
            varExp = (0, utils_1.objValueStr2AST)(`${varArr[0]}.list`);
        }
    }
    else if (varType === 'forEach-item') {
        varExp = t.identifier('item');
    }
    else if (varType.indexOf('page-commonSql') !== -1) {
        if (actValue.indexOf('.Current') !== -1) {
            const varArr = actValue.split('.List.Current');
            varExp = (0, utils_1.objValueStr2AST)(`this.state.${varArr[0]}_current${varArr[1]}`);
        }
        else {
            const varArr = actValue.split('.List');
            varExp = (0, utils_1.objValueStr2AST)(`this.state.${varArr[0]}${varArr[1]}`);
        }
    }
    else if (varType.indexOf('widget-') !== -1) {
        const compType = varType.split('-')[1];
        const actComp = actValue.split('.')[0];
        let actProp = actValue.split('.')[1];
        let actSubComp;
        if (compType === 'form') {
            if (actProp !== 'value') {
                actSubComp = actValue.split('.')[1];
                actProp = actValue.split('.')[2];
                if (actProp === 'value') {
                    // 这个有问题，暂时还没想到解决方法
                    varExp = t.callExpression((0, utils_1.objValueStr2AST)(`this.${actComp}.current.getFieldValue`), [t.identifier(actSubComp)]);
                }
            }
            else {
                // 这个有问题，暂时还没想到解决方法
                varExp = t.callExpression((0, utils_1.objValueStr2AST)(`this.${actComp}.current.getFieldsValue`), []);
            }
        }
        else if (actProp === 'value') {
            varExp = (0, utils_1.objValueStr2AST)(`this.state.${_dataBindingVars[actComp]}`);
        }
    }
    else {
        varExp = (0, utils_1.objValueStr2AST)(actValue);
    }
    return varExp;
};
const getActualVar = (key, type) => {
    let varExp = key;
    if (type.indexOf('action-') !== -1) {
        varExp = key;
    }
    else if (type === 'page-function') {
        varExp = key;
    }
    else if (type === 'page-path') {
        varExp = `this.props.match.params.${key}`;
    }
    else if (type === 'page-variable') {
        varExp = `this.state.${key}`;
    }
    else if (type === 'page-parameter') {
        varExp = `this.props.match.params.${key}`;
    }
    else if (type === 'graphql-response') {
        varExp = key;
    }
    else if (type === 'commonSql-response') {
        if (key.indexOf('.Current') !== -1) {
            const varArr = key.split('.List.Current');
            varExp = `${varArr[0]}.list[0]${varArr[1]}`;
        }
        else {
            const varArr = key.split('.List');
            varExp = `${varArr[0]}.list`;
        }
    }
    else if (type === 'forEach-item') {
        varExp = 'item';
    }
    else if (type.indexOf('page-commonSql') !== -1) {
        if (key.indexOf('.Current') !== -1) {
            const varArr = key.split('.List.Current');
            varExp = `this.state.${varArr[0]}_current${varArr[1]}`;
        }
        else {
            const varArr = key.split('.List');
            varExp = `this.state.${varArr[0]}${varArr[1]}`;
        }
    }
    else if (type.indexOf('widget-form') === -1 && key.indexOf('.') !== -1) {
        if (key.split('.')[1] === 'value') {
            varExp = `this.state.${_dataBindingVars[key.split('.')[0]]}`;
        }
    }
    else {
        varExp = key;
    }
    return varExp;
};
// eslint-disable-next-line consistent-return
const getVarTypeExp = v => {
    const type = Object.prototype.toString.call(v);
    switch (type) {
        case '[object String]':
            return t.stringLiteral(v);
        case '[object Boolean]':
            return t.booleanLiteral(v);
        case '[object Number]':
            return t.numericLiteral(v);
        case '[object Object]':
            return t.objectExpression([]);
        case '[object Array]':
            return t.arrayExpression();
        default:
            break;
    }
};
exports.default = logicData => {
    const { path, json, pageVar, entitiesData, pageName, errorInfo, dataBindingVars, initCommonSqlQuery = false, remoteOptions = false, } = logicData;
    const blocks = [];
    const { async } = json;
    // eslint-disable-next-line prefer-destructuring
    varInfo = json.varInfo;
    // eslint-disable-next-line prefer-destructuring
    actionName = json.actionName;
    _pageVar = pageVar;
    _pageName = pageName;
    _entitiesData = entitiesData;
    _dataBindingVars = dataBindingVars;
    if (json.variables) {
        json.variables.forEach(v => {
            blocks.push(t.variableDeclaration('let', [
                t.variableDeclarator(t.identifier(v.name), v.defaultValue ? getVarExp(v) : null),
            ]));
        });
    }
    const exceptBlocks = [];
    let errorText = '';
    let exceptErrorText = '';
    if (json.states || json.exceptions) {
        if (json.states) {
            errorText = checkDslCorrect(json.states, 'normal', '');
        }
        if (json.exceptions && json.exceptions.states) {
            exceptErrorText = checkDslCorrect(json.exceptions.states, 'except', '');
        }
        if (errorText || exceptErrorText) {
            errorInfo.type = 'logicDSL-compile-error';
            errorInfo.message = `${errorInfo.message} \n UI Flows ===> ${_pageName} ===> ${actionName}中的逻辑流程图有以下错误：\n${errorText}${exceptErrorText}`;
            return;
        }
    }
    if (json.exceptions &&
        json.exceptions.states &&
        json.exceptions.states[json.exceptions.startAt]) {
        const newJson = json.exceptions;
        genClassMethods(newJson, newJson.states[newJson.startAt], exceptBlocks, newJson.startAt);
    }
    if (json.states && json.states[json.startAt]) {
        genClassMethods(json, json.states[json.startAt], blocks, json.startAt);
    }
    const params = [];
    if (json.parameter && json.parameter.in) {
        json.parameter.in.forEach(v => {
            params.push(t.identifier(v.name));
        });
    }
    if (initCommonSqlQuery && actionName === 'mounted') {
        blocks.unshift(t.expressionStatement(t.callExpression((0, utils_1.objValueStr2AST)('this.atStart'), [])));
    }
    if (remoteOptions && actionName === 'mounted') {
        blocks.unshift(t.expressionStatement(t.callExpression((0, utils_1.objValueStr2AST)('this.fetchRemoteOptions'), [])));
    }
    let newBlocks;
    if (json.exceptions) {
        newBlocks = [
            t.tryStatement(t.blockStatement(blocks), t.catchClause(t.identifier('error'), t.blockStatement(exceptBlocks))),
        ];
    }
    else {
        newBlocks = blocks;
    }
    switch (actionName) {
        case 'mounted':
            path.node.body.push(t.classMethod('method', t.identifier('componentDidMount'), [], t.blockStatement(newBlocks), false, false, false, async));
            break;
        case 'destroyed':
            path.node.body.push(t.classMethod('method', t.identifier('componentWillUnmount'), [], t.blockStatement(newBlocks), false, false, false, async));
            break;
        default:
            path.node.body.push(t.classProperty(t.identifier(actionName), t.arrowFunctionExpression(params, t.blockStatement(newBlocks), async)));
            break;
    }
};
function checkDslCorrect(states, type, space) {
    let errorText = '';
    if (type === 'normal') {
        if (!states.start) {
            errorText += `${space}[error]: 该流程图没有【开始】节点！\n`;
        }
        if (!states.end) {
            errorText += `${space}[error]: 该流程图没有【结束】节点！\n`;
        }
    }
    else if (!states.end ||
        Object.values(states).findIndex(v => v.type === 'exception') === -1) {
        errorText += `${space}[error]: 该流程图中的异常环节不是一个完整的流程（必须以异常节点开始end节点结束）！\n`;
    }
    Object.keys(states).forEach(v => {
        const node = states[v];
        const stateObj = node.resource;
        if (node.type !== 'end' && !node.next) {
            errorText += `${space}[error]: 该流程图在【${v}】节点处中断，请确保流程图的完整！\n`;
        }
        switch (node.type) {
            case 'message':
                if (!stateObj.type) {
                    errorText += `${space}[error]:【${v}】(Message节点):【类型】字段不能为空，请确认填写！ \n`;
                }
                if (!stateObj.message) {
                    errorText += `${space}[error]:【${v}】(Message节点):【内容】字段不能为空，请确认填写！ \n`;
                }
                break;
            case 'javascript':
                if (!stateObj.javascript) {
                    errorText += `${space}[error]:【${v}】(Javascript节点):【javascript】字段不能为空，请确认填写！ \n`;
                }
                break;
            case 'go':
                if (!stateObj.path) {
                    errorText += `${space}[error]:【${v}】(Destination节点):【行为】字段不能为空，请确认填写！ \n`;
                }
                break;
            case 'if':
                if (!stateObj.condition) {
                    errorText += `${space}[error]:【${v}】(If节点):【条件】字段不能为空，请确认填写！ \n`;
                }
                if (stateObj.choices.length !== 2) {
                    errorText += `${space}[error]:【${v}】(If节点): 请确保该节点有两条分支（true和false）！ \n`;
                }
                break;
            case 'validate':
                if (!stateObj.form) {
                    errorText += `${space}[error]:【${v}】(Validate节点):【表单名】字段不能为空，请确认填写！ \n`;
                }
                if (stateObj.choices.length !== 2) {
                    errorText += `${space}[error]:【${v}】(Validate节点): 请确保该节点有两条分支（校验成功和失败）！ \n`;
                }
                break;
            case 'switch':
                if (!stateObj.condition) {
                    errorText += `${space}[error]:【${v}】(Switch节点):【条件】字段不能为空，请确认填写！ \n`;
                }
                if (!stateObj.default) {
                    errorText += `${space}[error]:【${v}】(Switch节点): 请确保该节点有default分支！ \n`;
                }
                if (stateObj.choices.length === 0) {
                    errorText += `${space}[error]:【${v}】(Switch节点): 请确保该节点至少有一条case分支（不包含default分支）！ \n`;
                }
                break;
            case 'assign':
                if (stateObj.length === 0) {
                    errorText += `${space}[error]:【${v}】(Assign节点): 请至少填写一条赋值记录！ \n`;
                }
                break;
            case 'forEach':
                if (!stateObj.data) {
                    errorText += `${space}[error]:【${v}】(For Each节点):【数据】字段不能为空，请确认填写！ \n`;
                }
                if (!stateObj.children) {
                    errorText += `${space}[error]:【${v}】(For Each节点): 请确保该节点有子流程（循环体流程）！ \n`;
                }
                else if (stateObj.children.states) {
                    const subErrorText = checkDslCorrect(stateObj.children.states, 'normal', '    ');
                    if (subErrorText) {
                        errorText += `${space}[error]:【${v}】(For Each节点): 该节点的子流程图（循环体流程）有以下错误：\n${subErrorText}`;
                    }
                }
                break;
            case 'runServerAction':
                if (!stateObj.name) {
                    errorText += `${space}[error]:【${v}】(Run Server Action节点):【行为】字段不能为空，请确认填写！ \n`;
                }
                break;
            case 'runClientAction':
                if (!stateObj.name) {
                    errorText += `${space}[error]:【${v}】(Run Client Action节点):【行为】字段不能为空，请确认填写！ \n`;
                }
                break;
            default:
                break;
        }
    });
    return errorText;
}
function genClassMethods(data, node, blocks, name, endFlag = '') {
    let stateObj;
    if (node.type === 'end' || name === endFlag) {
        return;
    }
    if (node.type === 'start') {
        genClassMethods(data, data.states[node.next], blocks, node.next, endFlag);
    }
    if (node.type === 'javascript') {
        blocks.push(t.expressionStatement(t.binaryExpression('^', t.identifier(`#${actionName}`), t.identifier(`${name}#`))));
        genClassMethods(data, data.states[node.next], blocks, node.next, endFlag);
    }
    if (node.type === 'go') {
        stateObj = node.resource;
        let urlStatement;
        const urlParam = [];
        const path = stateObj.path.value;
        const newUrl = path.replace(/\{([\s\S]*?)\}/g, (match, key) => {
            urlParam.push(getActionVarExp(key));
            return '@';
        });
        if (newUrl.indexOf('@') !== -1) {
            const urlTemp = newUrl.split('@').map((v, i) => {
                if (i !== newUrl.split('@').length - 1) {
                    return t.templateElement({ raw: v }, false);
                }
                return t.templateElement({ raw: v }, true);
            });
            urlStatement = t.templateLiteral(urlTemp, urlParam);
        }
        else {
            urlStatement = t.stringLiteral(newUrl);
        }
        blocks.push(t.expressionStatement(t.callExpression((0, utils_1.objValueStr2AST)('Fishx.history.push'), [urlStatement])));
        genClassMethods(data, data.states[node.next], blocks, node.next, endFlag);
    }
    if (node.type === 'if' || node.type === 'validate') {
        stateObj = node.resource;
        let condition;
        if (stateObj.form) {
            blocks.push(t.variableDeclaration('let', [
                t.variableDeclarator(t.identifier('validRes')),
            ]));
            blocks.push(t.tryStatement(t.blockStatement([
                t.expressionStatement(t.awaitExpression(t.callExpression((0, utils_1.objValueStr2AST)(`this.${stateObj.form}.current.validateFields`), []))),
                t.expressionStatement(t.assignmentExpression('=', t.identifier('validRes'), t.booleanLiteral(true))),
            ]), t.catchClause(t.identifier('error'), t.blockStatement([
                t.expressionStatement(t.callExpression((0, utils_1.objValueStr2AST)('console.log'), [
                    t.identifier('error'),
                ])),
                t.expressionStatement(t.assignmentExpression('=', t.identifier('validRes'), t.booleanLiteral(false))),
            ]))));
            condition = 'validRes';
        }
        else {
            let newNodeValue = stateObj.condition.value;
            if (Object.keys(stateObj.condition.relation).length) {
                Object.keys(stateObj.condition.relation).forEach(key => {
                    const exp = getActualVar(key, stateObj.condition.relation[key]);
                    newNodeValue = (0, utils_1.newReplaceAll)(newNodeValue, key, exp);
                });
            }
            condition = newNodeValue;
        }
        const trueBlocks = [];
        const falseBlocks = [];
        const trueNode = stateObj.choices[0];
        const falseNode = stateObj.choices[1];
        const ifNext = node.next;
        if (ifNext !== trueNode.next) {
            genClassMethods(data, data.states[trueNode.next], trueBlocks, trueNode.next, ifNext);
        }
        if (ifNext !== falseNode.next) {
            genClassMethods(data, data.states[falseNode.next], falseBlocks, falseNode.next, ifNext);
        }
        if (ifNext === trueNode.next) {
            blocks.push(t.ifStatement(t.unaryExpression('!', t.identifier(`(${condition})`)), t.blockStatement(falseBlocks), null));
        }
        else if (ifNext === falseNode.next) {
            blocks.push(t.ifStatement(t.identifier(condition), t.blockStatement(trueBlocks), null));
        }
        else {
            blocks.push(t.ifStatement(t.identifier(condition), t.blockStatement(trueBlocks), t.blockStatement(falseBlocks)));
        }
        genClassMethods(data, data.states[ifNext], blocks, ifNext, endFlag);
    }
    if (node.type === 'switch') {
        stateObj = node.resource;
        const switchCase = [];
        const switchNext = node.next;
        for (let i = 0; i < stateObj.choices.length; i += 1) {
            const v = stateObj.choices[i];
            const caseBlocks = [];
            genClassMethods(data, data.states[v.next], caseBlocks, v.next, switchNext);
            caseBlocks.push(t.breakStatement());
            switchCase.push(t.switchCase(t.stringLiteral(v.result), caseBlocks));
        }
        const defaultBlocks = [];
        if (stateObj.default) {
            genClassMethods(data, data.states[stateObj.default.next], defaultBlocks, stateObj.default.next, switchNext);
        }
        defaultBlocks.push(t.breakStatement());
        switchCase.push(t.switchCase(null, defaultBlocks));
        let newNodeValue = stateObj.condition.value;
        if (Object.keys(stateObj.condition.relation).length) {
            Object.keys(stateObj.condition.relation).forEach(key => {
                const exp = getActualVar(key, stateObj.condition.relation[key]);
                newNodeValue = (0, utils_1.newReplaceAll)(newNodeValue, key, exp);
            });
        }
        blocks.push(t.switchStatement(t.identifier(newNodeValue), switchCase));
        genClassMethods(data, data.states[switchNext], blocks, switchNext, endFlag);
    }
    if (node.type === 'message') {
        stateObj = node.resource;
        let msgExp;
        if (Object.keys(stateObj.message.relation).length) {
            msgExp = getActionVarExp(stateObj.message.value);
        }
        else {
            msgExp = getVarTypeExp(stateObj.message.value);
        }
        blocks.push(t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('message'), t.identifier(stateObj.type)), [msgExp])));
        genClassMethods(data, data.states[node.next], blocks, node.next, endFlag);
    }
    if (node.type === 'assign') {
        stateObj = node.resource;
        stateObj.forEach(v => {
            let valueExp;
            const nodeValue = v.value.value;
            const nodeVar = v.variable.value;
            let newNodeValue = nodeValue;
            if (Object.keys(v.value.relation).length) {
                Object.keys(v.value.relation).forEach(key => {
                    const exp = getActualVar(key, v.value.relation[key]);
                    newNodeValue = (0, utils_1.newReplaceAll)(newNodeValue, key, exp);
                });
                valueExp = t.identifier(newNodeValue);
            }
            else {
                valueExp = getVarTypeExp(nodeValue);
            }
            if (varInfo[nodeVar] === 'page-variable') {
                const stateExp = [
                    t.objectExpression([(0, utils_1.objPropStr2AST)(nodeVar, valueExp)]),
                ];
                blocks.push(t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('setState')), stateExp)));
            }
            else if (varInfo[nodeVar] === 'page-object') {
                let pageName;
                let pageProperty;
                let isComputed = false;
                if (nodeVar.indexOf('[') !== -1) {
                    isComputed = true;
                    pageName = nodeVar.split('[')[0];
                    pageProperty = nodeVar.split('[')[1].split(']')[0];
                }
                else {
                    pageName = nodeVar.split('.')[0];
                    pageProperty = nodeVar.split('.')[1];
                }
                blocks.push(t.expressionStatement(t.callExpression((0, utils_1.objValueStr2AST)('this.setState'), [
                    t.arrowFunctionExpression([t.identifier('prev')], t.blockStatement([
                        t.returnStatement(t.objectExpression([
                            t.objectProperty(t.identifier(pageName), t.objectExpression([
                                t.spreadElement((0, utils_1.objValueStr2AST)(`prev.${pageName}`)),
                                t.objectProperty(t.identifier(pageProperty), valueExp, isComputed),
                            ])),
                        ])),
                    ])),
                ])));
            }
            else if (varInfo[nodeVar] &&
                varInfo[nodeVar].indexOf('page-commonSql') !== -1) {
                const sqlname = nodeVar.split('.')[0];
                let stateExp;
                if (nodeVar.split('.').length === 2) {
                    stateExp = t.objectProperty(t.identifier(sqlname), valueExp);
                }
                else if (nodeVar.split('.').length === 3) {
                    stateExp = t.objectProperty(t.identifier(`${sqlname}_current`), valueExp);
                }
                else {
                    stateExp = (0, utils_1.objPropStr2AST)(nodeVar, valueExp);
                }
                blocks.push(t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('setState')), [t.objectExpression([stateExp])])));
            }
            else {
                blocks.push(t.expressionStatement(t.assignmentExpression('=', t.identifier(nodeVar), valueExp)));
            }
        });
        genClassMethods(data, data.states[node.next], blocks, node.next, endFlag);
    }
    if (node.type === 'forEach') {
        stateObj = node.resource;
        const subFlowData = stateObj.children;
        const forBlocks = [];
        const mapExp = getActionVarExp(stateObj.data.value);
        genClassMethods(subFlowData, subFlowData.states[subFlowData.startAt], forBlocks, subFlowData.startAt);
        forBlocks.unshift(t.variableDeclaration('const', [
            t.variableDeclarator(t.identifier('item'), t.memberExpression(mapExp, t.identifier('index'), true)),
        ]));
        blocks.push(t.forStatement(t.variableDeclaration('let', [
            t.variableDeclarator(t.identifier('index'), t.numericLiteral(0)),
        ]), t.binaryExpression('<', t.identifier('index'), t.memberExpression(mapExp, t.identifier('length'))), t.updateExpression('++', t.identifier('index'), false), t.blockStatement(forBlocks)));
        genClassMethods(data, data.states[node.next], blocks, node.next, endFlag);
    }
    if (node.type === 'runClientAction') {
        stateObj = node.resource;
        const paramExp = [];
        if (stateObj.in) {
            Object.values(stateObj.in).forEach(v => {
                paramExp.push(getActionVarExp(v.value));
            });
        }
        blocks.push(t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier(stateObj.name)), paramExp)));
        genClassMethods(data, data.states[node.next], blocks, node.next, endFlag);
    }
    if (node.type === 'runServerAction') {
        stateObj = node.resource;
        let fetchExp;
        let graphqlType;
        let entityName;
        let commonSqlName;
        if (stateObj.type === 'graphql') {
            const paramObj = stateObj.param || {};
            entityName = stateObj.name
                .replace(/^Delete|^Create(OrUpdate)?|^Update|^Get/, '')
                .replace(/ByFilter$/, '');
            graphqlType =
                stateObj.name === 'GetBySql'
                    ? 'CommonSql'
                    : stateObj.name.replace(entityName, '');
            commonSqlName =
                graphqlType === 'CommonSql' ? paramObj.qson.split('/')[3] : '';
            const paramExp = graphqlType === 'CommonSql'
                ? [
                    t.objectProperty(t.identifier('params'), t.callExpression(t.memberExpression(t.identifier('JSON'), t.identifier('stringify')), [t.identifier(`${commonSqlName}_params`)])),
                ]
                : [];
            let paramStr = '';
            let paramTypeStr = '';
            const paramArr = Object.keys(paramObj);
            const variablesExp = [];
            const variables = stateObj.variables || [];
            variables.forEach(v => {
                const vartype = v.varType;
                const varArr = v.expression
                    .replace(/["|'](.*?)["|']/g, '')
                    .replace(/true/g, '')
                    .replace(/false/g, '')
                    .match(/[a-zA-Z]([a-zA-Z]|[0-9]|_|\.)*/g) || [];
                const varName = varArr[0];
                if (varName) {
                    let replacedStr = '';
                    if (vartype === 'action') {
                        replacedStr = varName;
                    }
                    else if (vartype === 'page') {
                        replacedStr = `this.state.${varName}`;
                    }
                    else {
                        replacedStr = `this.props.match.params.${varName}`;
                    }
                    variablesExp.push(t.objectProperty(t.identifier(varName), t.identifier((0, utils_1.newReplaceAll)(v.expression, varName, replacedStr))));
                }
            });
            if (graphqlType === 'CommonSql') {
                blocks.push(t.variableDeclaration('const', [
                    t.variableDeclarator(t.identifier(`${commonSqlName}_params`), t.objectExpression(variablesExp)),
                ]));
            }
            paramArr.forEach((v, i) => {
                let resExp;
                if (graphqlType === 'CommonSql') {
                    if (v === 'qson') {
                        resExp = t.stringLiteral(paramObj[v]);
                    }
                    else {
                        resExp = (0, utils_1.objValueStr2AST)(`this.state.${paramObj[v]}`);
                    }
                }
                else if (v === 'toCreate' || v === 'toUpdate') {
                    if (paramObj[v].value.indexOf('.List') !== -1) {
                        if (paramObj[v].value.indexOf('.Current') !== -1) {
                            const varArr = paramObj[v].value.split('.List.Current');
                            resExp = (0, utils_1.objValueStr2AST)(`this.state.${varArr[0]}_current.${entityName}`);
                        }
                        else {
                            const varArr = paramObj[v].value.split('.List');
                            resExp = (0, utils_1.objValueStr2AST)(`this.state.${varArr[0]}.${entityName}`);
                        }
                    }
                    else {
                        resExp = getActionVarExp(paramObj[v].value);
                    }
                }
                else if (v === '_order_by') {
                    resExp = t.objectExpression([
                        t.objectProperty(t.identifier(paramObj[v].value), t.stringLiteral('asc')),
                    ]);
                }
                else {
                    resExp = getActionVarExp(paramObj[v].value);
                }
                paramExp.push(t.objectProperty(t.identifier(v), resExp));
                if (v === '_where') {
                    paramTypeStr +=
                        i === paramArr.length - 1
                            ? `$${v} : ${entityName}BoolExp`
                            : `$${v} : ${entityName}BoolExp\n`;
                    paramStr +=
                        i === paramArr.length - 1 ? `${v} : $${v}` : `${v} : $${v}\n`;
                }
                if (v === '_limit') {
                    paramTypeStr +=
                        i === paramArr.length - 1 ? `$${v} : Integer` : `$${v} : Integer\n`;
                    paramStr +=
                        i === paramArr.length - 1 ? `${v} : $${v}` : `${v} : $${v}\n`;
                }
                if (v === '_offset') {
                    paramTypeStr +=
                        i === paramArr.length - 1 ? `$${v} : Integer` : `$${v} : Integer\n`;
                    paramStr +=
                        i === paramArr.length - 1 ? `${v} : $${v}` : `${v} : $${v}\n`;
                }
                if (v === '_order_by') {
                    paramTypeStr +=
                        i === paramArr.length - 1
                            ? `$${v} : [${entityName}OrderBy!]`
                            : `$${v} : [${entityName}OrderBy!]\n`;
                    paramStr +=
                        i === paramArr.length - 1 ? `${v} : $${v}` : `${v} : $${v}\n`;
                }
                if (v === '_group_by') {
                    paramTypeStr +=
                        i === paramArr.length - 1
                            ? `$${v} : [${entityName}PrimitiveField!]`
                            : `$${v} : [${entityName}PrimitiveField!]\n`;
                    paramStr +=
                        i === paramArr.length - 1 ? `${v} : $${v}` : `${v} : $${v}\n`;
                }
            });
            const entityData = _entitiesData.find(v => v.name === entityName);
            let entityPropStr = '';
            const declArr = [];
            const parArr = [];
            if (entityData) {
                entityData.children.forEach((v, i) => {
                    if (v.iconType === 'primaryKey') {
                        declArr.push(`$${v.name}: Long!`);
                        parArr.push(`${v.name}: $${v.name}`);
                    }
                    entityPropStr +=
                        i === entityData.children.length - 1 ? v.name : `${v.name}\n`;
                });
            }
            let graphqlStr;
            switch (graphqlType) {
                case 'Get':
                    graphqlStr = `
            query (${declArr.join(', ')}) {
              ${stateObj.name}(${parArr.join(', ')}) {
                ${entityPropStr}
              }
            }
          `;
                    break;
                case 'Delete':
                    graphqlStr = `
            mutation (${declArr.join(', ')}) {
              ${stateObj.name}(${parArr.join(', ')})
            }
          `;
                    break;
                // 这块还需要修改下，过滤条件参数还未确定
                case 'GetByFilter':
                    graphqlStr = paramStr
                        ? `
            query (
              ${paramTypeStr}
            ) {
              ${stateObj.name}(
                ${paramStr}
              ) {
                ${entityPropStr}
              }
            }
          `
                        : `
            query {
              ${stateObj.name} {
                ${entityPropStr}
              }
            }
          `;
                    break;
                case 'Create':
                    graphqlStr = `
            mutation ($toCreate: [${entityName}Input!]) {
              ${stateObj.name}(toCreate: $toCreate) {
                ${entityPropStr}
              }
            }
          `;
                    break;
                case 'CreateOrUpdate':
                    graphqlStr = `
            mutation ($toCreate: [${entityName}Input!]) {
              ${stateObj.name}(toCreate: $toCreate) {
                ${entityPropStr}
              }
            }
          `;
                    break;
                case 'Update':
                    graphqlStr = `
            mutation ($toUpdate: ${entityName}Input) {
              ${stateObj.name}(toUpdate: $toUpdate)
            }
          `;
                    break;
                case 'CommonSql':
                    graphqlStr = `
            query ($qson: Text, $params: LongText) {
              ${stateObj.name}(qson: $qson, params: $params)
            }
          `;
                    break;
                default:
                    break;
            }
            fetchExp = t.awaitExpression(t.callExpression(t.memberExpression(t.identifier('client'), t.identifier('query')), [
                t.taggedTemplateExpression(t.identifier('gql'), t.templateLiteral([t.templateElement({ raw: graphqlStr }, true)], [])),
                t.objectExpression(paramExp),
            ]));
        }
        else {
            const optionStatement = [
                t.objectProperty(t.identifier('method'), t.stringLiteral(stateObj.method)),
            ];
            if (stateObj.body) {
                optionStatement.push(t.objectProperty(t.identifier('data'), getActionVarExp(stateObj.body.value)));
            }
            let urlStatement;
            let url = stateObj.path;
            if (stateObj.query) {
                const queryParam = [];
                // eslint-disable-next-line no-restricted-syntax
                for (const key in stateObj.query) {
                    if (stateObj.query.hasOwnProperty(key)) {
                        const element = stateObj.query[key].value;
                        queryParam.push(`${key}={${element}}`);
                    }
                }
                url = `${url}?${queryParam.join('&')}`;
            }
            if (stateObj.param) {
                // eslint-disable-next-line no-restricted-syntax
                for (const key in stateObj.param) {
                    if (stateObj.param.hasOwnProperty(key)) {
                        const element = stateObj.param[key].value;
                        url = url.replace(key, element);
                    }
                }
            }
            const urlParam = [];
            const newUrl = url.replace(/\{([\s\S]*?)\}/g, (match, key) => {
                urlParam.push(getActionVarExp(key));
                return '@';
            });
            if (newUrl.indexOf('@') !== -1) {
                const urlTemp = newUrl.split('@').map((v, i) => {
                    if (i !== newUrl.split('@').length - 1) {
                        return t.templateElement({ raw: v }, false);
                    }
                    return t.templateElement({ raw: v }, true);
                });
                urlStatement = t.templateLiteral(urlTemp, urlParam);
            }
            else {
                urlStatement = t.stringLiteral(newUrl);
            }
            fetchExp = t.awaitExpression(t.callExpression(t.identifier('fetch'), [
                urlStatement,
                t.objectExpression(optionStatement),
            ]));
        }
        if (stateObj.response) {
            if (stateObj.type === 'graphql') {
                blocks.push(t.variableDeclaration('let', [
                    t.variableDeclarator(t.objectPattern([
                        t.objectProperty(t.identifier(stateObj.name), graphqlType === 'CommonSql'
                            ? t.identifier(commonSqlName)
                            : t.identifier(stateObj.name)),
                    ]), fetchExp),
                ]));
            }
            else {
                blocks.push(t.variableDeclaration('const', [
                    t.variableDeclarator(t.identifier(stateObj.name), fetchExp),
                ]));
            }
            if (stateObj.response === 'true' && graphqlType === 'CommonSql') {
                const _res = t.callExpression(t.memberExpression(t.identifier('JSON'), t.identifier('parse')), [t.identifier(commonSqlName)]);
                blocks.push(t.expressionStatement(t.assignmentExpression('=', t.identifier(commonSqlName), _res)));
                blocks.push(t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('setState')), [
                    t.objectExpression([
                        t.objectProperty(t.identifier(commonSqlName), t.memberExpression(t.identifier(commonSqlName), t.identifier('list'))),
                        t.objectProperty(t.identifier(`${commonSqlName}_current`), t.memberExpression(t.memberExpression(t.identifier(commonSqlName), t.identifier('list')), t.numericLiteral(0), true)),
                    ]),
                ])));
            }
            // let _res;
            // if (stateObj['type'] === 'graphql') {
            //   if (graphqlType === 'CommonSql') {
            //     _res = t.memberExpression(
            //       t.callExpression(
            //         t.memberExpression(t.identifier('JSON'), t.identifier('parse')),
            //         [t.identifier(`${commonSqlName}_res`)]
            //       ),
            //       t.identifier('list')
            //     )
            //   } else {
            //     _res = t.identifier(`${stateObj['name']}_res`);
            //   }
            // } else {
            //   _res = t.identifier('_res');
            // }
            // const nodeRes = stateObj["response"] === "true" ? "true" : stateObj["response"]["value"];
            // if (varInfo[nodeRes] === 'page-variable') {
            //   const stateExp = [t.objectExpression([t.objectProperty(t.identifier(nodeRes), _res)])];
            //   blocks.push(
            //     t.expressionStatement(
            //       t.callExpression(
            //         t.memberExpression(t.thisExpression(), t.identifier('setState')),
            //         stateExp
            //       )
            //     )
            //   );
            // } else if (varInfo[nodeRes] && varInfo[nodeRes].indexOf('action-') !== -1) {
            //   blocks.push(
            //     t.expressionStatement(
            //       t.assignmentExpression(
            //         "=",
            //         t.identifier(nodeRes),
            //         _res
            //       )
            //     )
            //   );
            // } else if (varInfo[nodeRes] && varInfo[nodeRes].indexOf('page-commonSql') !== -1) {
            //   const sqlname = nodeRes.split('.')[0];
            //   if (_pageVar.findIndex(v => v.name === sqlname) === -1) {
            //     _pageVar.push({name: sqlname, type: 'Array'});
            //     _pageVar.push({name: `${sqlname}_current`, type: 'Object'});
            //   }
            //   blocks.push(
            //     t.expressionStatement(
            //       t.callExpression(
            //         t.memberExpression(t.thisExpression(), t.identifier('setState')),
            //         [t.objectExpression([
            //           t.objectProperty(
            //             t.identifier(sqlname),
            //             _res
            //           ),
            //           t.objectProperty(
            //             t.identifier(`${sqlname}_current`),
            //             t.memberExpression(_res, t.numericLiteral(0), true)
            //           )
            //         ])]
            //       )
            //     )
            //   );
            // }
        }
        else {
            blocks.push(t.expressionStatement(fetchExp));
        }
        genClassMethods(data, data.states[node.next], blocks, node.next, endFlag);
    }
    if (node.type === 'exception') {
        stateObj = node.resource;
        if (stateObj.logError) {
            blocks.push(t.expressionStatement(t.callExpression((0, utils_1.objValueStr2AST)('console.log'), [
                t.identifier('error'),
            ])));
        }
        genClassMethods(data, data.states[node.next], blocks, node.next, endFlag);
    }
}
