package com.salpa.model.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.PageHelper;
import com.salpa.common.constant.UserConstants;
import com.salpa.common.core.domain.AjaxResult;
import com.salpa.common.core.domain.entity.SysUser;
import com.salpa.common.utils.SecurityUtils;
import com.salpa.model.domain.ProjectModelInfo;
import com.salpa.model.mapper.ModelMapper;
import com.salpa.model.service.ModelService;
import com.salpa.system.domain.SysUserRole;
import com.salpa.system.mapper.SysUserMapper;
import com.salpa.system.mapper.SysUserRoleMapper;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.*;

@Service
public class ModelServiceImpl implements ModelService {


    @Autowired
    private ModelMapper modelMappper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 获取当前用户项目模型列表
     * @author zhuff
     * @return
     */
    @Override
    public List<ProjectModelInfo> getList(Integer pageNum,Integer pageSize,String projectName) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        List<String> projectList = new ArrayList<>();
        if (!user.isAdmin()){
            /*获取当前用户所对应项目id*/
            String projectIds = modelMappper.getProjectIds(user.getUserId());
            if (projectIds != null && projectIds != "") {
                projectList = Arrays.asList(projectIds.split(","));
            }
        }
        PageHelper.startPage(pageNum,pageSize);
        List<ProjectModelInfo> list = modelMappper.getList(projectList,projectName);
        /*添加项目人员*/
        for (ProjectModelInfo projectModelInfo : list) {
            List<SysUserRole> userRole = sysUserRoleMapper.getUserRole();
            List<Long> userList = new ArrayList<>();
            List<String> userNameList = new ArrayList<>();
            for (SysUserRole sysUserRole : userRole) {
                String projectIds = sysUserRole.getProjectIds();
                if (projectIds!=null){
                    String[] split = projectIds.split(",");
                    for (String projectId : split) {
                        if (projectId.equals(projectModelInfo.getProjectId().toString())){
                            userList.add(sysUserRole.getUserId());
                            userNameList.add(sysUserMapper.selectUserById(sysUserRole.getUserId()).getUserName());
                        }
                    }
                }
            }
            projectModelInfo.setUserIds(userList.toArray(new Long[userList.size()]));
            projectModelInfo.setUserNames(userNameList.toArray(new String[userNameList.size()]));
        }
        return list;
    }

    /**
     * 校验项目模型名称是否唯一
     * @author zhuff
     * @param projectName
     * @return
     */
    @Override
    public String checkProjectNameUnique(String projectName) {
        int count = modelMappper.checkProjectNameUnique(projectName);
        if (count > 0)
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 新增项目模型
     * @author zhuff
     * @param projectModelInfo
     * @return
     */
    @Override
    public int addProject(ProjectModelInfo projectModelInfo) throws IOException {
        InputStream inputStream = new ClassPathResource("empty.json").getInputStream();
        String json = IOUtils.toString(inputStream, "UTF-8");
        Map map = JSON.parseObject(json);
        map.put("name",projectModelInfo.getProjectName());
        map.put("describe",projectModelInfo.getProjectDescription());
        projectModelInfo.setJsonFile(JSONObject.toJSONString(map));
        /*新增项目模型*/
        int i = modelMappper.addProject(projectModelInfo);
        /*获取新增项目模型的id*/
        Integer projectId = projectModelInfo.getProjectId();
        /*为用户添加项目权限*/
        Long[] userIds = projectModelInfo.getUserIds();
        for (Long userId : userIds) {
            /*获取已有项目权限*/
            String projectIds = modelMappper.getProjectIds(userId);
            if (projectIds != null && !"".equals(projectIds)){
                projectIds += ","+ projectId;
                modelMappper.updateProjectIds(projectIds,userId);
            } else {
                if ("".equals(projectIds)) {
                    projectIds = projectId.toString();
                    modelMappper.updateProjectIds(projectIds,userId);
                } else {
                    projectIds = projectId.toString();
                    modelMappper.addProjectIds(projectIds,userId);
                }
            }
        }
        return i;
    }

    /**
     * 删除项目模型
     * @author zhuff
     * @param projectId
     * @return
     */
    @Override
    public int deleteProject(Integer projectId) {
        return modelMappper.deleteProject(projectId);
    }

    /**
     * 修改项目模型
     * @author zhuff
     * @param projectModelInfo
     * @return
     */
    @Override
    public int updateProject(ProjectModelInfo projectModelInfo) {
        /*读取json,修改名称及描述*/
        ProjectModelInfo byId = modelMappper.getById(projectModelInfo.getProjectId());
        Map map = JSON.parseObject(byId.getJsonFile());
        map.put("name",projectModelInfo.getProjectName());
        map.put("describe",projectModelInfo.getProjectDescription());
        projectModelInfo.setJsonFile(JSONObject.toJSONString(map));
        /*修改项目模型*/
        int i = modelMappper.updateProject(projectModelInfo);
        /*删除该项目原有人员*/
        List<SysUserRole> userRole = sysUserRoleMapper.getUserRole();
        for (SysUserRole sysUserRole : userRole) {
            List<String> projectList = new ArrayList<>(Arrays.asList(sysUserRole.getProjectIds().split(",")));
            if (projectList.size()>0){
                // 获取迭代器
                Iterator<String> it = projectList.iterator();
                while(it.hasNext()){
                    String str = it.next();
                    if(projectModelInfo.getProjectId().toString().equals(str)){
                        it.remove();
                    }
                }
            }
            String projectIds = "";
            if (projectList.size()>0){
                for (String project : projectList) {
                    if (projectIds == ""){
                        projectIds = project;
                    } else {
                        projectIds += "," + project;
                    }
                }
            }
            modelMappper.updateProjectIds(projectIds,sysUserRole.getUserId());
        }
        /*添加项目现有人员*/
        Long[] userIds = projectModelInfo.getUserIds();
        for (Long userId : userIds) {
            /*获取已有项目权限*/
            String projectIds = modelMappper.getProjectIds(userId);
            if (projectIds != null && !"".equals(projectIds)){
                projectIds += ","+ projectModelInfo.getProjectId();
                modelMappper.updateProjectIds(projectIds,userId);
            } else {
                if ("".equals(projectIds)) {
                    projectIds = projectModelInfo.getProjectId().toString();
                    modelMappper.updateProjectIds(projectIds,userId);
                } else {
                    projectIds = projectModelInfo.getProjectId().toString();
                    modelMappper.addProjectIds(projectIds,userId);
                }
            }
        }
        return i;
    }

    /**
     * 根据id获取项目模型
     * @author zhuff
     * @param projectId
     * @return
     */
    @Override
    public ProjectModelInfo getById(Integer projectId) {
        ProjectModelInfo projectModelInfo = modelMappper.getById(projectId);
        List<SysUserRole> userRole = sysUserRoleMapper.getUserRole();
        List<Long> userList = new ArrayList<>();
        for (SysUserRole sysUserRole : userRole) {
            String projectIds = sysUserRole.getProjectIds();
            if (projectIds!=null){
                String[] split = projectIds.split(",");
                for (String project : split) {
                    if (project.equals(projectModelInfo.getProjectId().toString())){
                        userList.add(sysUserRole.getUserId());
                    }
                }
            }
        }
        projectModelInfo.setUserIds(userList.toArray(new Long[userList.size()]));
        return projectModelInfo;
    }

    /**
     * 获取所有用户
     * @return
     */
    @Override
    public List<Map<String, Object>> getUserList() {
        return modelMappper.getUserList();
    }


    /**
     * 更新jsonFile
     * @param projectModelInfo
     * @return
     */
    @Override
    public int updateJsonFile(ProjectModelInfo projectModelInfo) {
        return modelMappper.updateJsonFile(projectModelInfo);
    }

    /**
     * 测试连接数据库
     * @param map
     * @return
     */
    @Override
    public AjaxResult connectDataSource(Map map) {
        Properties info = new Properties();
        info.put("user" ,map.get("username"));
        info.put("password" ,map.get("password"));
        try {
            Class.forName(map.get("driverName").toString());
            System.out.println("驱动加载成功");
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return AjaxResult.error("驱动加载失败");
        }
        try {
            DriverManager.getConnection(map.get("url").toString(), info);
            return AjaxResult.success("数据库连接成功");
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return AjaxResult.error("数据库连接失败");
        }
    }

    /**
     * 执行ddl语句
     * @param map
     * @return
     */
    @Override
    public AjaxResult executeSql(Map map) {
        Properties info = new Properties();
        info.put("user" ,map.get("username"));
        info.put("password" ,map.get("password"));
        try {
            Class.forName(map.get("driverName").toString());
            System.out.println("驱动加载成功");
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            System.out.println("驱动加载失败");
        }
        try {
            Connection connection = DriverManager.getConnection(map.get("url").toString(), info);
            String[] tableTypes = {"TABLE"};
            ResultSet tablesResult = connection.getMetaData()
                    .getTables(connection.getCatalog(), connection.getSchema(), null, tableTypes);
            while (tablesResult.next()) {
                return AjaxResult.error("该数据库已存在数据表,不能再次执行");
            }
            Statement statement = connection.createStatement();
            String[] sqls = map.get("sql").toString().split(";");
            for (String sql : sqls) {
                if (!sql.equals("\n\n") && !sql.equals("\n")) {
                    statement.executeUpdate(sql);
                }
            }
            statement.close();
            tablesResult.close();
            connection.close();
            return AjaxResult.success("执行成功");
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }
}
