import {
    App, MicroService, Interface, Enum,
    dataTypesMap, vertexsMap, Process,
} from '..';
import webFileService from '../../service/webFile';
import { saveLastModified } from './hotReload';

export function dataTypesToJson() {
    return dataTypesMap;
}

export function enumsToJson(app: App) {
    const enums = app.firstMicroService.data.enums;
    const enumsJson: {
        [prop: string]: { [prop: string]: string };
    } = {};
    enums.forEach((enumTemp: Enum) => {
        enumsJson[enumTemp.name] = enumsJson[enumTemp.name] || {};
        const enumItemList = enumTemp.enumItemList;
        enumItemList.forEach((enumItem) => {
            enumsJson[enumTemp.name][`${enumItem.value}`] = enumItem.label;
        });
    });
    return enumsJson;
}

export function apisToJson(app: App) {
    const apiJson: {
        [prop: string]: any;
    } = {};
    app.services.forEach((service) => {
        service.interfaces.forEach((itface: Interface) => {
            const path = itface.path || '';
            apiJson[itface.name] = {
                url: {
                    path,
                    method: itface.method,
                },
            };
        });
        if ((service as MicroService).processes) {
            (service as MicroService).processes.forEach((process: Process) => {
                const { launchProcessInterface, childShapes } = process;
                const path = launchProcessInterface.path || '';
                apiJson[launchProcessInterface.name] = {
                    url: {
                        path,
                        method: launchProcessInterface.method,
                    },
                };
                childShapes.forEach((processComp) => {
                    const { type, completeTaskInterface } = processComp;
                    if (type === 'UserTask') {
                        const path = completeTaskInterface.path || '';
                        apiJson[completeTaskInterface.name] = {
                            url: {
                                path,
                                method: completeTaskInterface.method,
                            },
                        };
                    }
                });
            });
        }
    });
    return apiJson;
}

export async function generateDataJson(app: App) {
    const services = await app.loadServices();
    const service = app.firstMicroService;
    await service.loadStructures();
    await service.loadInterfaces();
    await service.loadEntities();
    return {
        dataTypes: dataTypesToJson(),
        enums: enumsToJson(app),
        apis: apisToJson(app),
    };
}

export function saveDataTypesCache(app: App) {
    const serviceId = app.firstMicroService.id;
    const path = `dataTypes.json`;

    const promise = webFileService.saveFile({
        body: {
            serviceId,
            type: 'cache',
            path,
            content: JSON.stringify(dataTypesToJson()),
        },
    });

    saveLastModified(serviceId, path);
    return promise;
}

export async function loadDataTypesCache(serviceId: string) {
    const result = await webFileService.loadFile({
        query: {
            serviceId,
            path: `dataTypes.json`,
        },
    });
    return result && JSON.parse(result.content);
}

export function saveEnumsCache(app: App) {
    const serviceId = app.firstMicroService.id;
    const path = `enums.json`;

    const promise = webFileService.saveFile({
        body: {
            serviceId,
            type: 'cache',
            path,
            content: JSON.stringify(enumsToJson(app)),
        },
    });

    saveLastModified(serviceId, path);
    return promise;
}

export async function loadEnumsCache(serviceId: string) {
    const result = await webFileService.loadFile({
        query: {
            serviceId,
            path: `enums.json`,
        },
    });
    return result && JSON.parse(result.content);
}

export function saveApisCache(app: App) {
    const serviceId = app.firstMicroService.id;
    const path = `apis.json`;

    const promise = webFileService.saveFile({
        body: {
            serviceId,
            type: 'cache',
            path,
            content: JSON.stringify(apisToJson(app)),
        },
    });

    saveLastModified(serviceId, path);
    return promise;
}

export async function loadApisCache(serviceId: string) {
    const result = await webFileService.loadFile({
        query: {
            serviceId,
            path: `apis.json`,
        },
    });
    return result && JSON.parse(result.content);
}

export function getVertexIdToName() {
    const res: { [prop: string]: string } = {};
    for (const [id, vertex] of vertexsMap) {
        res[id] = vertex.name || (vertex as any).value;
    }
    return res;
}

export async function saveVertexIdToName(app: App) {
    const serviceId = app.firstMicroService.id;
    const path = `vertexIdToName.json`;

    // 合并原来的json。原因：如果有页面没有打开，vertexsMap里会没有那些页面的element点
    let nameJson = await webFileService.loadFile({
        query: {
            serviceId,
            path,
        },
    });
    nameJson = nameJson && JSON.parse(nameJson.content) || {};

    const promise = webFileService.saveFile({
        body: {
            serviceId,
            type: 'cache',
            path,
            content: JSON.stringify(Object.assign(nameJson, getVertexIdToName())),
        },
    });

    saveLastModified(serviceId, path);
    return promise;
}

export async function loadVertexIdToName(app: App) {
    const serviceId = app.firstMicroService.id;
    const result = await webFileService.loadFile({
        query: {
            serviceId,
            path: `vertexIdToName.json`,
        },
    });
    return result && JSON.parse(result.content);
}
