import { config, utils, Entity, EntityProperty, View, LEVEL_ENUM } from '../..';
import {
    NameGroup, genUniqueQueryNameGroup, getFirstDisplayedProperty,
    genGenericTypeSchema, genVariable, genInterParam, genQueryInterface,
    genQueryStructure, genCallInterfaceFromTempInterface,
} from '.';

export function genSelectTemplate(property: EntityProperty, nameGroup: NameGroup) {
    return `<u-select clearable placeholder="请选择" ref="select" :data-source="${nameGroup.load}" data-schema="${nameGroup.structure}"
    text-field="${nameGroup.lowerEntity}.${property.name}"
    value-field="${nameGroup.lowerEntity}.id" pageable remote-paging>
</u-select>`;
}

export function genH5SelectTemplate(property: EntityProperty, nameGroup: NameGroup) {
    return `<van-cascader title="请选择" placeholder="请选择" ref="select" :data-source="${nameGroup.load}" data-schema="${nameGroup.structure}"
    text-field="${nameGroup.lowerEntity}.${property.name}"
    value-field="${nameGroup.lowerEntity}.id" pageable remote-paging>
</van-cascader>`;
}

export function genLoadSelectLogic(entity: Entity, nameGroup: NameGroup,
    newStructures: Array<any>, newInterfaces: Array<any>) {
    const paramsSchema = {
        $ref: '#/systemTypes/DataSourceParams',
    };

    // Select 和 table 不一样，直接在内部产生了
    const newStructure = genQueryStructure([entity], nameGroup);
    const newInterface = genQueryInterface([entity], nameGroup, false, false);
    newStructures.push(newStructure);
    newInterfaces.push(newInterface);

    const resultSchema = genGenericTypeSchema('PageOf', { T: { $ref: nameGroup.structure } });

    return {
        level: 'logic',
        name: nameGroup.load,
        params: [
            {
                level: 'param',
                type: 'Identifier',
                name: 'params',
                schema: paramsSchema,
            },
        ],
        returns: [
            genVariable('result', resultSchema, LEVEL_ENUM.return),
        ],
        variables: [] as Array<any>,
        body: [
            {
                level: 'logicNode',
                type: 'Start',
                label: '开始',
            },
            {
                level: 'logicNode',
                type: 'AssignmentExpression',
                label: '赋值',
                operator: '=',
                left: {
                    level: 'expressionNode',
                    type: 'Identifier',
                    name: 'result',
                },
                right: genCallInterfaceFromTempInterface(newInterface, [
                    genInterParam(
                        `${newInterface.name}.${newInterface.logic.params[0].name}`,
                        'params.page',
                        [undefined, undefined],
                    ),
                    genInterParam(
                        `${newInterface.name}.${newInterface.logic.params[1].name}`,
                        'params.size',
                        [undefined, undefined],
                    ),
                ]),
            },
            {
                level: 'logicNode',
                type: 'End',
                label: '结束',
            },
        ],
    };
}

/**
 * 生成实体选择框区块
 */
export function genSelectBlock(entity: Entity, view: View) {
    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 = genUniqueQueryNameGroup(existingNameSets, view.name, 'select', false);
    nameGroup.lowerEntity = utils.firstLowerCase(entity.name);

    const displayedProperty = getFirstDisplayedProperty(entity, 'inDetail');

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

    return `<template>
    ${config.scope === 'h5' ? genH5SelectTemplate(displayedProperty, nameGroup) : genSelectTemplate(displayedProperty, nameGroup)}
</template>

<definition>
{
"logics": [
    ${JSON.stringify(genLoadSelectLogic(entity, nameGroup, newStructures, newInterfaces))}
],
"interfaces": ${JSON.stringify(newInterfaces)},
"structures": ${JSON.stringify(newStructures)}
}
</definition>
`;
}

export default genSelectBlock;
