package com.keyware.shandan.dynacmicform.core.basic.services;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.keyware.shandan.common.util.DateUtil;
import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.dynacmicform.core.DynamicFormEventListener;
import com.keyware.shandan.dynacmicform.core.basic.entity.FormInfoPo;
import com.keyware.shandan.dynacmicform.core.db.SqlHelper;
import com.keyware.shandan.dynacmicform.core.db.executor.SqlExecutor;
import com.keyware.shandan.dynacmicform.core.db.parser.TableInfoParser;
import com.keyware.shandan.dynacmicform.core.db.pojo.Table;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 动态表单服务类
 */
@Slf4j
@Service
public class DynamicFormService {
    private final SqlExecutor sqlExecutor;
    private final FormInfoService formInfoService;
    private final DynamicFormEventListener dynamicFormEventListener;

    public DynamicFormService(SqlExecutor sqlExecutor,
                              FormInfoService formInfoService,
                              DynamicFormEventListener dynamicFormEventListener) {
        this.sqlExecutor = sqlExecutor;
        this.formInfoService = formInfoService;
        this.dynamicFormEventListener = dynamicFormEventListener;
    }

    /**
     * 保存动态表单，并创建或者更新数据库表
     *
     * @param form 表单信息
     * @return boolean
     * @throws Exception 异常
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean saveForm(FormInfoPo form) throws Exception {
        FormInfoPo oldForm = formInfoService.getById(form.getId());
        Table table = TableInfoParser.parseTable(form);
        if (oldForm == null) {
            String sql = SqlHelper.tableCreateSql(table);
            sqlExecutor.execute(sql);
        } else {
            Table oldTable = TableInfoParser.parseTable(oldForm);
            List<String> alterSqlList = SqlHelper.alterTableDropColumnSql(oldTable, table);
            alterSqlList.addAll(SqlHelper.alterTableAlterColumnSql(oldTable, table));
            alterSqlList.addAll(SqlHelper.alterTableModifyColumnSql(oldTable, table));
            alterSqlList.addAll(SqlHelper.alterTableAddColumnSql(oldTable, table));
            alterSqlList.addAll(SqlHelper.commentTableSql(oldTable, table));
            alterSqlList.addAll(SqlHelper.commentColumnSql(oldTable, table));
            sqlExecutor.executeBatch(alterSqlList);
        }
        if (StringUtils.isBlank(form.getQueryConfig())) {
            generateQueryConfig(form);
        }

        boolean ok = formInfoService.saveOrUpdate(form);
        if (ok) {
            dynamicFormEventListener.onSave(form);
        }
        return ok;
    }

    /**
     * 删除表单信息，逻辑删除，并对实际数据表进行重命名备份
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Integer id) throws Exception {
        FormInfoPo form = formInfoService.getById(id);
        if (form != null) {
            // 对原始表结构进行重命名备份
            Table table = TableInfoParser.parseTable(form);
            String newName = table.getName() + "_BACKUP_" + DateUtil.getFormatNowDate("yyyyMMddHHmmss");
            String sql = SqlHelper.tableRenameSql(table.getName(), newName);
            sqlExecutor.execute(sql);
            // 更新表名后进行逻辑删除
            form.setFormId(newName);
            formInfoService.updateById(form);
            boolean ok = formInfoService.removeById(id);
            if (!ok) {
                throw new RuntimeException("表单信息删除异常");
            }
        }
        dynamicFormEventListener.onDrop(form);
        return true;
    }

    /**
     * 禁用表单
     *
     * @param id      表单ID
     * @param disable 是否禁用，true：禁用，false：启用
     * @return
     */
    public boolean disabledForm(int id, boolean disable) {
        UpdateWrapper<FormInfoPo> wrapper = new UpdateWrapper<>();
        wrapper.set("IS_DISABLED", disable).eq("ID", id);
        return formInfoService.update(wrapper);
    }

    /**
     * 生成查询配置信息
     *
     * @param form 表单数据
     */
    private void generateQueryConfig(FormInfoPo form) {
        JSONArray queryConfig = new JSONArray();
        JSONArray.parseArray(form.getFieldConfig()).forEach(obj -> {
            JSONObject field = (JSONObject) obj;
            JSONObject config = new JSONObject();
            config.put("fieldId", field.get("fieldId"));
            config.put("label", field.get("label"));
            config.put("tag", field.get("tag"));
            config.put("allowQuery", false);
            config.put("display", true);
            config.put("allowSort", false);
            config.put("headerOrder", 0);
            queryConfig.add(config);
        });
        form.setQueryConfig(queryConfig.toString());
    }
}
