package com.boman.gen.service;

import com.boman.domain.constant.UserConstants;
import com.boman.common.core.text.Convert;
import com.boman.common.core.utils.DateUtils;
import com.boman.common.core.utils.SecurityUtils;
import com.boman.common.core.utils.StringUtils;
import com.boman.common.core.utils.obj.ObjectUtils;
import com.boman.common.log.enums.BusinessType;
import com.boman.common.redis.RedisKey;
import com.boman.common.redis.service.RedisService;
import com.boman.domain.GenTable;
import com.boman.domain.GenTableColumn;
import com.boman.domain.TableSql;
import com.boman.domain.constant.FormDataConstant;
import com.boman.gen.mapper.GenTableColumnMapper;
import com.boman.gen.mapper.GenTableMapper;
import com.boman.gen.mapper.TableSqlMapper;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 业务字段 服务层实现
 *
 * @author ruoyi
 */
@Service
public class GenTableColumnServiceImpl implements IGenTableColumnService {
    @Autowired
    private GenTableColumnMapper genTableColumnMapper;
    @Autowired
    private GenTableMapper genTableMapper;
    @Autowired
    private TableSqlMapper tableSqlMapper;
    @Autowired
    private RedisService redisService;



    /**
     * 查询业务字段列表
     *
     * @param tableId 业务字段编号
     * @return 业务字段集合
     */
    @Override
    public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId) {
        List<GenTableColumn> genTableColumns = genTableColumnMapper.selectGenTableColumnListByTableId(tableId);
        for (GenTableColumn genTableColumn : genTableColumns) {
            if (genTableColumn.getHrParentId() != null) {
                for (GenTableColumn tableColumn : genTableColumns) {
                    if (genTableColumn.getHrParentId().equals(tableColumn.getId())) {
                        genTableColumn.setHrParentName(tableColumn.getColumnName());
                        break;
                    }
                }
            }
            if (genTableColumn.getForeignKey() != null) {
                GenTableColumn genTableColumn1 = selectGenTableColumnListByColumnId(genTableColumn.getForeignKey());
                genTableColumn.setForeignKeyName(genTableColumn1.getColumnName());
            }
        }
        return genTableColumns;
    }

    @Override
    public List<GenTableColumn> selectGenTableColumnList(GenTableColumn genTableColumn) {
        return genTableColumnMapper.selectGenTableColumnList(genTableColumn);
    }

    /**
     * 根据gen_table_column的id查询字段对象
     *
     * @param columnId
     * @return
     */
    @Override
    public GenTableColumn selectGenTableColumnListByColumnId(Long columnId) {
        return genTableColumnMapper.selectGenTableColumnByColumnId(columnId);
    }

    /**
     * /**
     * 根据字段编号获取字段详细信息, 把此外键对应的名称返回给前台
     *
     * @param columnId pk
     */
    @Override
    public GenTableColumn getByIdWithForeignKey(Long columnId) {
        GenTableColumn tableColumn = selectGenTableColumnListByColumnId(columnId);
        Long foreignKey = tableColumn.getForeignKey();
        if (ObjectUtils.isNotEmpty(foreignKey)) {
            GenTableColumn fkTableColumn = selectGenTableColumnListByColumnId(foreignKey);
            String columnName = fkTableColumn.getColumnName();
            Map<String, Object> map = Maps.newHashMap();
            map.put(FormDataConstant.SINGLE_OBJ_NAME, foreignKey);
            map.put(FormDataConstant.SINGLE_OBJ_VALUE, columnName);
            tableColumn.setFkInfo(map);
        }

        return tableColumn;
    }

    /**
     * 查询业务字段列表
     *
     * @param tableIdList 业务字段编号List
     * @return 业务字段集合
     */
    @Override
    public List<GenTableColumn> listByTableIdList(List<Long> tableIdList) {
        if (null == tableIdList || tableIdList.isEmpty()) {
            return Collections.emptyList();
        }

        return genTableColumnMapper.listByTableIdList(tableIdList);
    }

    /**
     * 新增业务字段
     *
     * @param genTableColumn 业务字段信息
     * @return 结果
     */
    @Override
    public int insertGenTableColumn(GenTableColumn genTableColumn) {
        Long tableId = genTableColumn.getTableId();
        GenTable genTable = genTableMapper.selectGenTableById(tableId);
        genTableColumn.setTableColumnName(genTable.getTableName()+"."+genTableColumn.getColumnName());
        int i = genTableColumnMapper.insertGenTableColumn(genTableColumn);
        List<GenTableColumn> list = new ArrayList<>();
        list.add(genTableColumn);
        isAk(list);
        insertCreateLog(list, BusinessType.INSERT);
        //处理字段翻译器
        //fieldTranslator(list);
        return i;
    }

    /**
     * 修改业务字段
     *
     * @param genTableColumn 业务字段信息
     * @return 结果
     */
    @Override
    public int updateGenTableColumn(GenTableColumn genTableColumn) {
        List<GenTableColumn> list = new ArrayList<>();
        list.add(genTableColumn);
        isAk(list);
        insertCreateLog(list, BusinessType.UPDATE);
        //fieldTranslator(list);
        return genTableColumnMapper.updateGenTableColumn(genTableColumn);
    }


    /**
     * 批量修改genTableColumn
     *
     * @param genTableColumn
     * @return
     */
    @Override
    public void updateGenTableColumnList(List<GenTableColumn> genTableColumn) {
        isAk(genTableColumn);
        insertCreateLog(genTableColumn, BusinessType.UPDATE);
        for (GenTableColumn tableColumn : genTableColumn) {
            genTableColumnMapper.updateGenTableColumn(tableColumn);
        }
    }

    /**
     * 插入表sql日志
     */
    @Async
    public void insertCreateLog(List<GenTableColumn> genTableColumnList, BusinessType type) {
        GenTable genTable = genTableMapper.selectGenTableById(genTableColumnList.get(0).getTableId());
        TableSql tableSql = tableSqlMapper.selectTableSqlByTableId(genTableColumnList.get(0).getTableId());
        //新增业务字段的同时新增一条建表sql修改日志
        String createLog = "";
        if (tableSql != null) {
            createLog = tableSql.getCreateLog();
        }
        StringBuffer sb = new StringBuffer(createLog);
        for (GenTableColumn genTableColumn : genTableColumnList) {
            //ALTER TABLE table_name ADD COLUMN column_name VARCHAR(100) DEFAULT NULL COMMENT '新加字段';
            sb.append("\r\n").append(DateUtils.getTime()).append(" ").append(SecurityUtils.getUsername()).append(" ALTER TABLE ").append(genTable.getTableName());
            if (BusinessType.INSERT.equals(type)) {
                sb.append(" ADD COLUMN ").append(genTableColumn.getColumnName()).append(" ").append(genTableColumn.getColumnType());
                sb = genTableColumn.getDefaultValue() == null ? sb.append(" DEFAULT NULL COMMENT ") : sb.append(" DEFAULT '").append(genTableColumn.getDefaultValue()).append("' COMMENT '");
                sb.append(genTableColumn.getColumnComment()).append("';");
            } else if (BusinessType.UPDATE.equals(type)) {
                sb.append(" MODIFY ").append(genTableColumn.getColumnName()).append(" ").append(genTableColumn.getColumnType()).append(";");
            } else if (BusinessType.DELETE.equals(type)) {
                sb.append(" DROP ").append(genTableColumn.getColumnName()).append(";");
            }
        }
        if (tableSql != null) {
            tableSql.setCreateLog(sb.toString());
            tableSqlMapper.updateTableSql(tableSql);
        }
    }

    /**
     * 判断对象是否设置显示和输入字段
     *
     * @param genTableColumnList
     */
    @Async
    public void isAk(List<GenTableColumn> genTableColumnList) {
        GenTable genTable = new GenTable();
        for (GenTableColumn genTableColumn : genTableColumnList) {
            //是否是输入
            String isIn = genTableColumn.getIsIn();
            //是否是显示
            String isOut = genTableColumn.getIsOut();
            //查询出该表所有是输入或者是显示的字段
            List<GenTableColumn> genTableColumns = genTableColumnMapper.selectGenTableColumnIsListByTableId(genTableColumn.getTableId());
            if (UserConstants.YES.equals(isIn)) {
                //判断是否已经存在输入字段且不是同一个字段
                if (genTableColumns.size() > 0) {
                    for (GenTableColumn tableColumn : genTableColumns) {
                        if (UserConstants.YES.equals(tableColumn.getIsIn()) && !tableColumn.getId().equals(genTableColumn.getId())) {
                            tableColumn.setIsIn("N");
                            genTableColumnMapper.updateGenTableColumn(tableColumn);
                            break;
                        }
                    }
                }
                genTable.setId(genTableColumn.getTableId());
                genTable.setAkColumn(genTableColumn.getId());
            }
            if (UserConstants.YES.equals(isOut)) {
                //判断是否已经存在显示字段且不是同一个字段
                if (genTableColumns.size() > 0) {
                    for (GenTableColumn tableColumn : genTableColumns) {
                        if (UserConstants.YES.equals(tableColumn.getIsOut()) && !tableColumn.getId().equals(genTableColumn.getId())) {
                            tableColumn.setIsOut("N");
                            genTableColumnMapper.updateGenTableColumn(tableColumn);
                            break;
                        }
                    }
                    genTable.setId(genTableColumn.getTableId());
                    genTable.setDkColumn(genTableColumn.getId());
                }
            }
        }
        if (genTable.getId() != null) {
            genTableMapper.updateGenTable(genTable);
        } else {
            //表明没有显示和输入字段更新到gen表上
            genTableMapper.updateGenTableColumnNull(genTableColumnList.get(0).getTableId());
        }
    }

    /**
     * 删除业务字段对象
     *
     * @param ids 表id
     * @return 结果
     */
    @Override
    public int deleteGenTableColumnByIds(String ids) {
        return genTableColumnMapper.deleteGenTableColumnByIds(Convert.toLongArray(ids));
    }

    /**
     * 删除业务字段对象
     *
     * @param ids 字段id
     * @return
     */
    @Override
    public int deleteGenTableColumnByColumnIds(String ids) {
        Long[] longs = Convert.toLongArray(ids);
        List<GenTableColumn> list = new ArrayList<>();
        for (Long aLong : longs) {
            GenTableColumn genTableColumn = genTableColumnMapper.selectGenTableColumnByColumnId(aLong);
            list.add(genTableColumn);
        }
        insertCreateLog(list, BusinessType.DELETE);
        return genTableColumnMapper.deleteGenTableColumnByColumnIds(Convert.toLongArray(ids));
    }

    /**
     * 校验column_name是否重复
     *
     * @param genTableColumn
     * @return
     */
    @Override
    public String checkColumnNameUnique(GenTableColumn genTableColumn) {
        Long columnId = StringUtils.isNull(genTableColumn.getId()) ? -1L : genTableColumn.getId();
        GenTableColumn column = genTableColumnMapper.checkColumnNameUnique(genTableColumn);
        if (StringUtils.isNotNull(column) && !column.getId().equals(columnId)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }


    /**
     * 功能描述: 根据表名查询改表所有的字段信息
     *
     * @param tableName tableName
     * @return java.util.List<com.boman.domain.GenTableColumn>
     */
    @Override
    public List<GenTableColumn> listColumnsByTableName(String tableName) {
        GenTable genTable = redisService.getCacheObject(RedisKey.TABLE_INFO + tableName);
        if (genTable == null) {
            genTable = genTableMapper.selectGenTableByName(tableName);
            if (genTable == null) {
                return null;
            }
        }

        List<GenTableColumn> columns = genTable.getColumns();
        if (ObjectUtils.isEmpty(columns)) {
            columns = listByTableIdList(Collections.singletonList(genTable.getId()));
        }

        return columns;
    }
}