/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springblade.common.utils.SnowFlakeUtil;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.manager.dto.FormElementDTO;
import org.springblade.manager.dto.WbsFormElementDTO2;
import org.springblade.manager.entity.WbsFormElement;
import org.springblade.manager.excel.WbsExcelBatchUtil;
import org.springblade.manager.excel.WbsFormElementBatchExcel;
import org.springblade.manager.excel.WbsFormElementExcel;
import org.springblade.manager.mapper.WbsFormElementMapper;
import org.springblade.manager.service.IWbsFormElementService;
import org.springblade.manager.service.IWbsTreeService;
import org.springblade.manager.vo.WbsFormElementVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * wbs表单元素 服务实现类
 *
 * @author liuyc
 * @since 2022-04-27
 */
@Service
@AllArgsConstructor
public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMapper, WbsFormElement> implements IWbsFormElementService {

    private final WbsFormElementMapper wbsFormElementMapper;


    @Override
    public IPage<WbsFormElementVO> selectWbsFormElementPage(IPage<WbsFormElementVO> page, WbsFormElementVO wbsFormElement) {
        return page.setRecords(baseMapper.selectWbsFormElementPage(page, wbsFormElement));
    }

    @Override
    public boolean addFormElement(WbsFormElement wbsFormElement) {
        int insert1 = baseMapper.insert(wbsFormElement);
        if (insert1 > 0) {
            return true;
        }
        return false;
    }

    @Override
    public Boolean selectElementsById(List<WbsFormElement> wbsFormElementList) {
        List<Long> ids = new ArrayList<>();
        for (WbsFormElement wbsFormElement : wbsFormElementList) {
            Long id = wbsFormElement.getId();
            ids.add(id);
        }
        List<WbsFormElement> wbsFormElements = baseMapper.selectBatchIds(ids);

        if ((wbsFormElements).equals(wbsFormElementList)) {
            return false;
        }
        return true;
    }

    @Override
    public Boolean initTable(List<WbsFormElement> elementList, String tableName) {
        String sql = createSQL(elementList);
        //建表
        Integer row = wbsFormElementMapper.createTable(sql, tableName);
        if (row >= 0) {
            return true;
        }
        return false;
    }

    private String createSQL(List<WbsFormElement> elementList) {
        StringBuffer sbr = new StringBuffer();
        for (WbsFormElement wbsFormElement : elementList) {
            //获取字段名、类型、长度
            String fieldNameKey = wbsFormElement.getEKey();
            String fieldType = judgeDataType(wbsFormElement.getEType());
            String fieldLength = String.valueOf(wbsFormElement.getELength());
            sbr.append("" + fieldNameKey + "");
            if ("varchar".equals(fieldType)) {
                sbr.append(" " + fieldType + "(" + fieldLength + ") ,\n");
            } else if ("bigint".equals(fieldType)) {
                sbr.append(" " + fieldType + "(" + fieldLength + ") ,\n");
            } else if ("decimal".equals(fieldType)) {
                sbr.append(" " + fieldType + "(" + fieldLength + ") ,\n");
            } else if ("datetime".equals(fieldType)) {
                sbr.append(" " + fieldType + "(" + fieldLength + ") ,\n");
            }
        }
        return String.valueOf(sbr);
    }

    /**
     * 判断类型
     */
    private String judgeDataType(Integer type) {
        switch (type) {
            case 1:
                return "varchar";
            case 2:
                return "bigint";
            case 3:
                return "decimal";
            case 4:
                return "datetime";
            default:
                return "varchar";
        }
    }


    @Override
    public List<WbsFormElement> selectElementListByFid(String tableId) {
        QueryWrapper<WbsFormElement> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("f_id", tableId);
        List<WbsFormElement> wbsFormElements = baseMapper.selectList(queryWrapper);
        return wbsFormElements;
    }

    @Override
    public void importElement(List<WbsFormElementExcel> data, Boolean isCovered, String tableId) {
        List<WbsFormElement> list = new ArrayList<>();
        data.forEach(excel -> {
            WbsFormElement wbsFormElement = new WbsFormElement();
            wbsFormElement.setEName(excel.getElementName());
            wbsFormElement.setEType(Integer.valueOf(excel.getElementType()));
            wbsFormElement.setELength(Integer.valueOf(excel.getElementLength()));
            wbsFormElement.setEAllowDeviation(excel.getElementAllowDeviation());
            wbsFormElement.setEInspectionMethod(excel.getElementInspectionMethod());
            wbsFormElement.setFId(tableId);
            list.add(wbsFormElement);
        });
        if (isCovered) {
            this.saveOrUpdateBatch(list);
        } else {
            this.saveBatch(list);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R saveAndSyn(WbsFormElement wbsFormElement, String tableName) {
        //新增元素字段
        //查询当前元素表中元素的最后一个key_?值
        QueryWrapper<WbsFormElement> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("f_id", wbsFormElement.getFId());
        List<WbsFormElement> wbsFormElements = baseMapper.selectList(queryWrapper);
        String substring = "";
        List<String> eKeyNum = new ArrayList<>();
        if (wbsFormElements.size() > 0) {
            for (WbsFormElement formElement : wbsFormElements) {
                String eKey = formElement.getEKey();
                substring = eKey.split("_")[1];
            }
            if (StringUtils.isNotEmpty(substring)) {
                long newFiled = Long.parseLong(substring) + 1;
                String substring1 = "key_" + newFiled;
                eKeyNum.add(substring1);
                if (wbsFormElement.getEType() == 4) {
                    wbsFormElement.setELength(0);
                }
            }
            wbsFormElement.setEKey(eKeyNum.get(eKeyNum.size() - 1));
        } else {
            wbsFormElement.setEKey("key_1");
        }
        String newName = wbsFormElement.getEKey();
        //同步
        StringBuilder sbr1 = new StringBuilder();
        String fieldType = judgeDataType(wbsFormElement.getEType());
        if ("varchar".equals(fieldType)) {
            if (wbsFormElement.getELength() > 1000 || wbsFormElement.getELength() < 10) {
                return R.fail("请输入正确的字符串长度,范围为10-1000");
            } else {
                baseMapper.insert(wbsFormElement);
                sbr1.append(" ").append(fieldType).append("(").append(wbsFormElement.getELength()).append(")");
                String sql = newName + " " + sbr1;
                baseMapper.alterAddFiled(sql, tableName);
                return R.data(wbsFormElement, "操作成功");
            }
        } else if ("bigint".equals(fieldType)) {
            if (wbsFormElement.getELength() > 255 || wbsFormElement.getELength() < 10) {
                return R.fail("请输入正确的整数长度,范围为10-255");
            } else {
                baseMapper.insert(wbsFormElement);
                sbr1.append(" ").append(fieldType).append("(").append(wbsFormElement.getELength()).append(")");
                String sql = newName + " " + sbr1;
                baseMapper.alterAddFiled(sql, tableName);
                return R.data(wbsFormElement, "操作成功");
            }
        } else if ("decimal".equals(fieldType)) {
            if (wbsFormElement.getELength() > 65 || wbsFormElement.getELength() < 10) {
                return R.fail("请输入正确的小数长度,范围为10-65");
            } else {
                baseMapper.insert(wbsFormElement);
                sbr1.append(" ").append(fieldType).append("(").append(wbsFormElement.getELength()).append(")");
                String sql = newName + " " + sbr1;
                baseMapper.alterAddFiled(sql, tableName);
                return R.data(wbsFormElement, "操作成功");
            }
        } else if ("datetime".equals(fieldType)) {
            baseMapper.insert(wbsFormElement);
            sbr1.append(" ").append(fieldType).append("(").append(0).append(")");
            String sql = newName + " " + sbr1;
            baseMapper.alterAddFiled(sql, tableName);
            return R.data(wbsFormElement, "操作成功");
        }
        return R.fail("操作失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAndSyn(String ids, String eKey, String tableName) {
        deleteLogic(Func.toLongList(ids));
        //删除前判断是否存在该key
        int row = baseMapper.judgeFiled(eKey, tableName);
        if (row > 0) {
            //同步删除实体表字段
            baseMapper.deleteTableFiled(eKey, tableName);
        }
        return true;
    }

    @Override
    public String updateAndSyn(List<WbsFormElement> wbsFormElementList, String initTableName) {
        QueryWrapper<WbsFormElement> queryWrapper = new QueryWrapper<>();
        String fId = "";
        for (WbsFormElement wbsFormElement : wbsFormElementList) {
            fId = wbsFormElement.getFId();
        }
        queryWrapper.eq("f_id", fId);
        List<WbsFormElement> wbsFormElements = baseMapper.selectList(queryWrapper);
        for (WbsFormElement wbsFormElement : wbsFormElements) {
            String eKey = wbsFormElement.getEKey();
            Integer eLength = wbsFormElement.getELength();
            String eType = judgeDataType(wbsFormElement.getEType());
            if (eType.equals("bigint") && (eLength > 255 || eLength < 10)) {  //整数
                return "2";
            } else if (eType.equals("varchar") && (eLength > 1000 || eLength < 10)) {  //字符串
                return "1";
            } else if (eType.equals("decimal") && (eLength > 65 || eLength < 10)) {  //小数
                return "3";
            }
            try {
                baseMapper.updateFiledType(initTableName, eKey, eType, eLength);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "0";
    }

    @Override
    public List<WbsFormElementDTO2> findWbsTreeTableSameLevel(String parentId) {
        List<WbsFormElementDTO2> trees = baseMapper.selectWbsTreeTableListByParentId(parentId);
        return trees;
    }

    @Override
    public boolean wbsTreeTableSort(List<WbsFormElementDTO2> wbsTreeDTO) {
        int number = 1;
        for (WbsFormElementDTO2 wbsTree : wbsTreeDTO) {
            wbsTree.setSort(number);
            //修改sort
            baseMapper.updateSortById(wbsTree.getId(), wbsTree.getSort());
            number++;
        }
        return true;
    }

    @Override
    public WbsFormElementVO getDetailById(WbsFormElement wbsFormElement) {
        WbsFormElementVO detail = baseMapper.selectDetailById(wbsFormElement.getId());
        return detail;
    }

    @Override
    public void importElement2(List<WbsFormElementBatchExcel> data, Boolean isCovered, String tableId) {
        //TODO
    }


}
