import { Resolver } from '../Entity';
import { config, dataTypesMap, vertexsMap, Entity, EntityProperty, View, Enum, LEVEL_ENUM, utils } from '../..';
import { NameGroup, genUniqueQueryNameGroup, filterProperty, getParamFromResolver, getFirstDisplayedProperty, genEnumSelectBlock, genCallComponentLogic, genCallInterface, genLoadSelectLogic } from '.';

export function genCreateFormTemplate(entity: Entity, nameGroup: NameGroup, selectNameGroupMap: Map<string, NameGroup>) {
    const propertyList = entity.propertyList
        .filter(filterProperty('inForm'));

    return `<u-form ref="form1">
    ${propertyList.map((property) => {
        const label = property.label || property.name;
        const required = !!property.required;
        const rules = [];
        if (property.rules && property.rules.length) {
            property.rules.forEach((rule) => rules.push(rule));
        }
        if (required)
            rules.push('required');
        const rulesStr = rules.join(' | ');

        let formItem = `            <u-form-item label="${label}"${required ? ' required' : ''}${rulesStr.length ? ` rules="${rulesStr}"` : ''}>\n`;

        if (property.$relationEntity) { // 有外键关联
            const relationEntity = vertexsMap.get(property.$relationEntity) as Entity;
            if (relationEntity) {
                const relationProperty = vertexsMap.get(property.$relationProperty) as EntityProperty;
                const displayedProperty = getFirstDisplayedProperty(relationEntity, 'inForm');
                if (displayedProperty) {
                    const lowerEntityName = utils.firstLowerCase(relationEntity.name);
                    formItem += `
                        <u-select clearable placeholder="请选择${label}" :data-source="${selectNameGroupMap.get(relationEntity.id).load}"
                            text-field="${lowerEntityName}.${displayedProperty.name}" value-field="${lowerEntityName}.${relationProperty.name}" pageable remote-paging v-model="${nameGroup.model}.${property.name}">
                        </u-select>
                    `;
                } else
                    return '';
            } else
                return '';
        } else if (property.typeKey === '#/basicTypes/Boolean') {
            formItem += `<u-checkbox v-model="${nameGroup.model}.${property.name}"></u-checkbox>`;
        } else if (property.typeKey === '#/basicTypes/Integer' || property.typeKey === '#/basicTypes/Long') {
            formItem += `<u-number-input v-model="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-number-input>`;
        } else if (property.typeKey === '#/basicTypes/Decimal') {
            formItem += `<u-number-input v-model="${nameGroup.model}.${property.name}" :precision="0" :step="0" placeholder="请输入${label}"></u-number-input>`;
        } else if (property.typeKey === '#/basicTypes/Text') {
            formItem += `<u-textarea v-model="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-textarea>`;
        } else if (property.typeKey === '#/basicTypes/Date') {
            formItem += `<u-date-picker clearable :date.sync="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-date-picker>`;
        } else if (property.typeKey === '#/basicTypes/Time') {
            formItem += `<u-time-picker :time.sync="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-time-picker>`;
        } else if (property.typeKey === '#/basicTypes/DateTime') {
            formItem += `<u-date-time-picker clearable :date.sync="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-date-time-picker>`;
        } else if (dataTypesMap[property.typeKey].type === 'enum') {
            formItem += genEnumSelectBlock(dataTypesMap[property.typeKey] as Enum, `${nameGroup.model}.${property.name}`, '', `请选择${label}`);
        } else {
            formItem += `<u-input v-model="${nameGroup.model}.${property.name}" placeholder="请输入${label}"></u-input>`;
        }

        formItem += `            </u-form-item>\n`;
        return formItem;
    }).join('')}
    <u-form-item>
        <u-button color="primary" @click="${nameGroup.submit}()">立即创建</u-button>
    </u-form-item>
</u-form>`;
}

export function genH5CreateFormTemplate(entity: Entity, nameGroup: NameGroup, selectNameGroupMap: Map<string, NameGroup>) {
    const propertyList = entity.propertyList
        .filter(filterProperty('inForm'));

    return `<van-form ref="form1">
    ${propertyList.map((property) => {
        const label = property.label || property.name;
        const required = !!property.required;
        const rules = [];
        if (property.rules && property.rules.length) {
            property.rules.forEach((rule) => rules.push(rule));
        }
        if (required)
            rules.push('required');
        const rulesStr = rules.join(' | ');

        let formItem = `            <van-field drole="other" label="${property.label || property.name}"${required ? ' required' : ''}${rulesStr.length ? ` rules="${rulesStr}"` : ''}>\n`;

        if (property.$relationEntity) { // 有外键关联
            const relationEntity = vertexsMap.get(property.$relationEntity) as Entity;
            if (relationEntity) {
                const relationProperty = vertexsMap.get(property.$relationProperty) as EntityProperty;
                const displayedProperty = getFirstDisplayedProperty(relationEntity, 'inForm');
                if (displayedProperty) {
                    const lowerEntityName = utils.firstLowerCase(relationEntity.name);
                    formItem += `
                        <template #input><van-cascader title="请选择${label}" placeholder="请选择${label}"
                            v-model="${nameGroup.model}.${property.name}" :data-source="${selectNameGroupMap.get(relationEntity.id).load}"
                            text-field="${lowerEntityName}.${displayedProperty.name}" value-field="${lowerEntityName}.${relationProperty.name}"
                            pageable remote-paging></van-cascader></template>
                    `;
                } else
                    return '';
            } else
                return '';
        } else if (property.typeKey === '#/basicTypes/Boolean') {
            formItem += `<template #input><van-switch v-model="${nameGroup.model}.${property.name}"></van-switch></template>`;
        } else if (property.typeKey === '#/basicTypes/Integer' || property.typeKey === '#/basicTypes/Long') {
            formItem += `<template #input><van-stepper v-model="${nameGroup.model}.${property.name}" placeholder="请输入${property.label || property.name}"></van-stepper></template>`;
        } else if (property.typeKey === '#/basicTypes/Decimal') {
            formItem += `<template #input><van-stepper v-model="${nameGroup.model}.${property.name}" placeholder="请输入${property.label || property.name}"></van-stepper></template>`;
        } else if (property.typeKey === '#/basicTypes/Text') {
            formItem = formItem.replace(/other/g, '');
            formItem += `<van-input v-model="${nameGroup.model}.${property.name}" placeholder="请输入${property.label || property.name}"></van-input>`;
        } else if (property.typeKey === '#/basicTypes/Date') {
            formItem += `<template #input><van-calendar v-model="${nameGroup.model}.${property.name}" title="请输入${property.label || property.name}"></van-calendar></template>`;
        } else if (property.typeKey === '#/basicTypes/Time') {
            formItem += `<template #input><van-datetime-picker type="time" v-model="${nameGroup.model}.${property.name}" title="请输入${property.label || property.name}"></van-datetime-picker></template>`;
        } else if (property.typeKey === '#/basicTypes/DateTime') {
            formItem += `<template #input><van-datetime-picker type="datetime" v-model="${nameGroup.model}.${property.name}" title="请输入${property.label || property.name}"></van-datetime-picker></template>`;
        } else if (dataTypesMap[property.typeKey].type === 'enum') {
            formItem += '<template #input>' + genEnumSelectBlock(dataTypesMap[property.typeKey] as Enum, `${nameGroup.model}.${property.name}`, '', `请选择${property.label || property.name}`) + '</template>';
        } else {
            formItem = formItem.replace(/other/g, '');
            formItem += `<van-input v-model="${nameGroup.model}.${property.name}" placeholder="请输入${property.label || property.name}"></van-input>`;
        }

        formItem += `            </van-field>\n`;

        formItem = formItem.replace(/>\n<van-input|<\/van-input>/g, '');
        return formItem;
    }).join('')}
    <div>
        <van-button round block="blockb" type="info" @click="${nameGroup.submit}()" text="立即创建"></van-button>
    </div>
</van-form>`;
}

function genSubmitLogic(resolver: Resolver, nameGroup: NameGroup) {
    const bodyParam = getParamFromResolver(resolver, 'body');

    return {
        level: 'logic',
        name: nameGroup.submit,
        params: [] as any,
        returns: [] as any,
        variables: [
            {
                level: 'variable',
                type: 'Identifier',
                name: 'validateResult',
                description: '',
                schema: {
                    $ref: '#/systemTypes/ValidateEvent',
                },
                isLeaf: true,
            },
        ],
        body: [
            {
                level: 'logicNode',
                type: 'Start',
                label: '开始',
            },
            {
                level: 'logicNode',
                type: 'AssignmentExpression',
                label: '赋值',
                operator: '=',
                left: {
                    level: 'expressionNode',
                    type: 'Identifier',
                    name: 'validateResult',
                },
                right: genCallComponentLogic('form1', 'validate'),
            },
            {
                level: 'logicNode',
                type: 'IfStatement',
                label: '条件分支',
                test: {
                    level: 'expressionNode',
                    type: 'MemberExpression',
                    name: 'name',
                    hide: false,
                    object: {
                        level: 'expressionNode',
                        type: 'Identifier',
                        name: 'validateResult',
                    },
                    property: {
                        level: 'expressionNode',
                        type: 'Identifier',
                        name: 'valid',
                    },
                },
                consequent: [
                    genCallInterface(resolver.interface, [
                        {
                            parentAttr: 'params',
                            level: LEVEL_ENUM.param,
                            type: 'CallInterParam',
                            name: '',
                            callInterParam: `#/${bodyParam.id}`,
                            callInterParamValue: {
                                parentAttr: 'callInterParamValue',
                                level: 'expressionNode',
                                type: 'Identifier',
                                name: nameGroup.model,
                            },
                        },
                    ]),
                    {
                        level: 'logicNode',
                        parentAttr: 'consequent',
                        label: '弹出消息',
                        folded: false,
                        type: 'CallMessageShow',
                        arguments: [
                            {
                                level: 'expressionNode',
                                parentAttr: 'arguments',
                                label: '原子项',
                                folded: false,
                                type: 'StringLiteral',
                                value: '创建成功！',
                            },
                        ],
                    },
                ],
                alternate: [] as any,
            },
            {
                level: 'logicNode',
                type: 'End',
                label: '结束',
            }],
    };
}

/**
 * 生成创建页区块
 * @param resolver 实体创建 Action
 */
export function genCreateBlock(entity: Entity, view: View) {
    const resolver = entity.resolvers.find((item) => item.name.startsWith('create'));

    const modelSchema = {
        $ref: entity.schemaRef,
    };

    const existingNameSets = {
        viewLogic: new Set(view.$def.logics.map((logic) => logic.name)),
        interface: new Set(entity.dataNode.service.interfaces.map((itface) => itface.name)),
        structure: new Set(entity.dataNode.structures.map((structure) => structure.name)),
    };
    const nameGroup: NameGroup = {
        model: utils.firstLowerCase(entity.name),
    };
    nameGroup.submit = utils.unique('submit', existingNameSets.viewLogic);

    // 收集所有和本实体关联的实体
    const allEntities = [entity];
    entity.propertyList.forEach((property) => {
        if (property.$relationEntity) { // 有外键关联
            const relationEntity = vertexsMap.get(property.$relationEntity) as Entity;
            if (relationEntity) {
                const displayedProperty = getFirstDisplayedProperty(relationEntity);
                if (displayedProperty)
                    allEntities.push(relationEntity);
            }
        }
    });

    const newStructures: Array<any> = [];
    const newInterfaces: Array<any> = [];

    const selectNameGroupMap: Map<string, NameGroup> = new Map();
    const loadSelectLogics = allEntities.slice(1).map((entity) => {
        const selectNameGroup = genUniqueQueryNameGroup(existingNameSets, view.name, 'select', false, entity.name);
        selectNameGroupMap.set(entity.id, selectNameGroup);
        return genLoadSelectLogic(entity, selectNameGroup, newStructures, newInterfaces);
    });

    return `<template>
    ${config.scope === 'h5' ? genH5CreateFormTemplate(entity, nameGroup, selectNameGroupMap) : genCreateFormTemplate(entity, nameGroup, selectNameGroupMap)}
</template>

<definition>
{
    "variables": [{
        "level": "variable",
        "type": "Identifier",
        "name": "${nameGroup.model}",
        "schema": ${JSON.stringify(modelSchema)}
    }],
    "logics": [
        ${JSON.stringify(genSubmitLogic(resolver, nameGroup))}
        ${loadSelectLogics.map((logic) => ',' + JSON.stringify(logic)).join('\n')}
    ],
    "interfaces": ${JSON.stringify(newInterfaces)},
    "structures": ${JSON.stringify(newStructures)}
}
</definition>
`;
}

export default genCreateBlock;

