package com.system.serivce.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.system.dao.DatabaseTableMapper;
import com.system.serivce.IDatabaseTableService;
import com.system.transfer.configure.*;
import com.system.transfer.response.RestResponse;
import com.system.utils.JsonUtil;
import com.system.utils.StringUtil;
import com.system.utils.TableStructureUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * @author Inori
 */
@Service
public class DatabaseTableServiceImpl implements IDatabaseTableService {

    @Autowired
    private DatabaseTableMapper databaseTableMapper;


    @Override
    public TableStructureListOutVo formTableStructureList(TableStructureListInVo inVo) {
        Page<TableStructureListOutVoRecords> page = new Page<>(inVo.getPageNo(), inVo.getPageSize());
        List<TableStructureListOutVoRecords> recordsList = databaseTableMapper.tableStructureList(page, inVo);

        TableStructureListOutVo outVo = new TableStructureListOutVo();
        outVo.setTotal((int) page.getTotal());
        outVo.setRecords(recordsList);
        return outVo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RestResponse formTableStructureCreate(TableStructureCreateInVo inVo) {
        if (StringUtil.isNotNull(inVo.getData())) {
            inVo.setFormJson(JsonUtil.toString(inVo.getData()));
        }

        TableStructureCreateInVo request = TableStructureUtil.purchaseInVo(inVo);
        List<TableStructureCreateInVoRecords> recordsList = TableStructureUtil.getFieldList(inVo.getFormJson());
        List<TableStructureCreateInVoRecords> collectList = recordsList.stream().filter(m -> StringUtil.isBlank(m.getDbFieldName()) && StringUtil.isBlank(m.getDbFieldComment())).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(collectList)) {
            return RestResponse.fail("字段填写缺失");
        }

        if (StringUtil.isNull(inVo.getId())) {
            if (databaseTableMapper.isDatabaseTableDoesItExist(request.getDbTableName()) > 0) {
                return RestResponse.fail("数据库表已存在");
            }

            request.setDbTableComment("'" + request.getDbTableComment() + "'");
            databaseTableMapper.databaseTableCreate(request, recordsList);

            request.setDbTableComment(request.getDbTableComment().replace("'", ""));
            databaseTableMapper.tableStructureCreate(request);
        } else {
            TableStructureListOutVoRecords result = databaseTableMapper.tableStructureOneById(request.getId());
            if (!request.getDbTableName().equals(result.getDbTableName())) {
                databaseTableMapper.databaseTableNameUpdate(request.getDbTableName(), result.getDbTableName());
            }
            if (!request.getDbTableComment().equals(result.getDbTableComment())) {
                databaseTableMapper.databaseTableCommentUpdate(request.getDbTableName(), "'" + request.getDbTableComment() + "'");
            }

            List<TableStructureCreateInVoRecords> tempList = TableStructureUtil.getFieldList(result.getFormJson());

            List<TableStructureCreateInVoRecords> deleteList = TableStructureUtil.isCreateOrDelete(tempList, recordsList);
            if (!CollectionUtils.isEmpty(deleteList)) {
                for (TableStructureCreateInVoRecords records : deleteList) {
                    records.setDbTableName(request.getDbTableName());
                    databaseTableMapper.databaseTableFieldDelete(records);
                }
            }

            List<TableStructureCreateInVoRecords> createList = TableStructureUtil.isCreateOrDelete(recordsList, tempList);
            if (!CollectionUtils.isEmpty(createList)) {
                for (TableStructureCreateInVoRecords records : createList) {
                    records.setDbTableName(request.getDbTableName());
                    databaseTableMapper.databaseTableFieldCreate(records);
                }
            }

            List<TableStructureCreateInVoRecords> updateList = TableStructureUtil.isUpdate(recordsList, tempList);
            if (!CollectionUtils.isEmpty(updateList)) {
                for (TableStructureCreateInVoRecords records : updateList) {
                    records.setDbTableName(request.getDbTableName());
                    databaseTableMapper.databaseTableFieldUpdate(records);
                }
            }

            databaseTableMapper.tableStructureUpdate(request);
        }

        return RestResponse.success();
    }

    @Override
    public RestResponse formTableStructureDelete(TableStructureDeleteInVo inVo) {
        databaseTableMapper.formTableStructureDelete(inVo);

        databaseTableMapper.databaseTableDelete(inVo.getDbTableName());
        return RestResponse.success();
    }

    @Override
    public TableStructureDataOutVo formTableStructureData(TableStructureDataInVo inVo) {
        TableStructureListOutVoRecords records = databaseTableMapper.tableStructureOneByFormId(inVo.getFormId());

        List<TableStructureDataOutVoRecords> fieldList = TableStructureUtil.getFormFieldList(records.getFormJson());
        List<String> dbFieldName = fieldList.stream().map(TableStructureDataOutVoRecords::getKey).collect(Collectors.toList());

        Page<Map<String, Object>> page = new Page<>(inVo.getPageNo(), inVo.getPageSize());
        List<Map<String, Object>> dataList = databaseTableMapper.databaseTableDataList(records.getDbTableName(), dbFieldName, page);

        TableStructureDataOutVo outVo = new TableStructureDataOutVo();
        outVo.setTotal((int) page.getTotal());
        outVo.setFieldList(fieldList);
        outVo.setDataList(dataList);
        return outVo;
    }

    @Override
    public RestResponse formTableStructureDataDelete(TableStructureDataDeleteInVo inVo) {
        databaseTableMapper.formTableStructureDataDelete(inVo);

        return RestResponse.success();
    }


}
