package com.cool.bang.modules.generate.service.impl;

import com.cool.bang.common.base.BaseServiceImpl;
import com.cool.bang.common.constant.enums.StatusType;
import com.cool.bang.common.tools.string.CharsetKit;
import com.cool.bang.common.web.request.PageDomain;
import com.cool.bang.core.exception.base.BusinessException;
import com.cool.bang.modules.generate.domain.po.TableColumnInfo;
import com.cool.bang.modules.generate.domain.po.TableInfo;
import com.cool.bang.modules.generate.mapper.TableColumnInfoMapper;
import com.cool.bang.modules.generate.mapper.TableInfoMapper;
import com.cool.bang.modules.generate.service.ITableInfoService;
import com.cool.bang.modules.generate.utils.FreeMarkerProcess;
import com.cool.bang.modules.generate.utils.FreeMarkerUtils;
import com.cool.bang.modules.generate.utils.GenUtil;
import com.cool.bang.modules.system.domain.po.Menu;
import com.cool.bang.modules.system.mapper.MenuMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import freemarker.template.Template;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Database table info service implementation class
 *
 * @author PeiZhi Guo
 * 2021-3-26 11:41
 */
@Service
public class TableInfoServiceImpl extends BaseServiceImpl<TableInfoMapper, TableInfo> implements ITableInfoService {

    @Resource
    private TableColumnInfoMapper columnInfoMapper;

    @Resource
    private MenuMapper menuMapper;

    @Override
    public PageInfo<TableInfo> dataBaseTablePage(PageDomain page, TableInfo param) {
        PageHelper.startPage(page.getPage(), page.getLimit());
        List<TableInfo> list = baseMapper.selectDataBaseTableByParam(param);
        return new PageInfo<>(list);
    }

    @Override
    public List<TableInfo> queryByNames(String[] tableNames) {
        return baseMapper.selectByNames(tableNames);
    }

    @Override
    public TableInfo queryTableById(Long id) {
        return baseMapper.selectTableById(id);
    }

    @Override
    public boolean update(TableInfo param) {
        super.update(param);
        param.getColumns().forEach(TableColumnInfo::nullConversionZero);
       for (TableColumnInfo res:param.getColumns()){
           return columnInfoMapper.update(res)>0;
       }
        return true;
        //return columnInfoMapper.updateBatch(param.getColumns()) > 0;
    }

    @Override
    @Transactional
    public StringBuilder generateCode(Long tableId) {
        StringBuilder strBuilder = new StringBuilder();
        // 获取表信息
        TableInfo tableInfo = baseMapper.selectById(tableId);
        // 获取表字段信息
        List<TableColumnInfo> tableColumnInfos = columnInfoMapper.selectByTableId(tableInfo.getId());
        // 初始化表
        GenUtil.initTable(tableInfo);
        // 循环初始化表字段
        //tableColumnInfos.forEach(item -> GenUtil.initTableColumn(item, tableInfo));
        tableInfo.setColumns(tableColumnInfos);
        // 初始化菜单
        //----------- start -----------
        if (null != tableInfo.getParentMenu()) {
            Menu menu = new Menu();
            menu.setParentId(tableInfo.getParentMenu());
            menu.setTitle(tableInfo.getFunctionName());
            menu.setType(1);
            menu.setCode(tableInfo.getModuleName() + ":" + tableInfo.getBusinessName() + ":main");
            menu.setHref("view/" + tableInfo.getModuleName() + "/" + tableInfo.getBusinessName() +"/main.html");
            menu.setSort(1);
            menu.setEnable(StatusType.ENABLE.ordinal());
            menu.setDelFlag(StatusType.ENABLE.ordinal());
            menu.setIcon("layui-icon ");

            Map<String, Object> params = new HashMap<>();
            params.put("name", tableInfo.getFunctionName());
            params.put("parentId", tableInfo.getParentMenu());
            Menu isMenu = menuMapper.selectMenuNameUnique(params);
            if (null == isMenu) {
                menu.insertConfigure();
                menuMapper.insert(menu);
            } else {
                menu.updateConfigure();
                menu.setId(isMenu.getId());
                menuMapper.update(menu);
            }
        }
        // ------------ end ----------
        // 生成模版数据
        Map<String, Object> map = FreeMarkerProcess.prepareContext(tableInfo);
        // 获取模版
        List<String> templates = FreeMarkerProcess.getTemplateList("");
        try {
            for (String template : templates) {
                // 渲染模板
                StringWriter sw = new StringWriter();
                Template tpl = FreeMarkerUtils.getTemplate(template);
                tpl.process(map, sw);
                String path = getGenPath(tableInfo, template);
                FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8);
                strBuilder.append(path).append("<br>");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strBuilder;
    }

    @Override
    @Transactional
    public void importTableStructure(List<TableInfo> list) {
        try {
            for (TableInfo tableInfo : list) {
                GenUtil.initTable(tableInfo);
                tableInfo.insertConfigure();
                int row = baseMapper.insert(tableInfo);
                if (row > 0) {
                    List<TableColumnInfo> tableColumns = columnInfoMapper.selectByTableName(tableInfo.getTableName());
                    for (TableColumnInfo tableColumn : tableColumns) {
                        GenUtil.initTableColumn(tableColumn, tableInfo);
                    }
                    columnInfoMapper.insertBatch(tableColumns);
                }
            }
        } catch (Exception e) {
            throw new BusinessException("导入失败：" + e.getMessage());
        }
    }

    /**
     * 获取代码生成地址
     *
     * Param table 业务表信息
     * Param template 模板文件路径
     * Return String
     */
    private static String getGenPath(TableInfo table, String template) {
        return System.getProperty("user.dir") + File.separator + FreeMarkerProcess.getFileName(template, table);
    }
}
