package net.tccn.meta;

import net.tccn.base.*;
import net.tccn.base.dbq.table.Field;
import net.tccn.plat.MPlat;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestParam;
import org.redkale.net.http.RestService;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: liangxianyou at 2018/10/17 16:59.
 */
@RestService(name = "meta", automapping = true, comment = "元数据服务")
public class MetadataService extends BaseService { //arango

    //-----------  元数据管理 ---------------
    @RestMapping(name = "tablelist", comment = "table列表")
    public JBean tableList(@RestParam(name = "plattoken") String token, String catalog, Integer dbid, String name) {
        JBean jBean = new JBean();

        List<Kv> list = MetaKit.getMTables().stream().filter(x
                -> (isEmpty(catalog) || catalog.equals(x.getCatalog())) &&
                (isEmpty(dbid) || dbid == (int) x.getDbid()) &&
                (isEmpty(name) || x.getTablename().contains(name)) &&
                (isEmpty(token) || x.getPlatid().equals(platId(token))) &&
                (isEmpty(x.getStatus()) || x.getStatus() != 9)
        ).map(x -> Kv.of("tablename", x.getTablename())
                .set("comment", x.getComment())
                .set("catalog", x.getCatalog())
                .set("alias", x.getAlias())
                .set("dbid", x.getDbid())
                .set("linkCount", MetaKit.getMetaLinks().stream().filter(link -> { // 关联表数量
                    String[] tables = link.getTables();
                    return x.getAlias().equals(tables[0]) || x.getAlias().equals(tables[1]);
                }).count())
        ).collect(Collectors.toList());
        return jBean.setBody(list);
    }


    @RestMapping(name = "service_list", comment = "业务列表")
    public JBean serviceList(@RestParam(name = "plattoken") String token) {
        JBean jBean = new JBean();

        List<MService> list = MetaKit.getMetaServices().stream()
                .filter(x -> platId(token).equals(x.getPlatid()))
                .collect(Collectors.toList());
        jBean.setBody(list);

        return jBean;
    }

    @RestMapping(name = "tableinfo", comment = "table详情")
    public JBean tableInfo(@RestParam(name = "plattoken") String token, String name, String alias) {
        JBean jBean = new JBean();

        MTable metaTable = null;
        if (!isEmpty(name)) {
            metaTable = MetaKit.getMetaTable(name, token);
        }
        if (metaTable == null && !isEmpty(alias)) {
            metaTable = MetaKit.getMetaTableByAlias(alias);
        }

        return jBean.setBody(metaTable);
    }

    @RestMapping(name = "service_save", comment = "service信息保存")
    public JBean serviceSave(@RestParam(name = "plattoken") String token, @RestParam(name = "service") MService service) {
        JBean jBean = new JBean();
        do {
            // 标识码非空校验
            if (isEmpty(service.getTablealias())) {
                jBean.set(-1, "请选择业务主表");
                break;
            }

            // 标识码非空校验
            if (isEmpty(service.getName())) {
                jBean.set(-1, "业务标识码无效");
                break;
            }

            // 标识码重复校验
            MService metaService = MetaKit.getMetaService(service.getName(), token);
            if (metaService != null && metaService.getServid() != service.getServid()) {
                jBean.set(-1, "业务标识码被占用，修改业务标识码重试");
                break;
            }

            if (service.getServid() == 0) {
                service.setPlatid(platId(token));
            }
            metaKit.save(service);
        } while (false);
        return jBean;
    }

    @RestMapping(name = "service_info", comment = "service基本信息")
    public JBean serviceInfo(@RestParam(name = "plattoken") String token, String name) {
        MService mService = MetaKit.getMetaService(name, token);
        return JBean.by(0, "", mService);
    }

    @RestMapping(name = "service_detail", comment = "service详情")
    public JBean serviceDetail(@RestParam(name = "plattoken") String token, String name) {
        MService metaService = MetaKit.getMetaService(name, token);
        Kv detail = MetaKit.buildeDetail(metaService);

        return JBean.by(0, "", detail);
    }

    //修改item的排序
    @RestMapping(name = "itemsort", comment = "字段排序")
    public JBean itemSortSave(String alias, String[] items, @RestParam(name = "plattoken") String token) {

        MTable metaTable = MetaKit.getMetaTableByAlias(alias);

        MetaKit.sortItem.apply(metaTable, items);

        metaKit.save(metaTable);
        return JBean.OK;
    }

    @RestMapping(name = "itemupdate", comment = "字段修改")
    public JBean itemUpdate(String alias, List<Field> items, @RestParam(name = "plattoken") String token) {
        MTable metaTable = MetaKit.getMetaTableByAlias(alias);

        MetaKit.itemUpdate.apply(metaTable, items);
        metaKit.save(metaTable);
        return JBean.OK;
    }

    @RestMapping(name = "showsort", comment = "展示字段修改")
    public JBean showSort(String name, List<Map<String, String>> shows, @RestParam(name = "plattoken") String token) {
        if (Utils.isEmpty(shows)) return null;

        MService metaService = MetaKit.getMetaService(name, token);
        metaService.setShows(shows);
        metaKit.save(metaService);
        return JBean.OK;
    }

    @RestMapping(name = "exportsave", comment = "导出配置保存")
    public JBean exportSave(String name, List<Map<String, String>> exports, @RestParam(name = "plattoken") String token) {
        if (Utils.isEmpty(exports)) return null;

        MService metaService = MetaKit.getMetaService(name, token);
        metaService.setExports(exports);

        metaKit.save(metaService);
        return JBean.OK;
    }

    @RestMapping(name = "detailsave", comment = "详情配置保存")
    public JBean detailSave(String name, List<Map<String, String>> details, @RestParam(name = "plattoken") String token) {
        if (Utils.isEmpty(details)) return null;

        MService metaService = MetaKit.getMetaService(name, token);
        metaService.setDetails(details);

        metaKit.save(metaService);
        return JBean.OK;
    }

    @RestMapping(name = "editsave", comment = "表单配置保存")
    public JBean editSave(String name, List<FromItem> edits, @RestParam(name = "plattoken") String token) {
        if (Utils.isEmpty(edits)) return null;

        MService metaService = MetaKit.getMetaService(name, token);
        metaService.setEdits(edits);

        metaKit.save(metaService);
        return JBean.OK;
    }

    /*@RestMapping(name = "delsave", comment = "删除配置保存")
    public JBean delSave(String name, Map<String, String> dels, @RestParam(name = "plattoken") String token) {
        if (Utils.isEmpty(dels)) return null;

        MService metaService = MetaKit.getMetaService(name, token);
        metaService.setDels(dels);

        MetaKit.save(metaService);
        return JBean.OK;
    }*/

    @RestMapping(name = "importsort", comment = "导入字段保存")
    public JBean importSort(String serviceKey, List<String> items, @RestParam(name = "plattoken") String token) {
        if (Utils.isEmpty(items)) return null;

        MTable metaTable = MetaKit.getMetaTable(serviceKey, token);
        //fixme: metaTable.setImports(items);

        metaKit.save(metaTable);
        return JBean.OK;
    }

    @RestMapping(name = "dbplatupdate", comment = "数据平台修改")
    public JBean dbPlatUpdate(MTable metaTable, @RestParam(name = "plattoken") String token) {

        MTable _metaTable = MetaKit.getMetaTableByKey(metaTable.getTableid());
        _metaTable.setTablename(metaTable.getTablename());
        _metaTable.setComment(metaTable.getComment());
        _metaTable.setCatalog(metaTable.getCatalog());
        _metaTable.setDbid(metaTable.getDbid());
        _metaTable.setCatalog(metaTable.getCatalog());

        metaKit.save(_metaTable);
        return JBean.OK;
    }

    @RestMapping(name = "filter_update", comment = "查询配置修改")
    public JBean filterUpdate(String name, List<Filter> filters, @RestParam(name = "plattoken") String token) {
        MService metaService = MetaKit.getMetaService(name, token);
        metaService.setFilters(filters);

        metaKit.save(metaService);
        return JBean.OK;
    }

    @RestMapping(name = "table_link_list", comment = "实体表，包含link信息的列表,(metalink 管理页面使用)")
    public JBean tableLinkList(@RestParam(name = "plattoken") String token) {
        JBean jBean = new JBean();

        List<Kv> list = MetaKit.getMTables().stream()
                .filter(x -> (isEmpty(token) || x.getPlatid().equals(platId(token)))
                        && (x.getStatus() != 9)
                ).map(x -> {
                    Kv kv = Kv.of("tablename", x.getTablename())
                            .set("comment", x.getComment())
                            .set("alias", x.getAlias())
                            .set("linkCount", 0);

                    //关联表数量
                    long count = MetaKit.getMetaLinks().stream().filter(link -> {
                        String[] tables = link.getTables();
                        return x.getAlias().equals(tables[0]) || x.getAlias().equals(tables[1]);
                    }).count();
                    kv.set("linkCount", count);

                    return kv;
                }).collect(Collectors.toList());

        return jBean.setBody(list);
    }


    @RestMapping(name = "link_info_list", comment = "关联信息")
    public JBean linkInfo(String alias) {
        JBean jBean = new JBean();
        //MetaTable metaTable = MetaKit.getMetaTableByAlias(alias);
        List<Kv> list = MetaKit.getMetaLinks().stream().filter(x ->
                x.getTables()[0].equals(alias) || x.getTables()[1].equals(alias)
        ).map(x -> {
            MTable linkTable = MetaKit.getMetaTableByAlias(x.getTables()[0].equals(alias) ? x.getTables()[1] : x.getTables()[0]);
            Kv kv = Kv.of("tablename", linkTable.getTablename())
                    .set("alias", linkTable.getAlias())
                    .set("comment", linkTable.getComment())
                    .set("linkSize", x.getLinks().size())
                    .set("links", x.getLinks());
            return kv;
        }).collect(Collectors.toList());

        return jBean.setBody(list);
    }

    @RestMapping(name = "link_list", comment = "实体关系列表")
    public JBean linkList(String alias) {
        JBean jBean = new JBean();

        List<MLink> links = MetaKit.getMetaLinks();

        if (!isEmpty(alias)) {
            links = Utils.filter(links, x -> x.getTables()[0].equals(alias) || x.getTables()[1].equals(alias));
        }

        return jBean.setBody(links);
    }

    @RestMapping(name = "link_save", comment = "实体关系列表")
    public JBean linkSave(MLink link, @RestParam(name = "plattoken") String token) {
        metaKit.save(link);
        return JBean.OK;
    }


    @RestMapping(name = "plat_list", comment = "平台列表")
    public JBean platList() {
        JBean jBean = new JBean();
        List<MPlat> plats = MetaKit.getMPlats();

        return jBean.setBody(plats);
    }

    @RestMapping(name = "refresh", comment = "刷新服务端缓存数据")
    public JBean refresh() {
        JBean jBean = new JBean();
        MetaKit.init();
        return jBean;
    }

    // ------------------------------------ 对外服务 --------------------------------------
    @RestMapping(name = "cfg", auth = false, comment = " 功能配置")
    public JBean cfg(String name, @RestParam(name = "plattoken") String token) {
        JBean jBean = new JBean();
        Map cfg = MetaKit.cfg(name, token);

        return jBean.setBody(cfg);
    }
}
