package io.renren.modules.levelManage.controller;

import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;
import io.renren.common.utils.RandomGen;
import io.renren.common.utils.SubString;
import io.renren.modules.levelManage.entity.LevelEntity;
import io.renren.modules.levelManage.entity.ProjectAttributesEntity;
import io.renren.modules.levelManage.service.LevelService;
import io.renren.modules.levelManage.service.ProjectAttributesService;
import io.renren.modules.sys.controller.AbstractController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 
 *
 * @author Noth
 * @email sunlightcs@gmail.com
 * @date 2022-09-17 17:20:39
 */
@RestController
@RequestMapping("/levelManage/projectattributes")
public class ProjectAttributesController extends AbstractController {
    @Autowired
    private ProjectAttributesService projectAttributesService;
    @Autowired
    private LevelService levelService;
    @Value("${cengji}")
    private String schema;


    @RequestMapping("/projectToLevel")
    public R projectToLevel(@RequestParam("id") Long id){
        if(projectAttributesService.countProjectLevel(id).equals("0"))
            return R.ok().put("state",0);
        else {
            Integer tableId=projectAttributesService.selectRootLevel(id);
            return R.ok().put("tableId",tableId).put("state",1);
        }
    }

    @RequestMapping("/getProjectInfoForLevel")
    public R getProjectInfoForLevel()
    {
        List<Map<String,Object>> projects=projectAttributesService.listProjectName();

        for(Map<String,Object> project:projects){
            project.put("disabled",projectAttributesService.countProjectLevel((Long) project.get("id")));
        }
        SubString.subStringList(projects);
        return R.ok().put("data",projects);
    }

    @RequestMapping("/getProjectInfo")
    public R getProjectInfo(@RequestParam("page") Integer page,@RequestParam("size") Integer size)
    {

        List<String> tableCols =projectAttributesService.listCols();
        List<Map<String,Object>> data=projectAttributesService.listData(tableCols,page,size);
        //data是<列名，具体值>的list

        //对bool值需要修改为是/否，否则前端不显示（应该在前端解决，但是做不到，先在后端进行）
        //先获取所有是bool的列，通过遍历list，用列名对所有value修改
        List<String> boolCols=projectAttributesService.listBoolCols();

        for(Map<String,Object> map :data)
        {
            for(String col: boolCols)
            {
                if((boolean) map.get(col))
                {
                    map.put(col,"是");
                }
                else
                    map.put(col,"否");
            }
        }
        SubString.subStringList(data);
        Integer count=projectAttributesService.countProject();
        return R.ok().put("data",data).put("count",count);
    }

    @RequestMapping("/hasProject")
    public R count(){
        int count=projectAttributesService.hasProject(schema);
        return R.ok().put("count",count);
    }

    @RequestMapping("/createTable")
    public R createTable(@RequestBody Map<String,Object> map)
    {
        if(projectAttributesService.hasProject(schema)==1)
            return R.error().put("msg","项目表格已存在");

        List<Map<String,String>> colName= ( List<Map<String,String>>) map.get("col");
        Long userId = getUserId();

        //无效数据的清洗
        List<Map<String,String>> trueCols=new ArrayList<>();
        for(Map<String,String> item :colName)
        {
            String type = item.get("type");
            String comment = item.get("remark");
            String name = item.get("name");
            if(comment==null)
                comment=name;
            if(name==null && type==null)
                continue;
            if(type==null || name==null)
                return R.error().put("msg","表格属性输入错误");
            HashMap<String,String> temp = new HashMap<>();
            temp.put("name",name);
            temp.put("type",trans(type));
            temp.put("comment",comment);
            trueCols.add(temp);
        }

        //将属性存入project_attribute表中
        for(Map<String,String> attribute: trueCols){
            ProjectAttributesEntity projectAttributesEntity=new ProjectAttributesEntity();
            projectAttributesEntity.setName(attribute.get("name"));
            projectAttributesEntity.setType(attribute.get("type"));
            projectAttributesEntity.setRemark(attribute.get("comment"));
            if(!projectAttributesService.save(projectAttributesEntity))
                return R.error().put("msg","保存失败");
        }

        //利用属性建立project表
        projectAttributesService.createTable(trueCols);
        return R.ok();
    }

    @RequestMapping("/getCols")
    public R getCols()
    {
        //因为实际上给的应该是 字段名、中文名、类型
        List<Map<String,Object>> data=projectAttributesService.listAttribute();

        return R.ok().put("data",data);
    }

    @RequestMapping("/getInfo")
    public R getInfo(@RequestParam("rowId") Long id){
        //获取列，list里面的Map的key为 name,remark,type
        List<Map<String,Object>> data=projectAttributesService.listAttribute();
        //在list里面的Map添加新的key，值为value
        //先获取所有的值
        List<String> tableCols = projectAttributesService.listCols();
        Map<String,Object> valueMap=projectAttributesService.selectById(id,tableCols);
        //在list里面添加上面map的值，存到key为value的对里面
        for (Map<String,Object> item : data)
        {
            item.put("value", String.valueOf(valueMap.get(item.get("name"))));
        }

        SubString.subStringRow(data);
        return R.ok().put("data",data);
    }

    @RequestMapping("/selectByName")
    public R selectByName(@RequestParam("page") Integer page,@RequestParam("limit") Integer limit,
                          @RequestParam("name") String name)
    {
        //获取查询需要的参数
        List<String> tableCols =projectAttributesService.listCols();

        List<Map<String,Object>> data=projectAttributesService.selectByName(tableCols,page,limit,name);
        SubString.subStringList(data);
        Integer count = projectAttributesService.getCountByName(name);
        return R.ok().put("data",data).put("count",count);
    }

    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = projectAttributesService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id){
		ProjectAttributesEntity projectAttributes = projectAttributesService.getById(id);

        return R.ok().put("projectAttributes", projectAttributes);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody Map<String,Object> map) throws ParseException {
        //先抽取属性，形成表结构，然后存进表里，最后返回ok
        //真正需要的字段
        List<Map<String,Object>> trueCols= new ArrayList<>();

        //获取的数据，需要进行处理
        List<Map<String,Object>> cols= (List<Map<String, Object>>) map.get("cols");
        Long uid=getUserId();

        //save没有字段id
        //对cols进行处理，去除没有value的字段，将特定字段：create_user进行修改
        for(Map<String,Object> col :cols)
        {
            if(col.get("cols").equals("name"))
            {
                col.put("value",RandomGen.formatName(col.get("value").toString()));
            }
            else if(col.get("cols").equals("create_user"))
            {
                col.put("value",uid);
            }
            else if(col.get("cols").equals("create_time"))
            {
                col.put("value",new Date());
            }
            else if (col.get("cols").equals("id"))
            {
                continue;
            }
            else if(col.get("type").equals("date"))
            {
                String  str= col.get("value").toString();
                DateFormat format=new SimpleDateFormat("yyyy-MM-dd");
                Date date=format.parse(str);
                col.put("value",date);
            }
            trueCols.add(col);
        }
        //直接通过map进行存储,同时，需要将动态列作为参数传入，在map里面进行动态插入
        projectAttributesService.saveWithCols(trueCols);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody Map<String,Object> map) throws ParseException{

        //先抽取属性，形成表结构，然后存进表里，最后返回ok
        //真正需要的字段
        List<Map<String,Object>> trueCols= new ArrayList<>();

        //获取的数据，需要进行处理
        List<Map<String,Object>> cols= (List<Map<String, Object>>) map.get("cols");
        Long id=Long.valueOf(map.get("id").toString());
        Long uid=getUserId();
        String orginRowName = projectAttributesService.selectProjectNameById(id);

        //和save不同，update有字段id,但是实际上cols中不需要id，id需要作为另外的参数传入
        //对cols进行处理，去除没有value的字段，将特定字段进行修改
        for(Map<String,Object> col :cols)
        {
            if(col.get("cols").equals("name"))
            {
                //cols中的name是处理过的name，因此不需要再次substring
                if(col.get("value").toString().equals(orginRowName.substring(4)))
                {
                    col.put("value",orginRowName);
                }
                else{
                    col.put("value",RandomGen.formatName(col.get("value").toString()));
                }
            }
            else if(col.get("cols").equals("create_user"))
            {
                col.put("value",uid);
            }
            else if(col.get("cols").equals("create_time"))
            {
                col.put("value",new Date());
            }
            else if (col.get("cols").equals("id"))
            {
                continue;
            }
            else if(col.get("type").equals("date"))
            {
                String  str= col.get("value").toString();
                DateFormat format=new SimpleDateFormat("yyyy-MM-dd");
                Date date=format.parse(str);
                col.put("value",date);
            }
            trueCols.add(col);
        }
        //直接存储不可以，因为还是需要进行类的变化,因此需要将动态列作为参数传入，在map里面进行动态插入
        //因为dao里面不一样，所以不能直接用save
        projectAttributesService.updateWithCols(trueCols,id);
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids){
//		projectAttributesService.removeByIds(Arrays.asList(ids));
        projectAttributesService.removeProjectByIds(Arrays.asList(ids));
        List<LevelEntity> enabledLevelList=levelService.getEnabledLevelByProject(Arrays.asList(ids));
        for(LevelEntity levelEntity:enabledLevelList){
            levelEntity.setProjectId(0L);
            levelEntity.setEnabled(0);
        }
        if(!levelService.saveOrUpdateBatch(enabledLevelList))
        {
            return R.error().put("msg","层级状态修改失败");
        }
        return R.ok();
    }

    @RequestMapping("/dropProject")
    public R RequestMapping(){
        projectAttributesService.dropProject();
        return R.ok();
    }

    private String trans(String type)
    {
        if(type.equals("varchar"))
            type="varchar(255)";
        return type;
    }

    /**
     * 获取第一层级(项目)的信息，包括id和名称，本次获取应该在页面刷新时进行，并且此时获取的数据仅有页面左侧区域
     * @return
     */
    @RequestMapping("/getAllProject")
    public R getAllProject(){
        int count=projectAttributesService.hasProject(schema);
        if(count==0)
            return R.error("暂未设定项目属性");
        else {
            return getProjectInfoForLevel();
        }
    }

    /**
     * 获取目标用户创建的项目的信息
     */
    @RequestMapping("/getProjectWithUid")
    public R getProjectWithUid(@RequestParam Long uid){
        int count=projectAttributesService.hasProject(schema);
        if(count==0)
            return R.error("暂未设定项目属性");
        else {
            List<Map<String,Object>> projects=projectAttributesService.listProjectByUid(uid);

            for(Map<String,Object> project:projects){
                project.put("disabled",projectAttributesService.countProjectLevel((Long) project.get("id")));
            }
            SubString.subStringList(projects);
            return R.ok().put("data",projects);
        }
    }

}
