package com.goer.project.model.modelEntity.controller;

import java.io.File;
import java.util.*;

import com.goer.common.chiner.model.TableEntity;
import com.goer.common.command.AbstractDBCommand;
import com.goer.common.command.ExecResult;
import com.goer.common.command.impl.DBReverseGetAllTablesListImpl;
import com.goer.common.command.impl.PingLoadDriverClassImpl;
import com.goer.common.utils.StringUtils;
import com.goer.project.model.modelDbs.domain.ModelDbs;
import com.goer.project.model.modelDbs.service.IModelDbsService;
import com.goer.project.model.modelField.domain.ModelField;
import com.goer.project.model.modelField.service.IModelFieldService;
import com.goer.project.model.modelProject.domain.ModelProject;
import com.goer.project.model.modelProject.service.IModelProjectService;
import com.goer.project.system.user.domain.User;
import lombok.SneakyThrows;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.goer.framework.aspectj.lang.annotation.Log;
import com.goer.framework.aspectj.lang.enums.BusinessType;
import com.goer.project.model.modelEntity.domain.ModelEntity;
import com.goer.project.model.modelEntity.service.IModelEntityService;
import com.goer.framework.web.controller.BaseController;
import com.goer.framework.web.domain.AjaxResult;
import com.goer.common.utils.poi.ExcelUtil;
import com.goer.framework.web.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
import com.goer.framework.config.GoerConfig;

/**
 * 数据Controller
 * 
 * @author goer
 * @date 2022-01-17
 */
@Controller
@RequestMapping("/model/modelEntity")
public class ModelEntityController extends BaseController
{
    private String prefix = "model/modelEntity";

    @Autowired
    private IModelProjectService modelProjectService;

    @Autowired
    private IModelEntityService modelEntityService;

    @Autowired
    private IModelFieldService modelFieldService;

    @Autowired
    private IModelDbsService modelDbsService;

    @RequiresPermissions("model:modelEntity:view")
    @GetMapping()
    public String modelEntity(@RequestParam(name = "projectId", required = false, defaultValue = "0") Long projectId,
                              ModelMap mmap)
    {
        ModelProject modelProject = modelProjectService.selectModelProjectById(projectId);
        mmap.put("modelProject", modelProject);
        return prefix + "/modelEntity";
    }

    /**
     * 查询数据列表
     */
    @RequiresPermissions("model:modelEntity:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(ModelEntity modelEntity)
    {
        startPage();
        List<ModelEntity> list = modelEntityService.selectModelEntityList(modelEntity);
        return getDataTable(list);
    }

    /**
     * 导出数据列表
     */
    @RequiresPermissions("model:modelEntity:export")
    @Log(title = "数据", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(ModelEntity modelEntity)
    {
        List<ModelEntity> list = modelEntityService.selectModelEntityList(modelEntity);
        ExcelUtil<ModelEntity> util = new ExcelUtil<ModelEntity>(ModelEntity.class);
        return util.exportExcel(list, "数据数据");
    }

    /**
     * 新增数据
     */
    @GetMapping("/add/{projectId}")
    public String add(@PathVariable("projectId") Long projectId, ModelMap mmap)
    {
        ModelProject modelProject = modelProjectService.selectModelProjectById(projectId);
        mmap.put("modelProject", modelProject);
        return prefix + "/add";
    }

    /**
     * 新增保存数据
     */
    @RequiresPermissions("model:modelEntity:add")
    @Log(title = "数据", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(ModelEntity modelEntity)
    {
//        ModelVersionChanges modelVersionChanges = new ModelVersionChanges();
//        // 模型对象ID
//        modelVersionChanges.setProjectId(modelEntity.getProjectId());
//        // 版本号
//        modelVersionChanges.setVersionId(0L);
//        // 变更区分(entity,field)
//        modelVersionChanges.setChangeType("entity");
//        // 变更类型(add)
//        modelVersionChanges.setChangeOption("add");
//        // 表逻辑名
//        modelVersionChanges.setEntityCode(modelEntity.getEntityCode());
//        // 变更内容
//        modelVersionChanges.setChangeContent("");
//        // 创建者
//        modelVersionChanges.setCreateBy(getLoginName());
//        modelVersionChangesService.insertModelVersionChanges(modelVersionChanges);

        modelEntity.setVersionId(0L);
        modelEntity.setParentVersionId(0L);
        modelEntity.setCreateBy(getLoginName());
        return toAjax(modelEntityService.insertModelEntity(modelEntity));
    }


    /**
     * 新增数据
     */
    @GetMapping("/copy/{id}")
    public String copy(@PathVariable("id") Long id, ModelMap mmap)
    {
        ModelEntity modelEntity = modelEntityService.selectModelEntityById(id);
        ModelProject modelProject = modelProjectService.selectModelProjectById(modelEntity.getProjectId());
        modelProject.setOrgEntityid(id);
        mmap.put("modelProject", modelProject);
        mmap.put("modelEntity", modelEntity);

        return prefix + "/copy";
    }

    /**
     * 新增保存数据
     */
    @RequiresPermissions("model:modelEntity:add")
    @Log(title = "数据", businessType = BusinessType.INSERT)
    @PostMapping("/copy")
    @ResponseBody
    public AjaxResult copySave(ModelEntity modelEntity)
    {

        ModelField condMf = new ModelField();
        condMf.setEntityId(modelEntity.getOrgEntityId());
        List<ModelField> mfs = modelFieldService.selectModelFieldList(condMf);

        modelEntity.setVersionId(0L);
        modelEntity.setParentVersionId(0L);
        modelEntity.setCreateBy(getLoginName());
        for (ModelField mf : mfs) {
            mf.setCreateBy(getLoginName());
        }
        modelEntity.setFields(mfs);
        modelEntityService.copyModelEntity(modelEntity);

        return AjaxResult.success();
    }

    /**
     * 修改数据
     */
    @RequiresPermissions("model:modelEntity:edit")
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap mmap)
    {
        ModelEntity modelEntity = modelEntityService.selectModelEntityById(id);
        mmap.put("modelEntity", modelEntity);
        return prefix + "/edit";
    }

    /**
     * 修改保存数据
     */
    @RequiresPermissions("model:modelEntity:edit")
    @Log(title = "数据", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(ModelEntity modelEntity)
    {
//        if(modelEntity.getVersionId() != null && modelEntity.getVersionId() != 0L) {
//
//        }
        modelEntity.setUpdateBy(getLoginName());
        return toAjax(modelEntityService.updateModelEntity(modelEntity));
    }

    /**
     * 删除数据
     */
    @RequiresPermissions("model:modelEntity:remove")
    @Log(title = "数据", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(modelEntityService.deleteModelEntityByIds(ids));
    }

    /**
     * 排序
     */
    @RequiresPermissions("model:dataType:edit")
    @Log(title = "数据类型", businessType = BusinessType.UPDATE)
    @PostMapping("/sort")
    @ResponseBody
    @SneakyThrows
    public AjaxResult sort(ModelEntity modelEntity)
    {
        modelEntity.setUpdateBy(getLoginName());
        modelEntity.setUpdateTime(new Date());
        return toAjax(modelEntityService.sort(modelEntity));
    }

    @PostMapping("/importTableCheck")
    @ResponseBody
    public AjaxResult importTableCheck(ModelEntity modelEntity) {
        ModelDbs modelDbs = modelDbsService.selectDefaultDbByProjectId(modelEntity.getProjectId());
        if(modelDbs == null) {
            return AjaxResult.error("未配置默认数据库");
        }
        ExecResult ret = new ExecResult(ExecResult.FAILED,"未知错误");
        PingLoadDriverClassImpl ping = new PingLoadDriverClassImpl();
        Map<String, String> argsMap = new HashMap<String, String>();
        argsMap.put(AbstractDBCommand.KEY_DRIVER_CLASS_NAME,modelDbs.getDriverClassName());
        argsMap.put(AbstractDBCommand.KEY_URL,modelDbs.getUrl());
        argsMap.put(AbstractDBCommand.KEY_USERNAME,modelDbs.getUserName());
        argsMap.put(AbstractDBCommand.KEY_PASSWORD,modelDbs.getPassword());
        ret = ping.exec(argsMap);

        if(!ExecResult.SUCCESS.equals(ret.getStatus())) {
            return AjaxResult.error("配置的默认数据库连接失败。");
        }
        return AjaxResult.success();
    }

    /**
     * 从数据库导入
     */
    @RequiresPermissions("model:modelEntity:import")
    @GetMapping("/importTable/{projectId}")
    public String importTable(@PathVariable("projectId") Long projectId, ModelMap mmap)
    {
        ModelDbs modelDbs = new ModelDbs();
        modelDbs.setProjectId(projectId);
        List<ModelDbs> list = modelDbsService.selectModelDbsList(modelDbs);
//        for (Iterator<ModelDbs> iterator = list.listIterator(); iterator.hasNext();) {
//            ModelDbs next = iterator.next();
//            if("Y".equalsIgnoreCase(next.getDefaultDb())) {
//                modelDbs = next;
//                iterator.remove();
//                break;
//            }
//        }
//        list.sort(Comparator.comparing(ModelDbs::getId));
//        list.add(0, modelDbs);

        Collections.sort(list,new Comparator<ModelDbs>(){
                @Override
                public int compare(ModelDbs m1,ModelDbs m2){
                        int i = m2.getDefaultDb().compareTo(m1.getDefaultDb());
                        if(i != 0) {
                            return i;
                        }
                        return Long.compare(m1.getId(), m2.getId().longValue());
                    }
        });
        mmap.put("projectId", projectId);
        mmap.put("modelDbs", list);

        return prefix + "/importTable";
    }

    /**
     * 查询数据库列表
     */
    @RequiresPermissions("model:modelEntity:list")
    @PostMapping("/db/list")
    @ResponseBody
    public TableDataInfo dataList(ModelDbs modelDbs){
        ModelDbs dbs = modelDbsService.selectModelDbsById(modelDbs.getId());
        DBReverseGetAllTablesListImpl reverse = new DBReverseGetAllTablesListImpl();
        Map<String, String> argsMap = new HashMap<String, String>();
        argsMap.put(AbstractDBCommand.KEY_DRIVER_CLASS_NAME,dbs.getDriverClassName());
        argsMap.put(AbstractDBCommand.KEY_URL,dbs.getUrl());
        argsMap.put(AbstractDBCommand.KEY_USERNAME,dbs.getUserName());
        argsMap.put(AbstractDBCommand.KEY_PASSWORD,dbs.getPassword());
        ExecResult ret = reverse.exec(argsMap);
        List<TableEntity> listTable = (List<TableEntity>)ret.getBody();

        List<ModelEntity> retList = new ArrayList<>();
        if(listTable != null && listTable.size() >0) {
            ModelEntity modelEntity = new ModelEntity();
            modelEntity.setProjectId(modelDbs.getProjectId());
            modelEntity.setVersionId(0L);
            List<ModelEntity> listEntity = modelEntityService.selectModelEntityList(modelEntity);

            for (TableEntity t : listTable) {
                boolean existFlag = false;
                for (ModelEntity m : listEntity) {
                    if (t.getDefKey().equalsIgnoreCase(m.getEntityCode())) {
                        existFlag = true;
                        break;
                    }
                }
                if (!existFlag) {
                    ModelEntity ne = new ModelEntity();
                    ne.setEntityCode(t.getDefKey());
                    ne.setEntityName(t.getDefName());
                    retList.add(ne);
                }
            }
        }
        return getDataTable(retList);
    }

    /**
     * 从数据库导入
     */
    @RequiresPermissions("model:modelEntity:import")
    @Log(title = "从数据库导入", businessType = BusinessType.IMPORT)
    @PostMapping("/importTable")
    @ResponseBody
    public AjaxResult importTableSave(ModelEntity modelEntity)
    {
        modelEntity.setCreateBy(getLoginName());
        modelEntity.setCreateTime(new Date());

        return toAjax(modelEntityService.importTable(modelEntity));
    }

    /**
     * 校验表逻辑名唯一性
     */
    @PostMapping("/checkEntityCodeUnique")
    @ResponseBody
    public String checkEntityCodeUnique(ModelEntity modelEntity)
    {
        return modelEntityService.checkEntityCodeUnique(modelEntity);
    }


    /**
     * 下载模板
     */
    @RequiresPermissions("vendor:order:importExpress")
    @GetMapping("/importTemplate")
    @ResponseBody
    public AjaxResult importTemplate() throws Exception {
        ExcelUtil<ModelEntity> util = new ExcelUtil<ModelEntity>(ModelEntity.class);
        String templateFile = GoerConfig.getProfile() + File.separator + "importTables.xlsx";
        return util.exportExcelWithTemplate(null, templateFile);
    }

    /**
     * 导入快递编号文件
     */
    @RequiresPermissions("vendor:order:importExpress")
    @PostMapping("/importExpress")
    @ResponseBody
    @Log(title = "导入表结构文件 ", businessType = BusinessType.INSERT)
    public AjaxResult importExpress(MultipartFile file, Long prjId) {

        try {

            modelEntityService.importTables(file.getInputStream(), prjId);

            return AjaxResult.success();
        } catch (Exception e) {
            return AjaxResult.error(StringUtils.isEmpty(e.getMessage()) ? e.getCause().getMessage() : e.getMessage());
        }
    }

}
