/**
 * Copyright © 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.form.service;

import com.alibaba.fastjson.JSON;
import com.jeeplus.common.utils.IdGen;
import com.jeeplus.common.utils.SpringContextHolder;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.core.persistence.Page;
import com.jeeplus.core.persistence.dialect.Dialect;
import com.jeeplus.core.persistence.dialect.db.*;
import com.jeeplus.core.persistence.interceptor.SQLHelper;
import com.jeeplus.modules.form.entity.Column;
import com.jeeplus.modules.form.entity.Form;
import com.jeeplus.modules.sys.service.AreaService;
import com.jeeplus.modules.sys.service.OfficeService;
import com.jeeplus.modules.sys.utils.UserUtils;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 数据表单Service
 *
 * @author 刘高峰
 * @version 2019-12-24
 */
@Service
@Transactional(readOnly = true)
public class GenerateFormService {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private OfficeService officeService;
    @Autowired
    private AreaService areaService;

    /**
     * 更新表单
     *
     * @param data
     * @return
     */
    @Transactional(readOnly = false)
    public void executeUpdate(Form form, Map data, HashMap map) {
        //保存表单数据
        if (StringUtils.isNotBlank(form.getTableName())) {
            String updateSql = "update " + form.getTableName() + " set ";
            boolean needUpdate = false;
            for (Object name : data.keySet()) {
                if (name.equals("id"))
                    continue;
                if (map.get(name).equals("slider")
                        || map.get(name).equals("number")
                        || map.get(name).equals("rate")
                        || map.get(name).equals("switch")) {
                    updateSql = updateSql + " " + name + " = " + data.get(name) + ",";
                } else {
                    updateSql = updateSql + " " + name + " = '" + data.get(name) + "',";
                }
                needUpdate = true;
            }
            updateSql = updateSql.substring(0, updateSql.length() - 1);
            updateSql = updateSql + " where id = '" + data.get("id").toString() + "'";
            if (needUpdate) {
                jdbcTemplate.execute(updateSql);
            }
        }
    }

    /**
     * 保存表单
     *
     * @param data
     * @return
     */
    @Transactional(readOnly = false)
    public void executeInsert(Form form, Map data, Map map) {
        //保存表单数据
        if (StringUtils.isNotBlank(form.getTableName())) {
            //遍历参数，组装sql语句
            String insertSql = "insert into " + form.getTableName() + "(";
            String insertSqlValue = " values(";
            for (Object name : data.keySet()) {
                insertSql += "" + name + ",";
                if (map.get(name).equals("slider")
                        || map.get(name).equals("number")
                        || map.get(name).equals("rate")
                        || map.get(name).equals("switch")) {
                    insertSqlValue += "" + data.get(name) + ",";
                } else {
                    insertSqlValue += "'" + data.get(name) + "',";
                }
            }
            String uuid = IdGen.uuid();
            insertSql += "id)" + insertSqlValue + "'" + uuid + "')";

            jdbcTemplate.execute(insertSql);
        }

    }
    /**
     * 删除表单内容
     *
     * @return
     */
    @Transactional(readOnly = false)
    public void executeDelete(Form form, String ids) {
        if (StringUtils.isNotBlank(form.getTableName())) {
            String deleteSql = "delete from " + form.getTableName() + " where id in ( ";
            String idArra = "";
            for (String id : ids.split(",")) {
                idArra = idArra + "'" + id + "',";
            }
            idArra = idArra.substring(0, idArra.length() - 1);
            deleteSql = deleteSql + idArra + " ) ";
            jdbcTemplate.execute(deleteSql);
        }
    }
    protected Dialect getDialect() {
        Dialect dialect = null;
        String dbType ;
        try{
            dbType = SpringContextHolder.getBean(DatabaseIdProvider.class).getDatabaseId(SpringContextHolder.getBean(DataSource.class));
        }catch (Exception e){
            dbType = "mysql";
        }

        if ("db2".equals(dbType)){
            dialect = new DB2Dialect();
        }else if("derby".equals(dbType)){
            dialect = new DerbyDialect();
        }else if("h2".equals(dbType)){
            dialect = new H2Dialect();
        }else if("hsql".equals(dbType)){
            dialect = new HSQLDialect();
        }else if("mysql".equals(dbType)){
            dialect = new MySQLDialect();
        }else if("oracle".equals(dbType)){
            dialect = new OracleDialect();
        }else if("postgre".equals(dbType)){
            dialect = new PostgreSQLDialect();
        }else if("mssql".equals(dbType) || "sqlserver".equals(dbType)){
            dialect = new SQLServerDialect();
        }else if("sybase".equals(dbType)){
            dialect = new SybaseDialect();
        }
        if (dialect == null) {
            throw new RuntimeException("mybatis dialect error.");
        }
        return dialect;
    }
    public Page<Map> executeFindPage(Page page, Form form, String params, String fields){
        String originalSql = "select * from "+form.getTableName()+" ";
        Map <String, String>paramsMap = JSON.parseObject(params, Map.class);
        List<Column> fieldArra = JSON.parseArray(fields, Column.class);
        HashMap<String, String> typeMap = new HashMap();
        for(Column column: fieldArra){
            typeMap.put(column.getModel(), column.getType());
        }
        if(paramsMap.size() > 0){
            originalSql = originalSql + "where ";
            for (String key : paramsMap.keySet()) {
                originalSql = originalSql + " " + key + " like " + "'%"+String.valueOf(paramsMap.get(key))+"%' and ";
            }
            originalSql = originalSql.substring(0, originalSql.length() - 4);
        }
        if(StringUtils.isNotBlank(page.getOrderBy())){
            originalSql = originalSql + " order by " + page.getOrderBy();
        }
        Dialect dialect = getDialect();
        final String countSql = "select count(1) from (" + dialect.getCountString(originalSql) + ") tmp_count";
        int count = jdbcTemplate.queryForObject(countSql, Integer.class);
        page.setCount(count);
        String pageSql = SQLHelper.generatePageSql(originalSql, page, dialect);
        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(pageSql);

        for (Map<String, Object> map : mapList) {
            for (String key : map.keySet()) {
                if("user".equals(typeMap.get(key))){
                    if(map.get(key) != null && UserUtils.get(map.get(key).toString())!=null){
                        map.put(key, UserUtils.get(map.get(key).toString()).getName());
                    }
                }
                if("office".equals(typeMap.get(key))){
                    if(map.get(key) != null && officeService.get(map.get(key).toString())!=null){
                        map.put(key, officeService.get(map.get(key).toString()).getName());
                    }
                }
                if("area".equals(typeMap.get(key))){
                    if(map.get(key) != null && areaService.get(map.get(key).toString())!=null){
                        map.put(key, areaService.get(map.get(key).toString()).getName());
                    }
                }
            }
        }
        page.setCount(count);
        page.setList(mapList);
        return page;
    }


}
