package cn.feast.coding.controller.generator;


import cn.feast.coding.controller.BaseController;
import cn.feast.coding.model.generator.*;
import cn.feast.coding.service.generator.*;
import cn.feast.coding.tools.*;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Controller
@RequestMapping("/project")
public class ProjectController extends BaseController {
    private Logger logger = LoggerFactory.getLogger(ProjectController.class);
    @Autowired
    private ProjectService projectService;
    @Autowired
    private DataSourceService dataSourceService;
    @Autowired
    private TableService tableService;
    @Autowired
    private ColunmService colunmService;
    @Autowired
    private GeneratorService generatorService;
    @Autowired
    private PageTemplateService pageTemplateService;
    @Autowired
    private ModuleProjectService moduleProjectService;

    /**
     * 项目列表
     *
     * @param project
     * @param curPage
     * @param pageSize
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "/list")
    public String list(Project project, Integer curPage, Integer pageSize, ModelMap model, HttpServletRequest request) {
        PageInfo<Project> pageInfo = projectService.queryPage(project, pageNum(curPage), pageSize(request, pageSize));
        model.put("pages", pageInfo);
        model.put("project", project);
        return "project/project_list";
    }

    /**
     * 新增项目
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String add(ModelMap model) {
        List<DataSource> dataSourceList = dataSourceService.queryAll();
        List<PageTemplate> pageTemplateList = pageTemplateService.queryByAll();
        model.put("dataSourceList", dataSourceList);
        model.put("pageTemplateList", pageTemplateList);
        return "project/project_add";
    }

    /**
     * 新增项目
     *
     * @param project
     * @param request
     * @param model
     * @return
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String add(Project project, HttpServletRequest request, ModelMap model) {
        projectService.save(project);
        model.put("flag", 1);
        return "project/project_add";
    }

    /**
     * 更新项目
     *
     * @param project
     * @param model
     * @return
     */
    @RequestMapping(value = "/update", method = RequestMethod.GET)
    public String update(Project project, ModelMap model) {
        project = projectService.queryById(project.getId());
        project.setDataSource(dataSourceService.queryById(project.getDataSourse()));
        List<PageTemplate> pageTemplateList = pageTemplateService.getPage(project.getTemplateType());
        model.put("pageTemplateList", pageTemplateList);
        model.put("project", project);
        return "project/project_edit";
    }

    /**
     * 更新项目
     *
     * @param project
     * @param request
     * @param model
     * @return
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String update(Project project, HttpServletRequest request, ModelMap model) {
        projectService.update(project);
        model.put("flag", 1);
        return "project/project_edit";
    }

    /**
     * 删除项目
     *
     * @param project
     */
    @RequestMapping(value = "/delete", method = RequestMethod.GET)
    @ResponseBody
    public void delete(Project project) {
        //删除项目关联的表和字段数据
        deleteProjectRelatedData(project);
        projectService.deleteById(project.getId());
    }

    /**
     * 导入数据表数据
     *
     * @param project
     * @return
     */
    @RequestMapping(value = "/importData", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult importData(Project project) {
        Date start = new Date();
        JsonResult jsonResult = new JsonResult();
        jsonResult.setState(JsonResult.SUCCESS);
        //获取项目信息
        project = projectService.queryById(project.getId());
        if (project == null) {
            jsonResult.setState(JsonResult.ERROR);
            jsonResult.setMessage("项目信息不存在");
            return jsonResult;
        }
        //获取项目数据源
        if (project.getDataSourse() == null) {
            jsonResult.setState(JsonResult.ERROR);
            jsonResult.setMessage("项目未配置数据源");
            return jsonResult;
        }
        DataSource dataSource = dataSourceService.queryById(project.getDataSourse());
        //测试数据源能否连接数据库
        boolean res = dataSourceService.testConnection(dataSource);
        if (!res) {
            jsonResult.setState(JsonResult.ERROR);
            jsonResult.setMessage("数据库连接失败");
            return jsonResult;
        }
        //删除项目关联的表和字段数据
        deleteProjectRelatedData(project);
        //加载表数据
        List<Table> tableList = DataBaseTools.getTables(dataSource);
        for (Table table : tableList) {
            table.setProjectId(project.getId());
        }
        //批量插入表信息
        tableService.saveByBatch(tableList);
        List<Table> tList = tableService.queryByProject(project.getId());
        List<Colunm> allColunmList = new ArrayList<>();
        for(Table table : tList){
            //加载字段数据
            List<Colunm> colunmList = DataBaseTools.readData(dataSource, table.getTableName());
            for (Colunm colunm : colunmList) {
                colunm.setTableId(table.getId());
                //editStyle编辑方式：1.输入框 2.密码框 3.下拉框 4.复选框 5.单选框 6.文本域。默认为:输入框
                colunm.setEditStyle(1);
                colunm.setIsShowed(Contants.COLUNM_IS_SHOWED);

            }
            allColunmList.addAll(colunmList);
        }
        //批量插入字段信息
        colunmService.saveByBatch(allColunmList);
        logger.debug("导入数据表耗时：" + (new Date().getTime() - start.getTime()));
        return jsonResult;
    }

    /**
     * 生成代码
     *
     * @param project
     * @param request
     * @return
     */
    @RequestMapping(value = "/generate", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult generate(Project project, HttpServletRequest request) {
        JsonResult jsonResult = new JsonResult();
        jsonResult.setState(JsonResult.SUCCESS);
        List<Table> tableList = tableService.queryByProject(project.getId());
        if (tableList.size() == 0) {
            jsonResult.setState(JsonResult.ERROR);
            jsonResult.setMessage("项目下没有表数据，请先导入数据库");
        }
        try {
            generatorService.generator(project, request);
        } catch (Exception e) {
            jsonResult.setState(JsonResult.ERROR);
            jsonResult.setMessage("错误：" + e);
            e.printStackTrace();
        }
        return jsonResult;
    }

    /**
     * 下载代码检查
     *
     * @param project
     * @param request
     * @return
     */
    @RequestMapping(value = "/check", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult check(Project project, HttpServletRequest request) {
        project = projectService.queryById(project.getId());
        JsonResult jsonResult = new JsonResult();
        jsonResult.setState(JsonResult.SUCCESS);
        String downloadPath = request.getSession().getServletContext().getRealPath("/zip") + "/" + project.getProjectName() + ".zip";
        File file = new File(downloadPath);
        if (!file.exists()) {
            jsonResult.setState(JsonResult.ERROR);
            jsonResult.setMessage("生成代码后，再进行下载操作");
        }
        return jsonResult;
    }

    @RequestMapping(value = "/getPage", method = RequestMethod.GET)
    @ResponseBody
    public JsonResult getPage(String templateType, HttpServletRequest request) {
        JsonResult jsonResult = new JsonResult();
        jsonResult.setState(JsonResult.SUCCESS);
        try {
            List<PageTemplate> pageList = pageTemplateService.getPage(templateType);
            jsonResult.setData(pageList);
        }catch (Exception e){
            jsonResult.setState(JsonResult.ERROR);
            jsonResult.setMessage("服务器错误");
        }
        return jsonResult;
    }

    /**
     * 下载代码
     *
     * @param project
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public HttpServletResponse download(Project project, HttpServletRequest request, HttpServletResponse response) {
        project = projectService.queryById(project.getId());
        String downloadPath = request.getSession().getServletContext().getRealPath("/zip") + "/" + project.getProjectName() + ".zip";
        File file = new File(downloadPath);
        return ZipTools.downloadZip(file, response);
    }

    private void deleteProjectRelatedData(Project project) {
        //删除项目关联的表和字段数据
        colunmService.deleteProjectRelatedData(project.getId());
        tableService.deleteProjectRelatedData(project.getId());
        //删除项目关联的功能模块数据
        moduleProjectService.deleteProjectRelatedData(project.getId());
    }
}
