package com.yeejoin.amos.boot.module.common.biz.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.module.common.api.dto.DynamicFormInstanceDto;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormColumn;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormInstance;
import com.yeejoin.amos.boot.module.common.api.mapper.DynamicFormInstanceMapper;
import com.yeejoin.amos.boot.module.common.api.service.IDynamicFormInstanceService;

/**
 * 动态表单实例表服务实现类
 *
 * @author system_generator
 * @date 2021-07-06
 */
@Service
public class DynamicFormInstanceServiceImpl extends BaseService<DynamicFormInstanceDto, DynamicFormInstance, DynamicFormInstanceMapper> implements IDynamicFormInstanceService {

    @Autowired
    Sequence sequence;

    @Autowired
    DynamicFormColumnServiceImpl dynamicFormColumnService;

    @Autowired
    DynamicFormInstanceMapper dynamicFormInstanceMapper;

    @Autowired
    HttpServletRequest request;

   private static final String QUERYSTRATEGY= "queryStrategy";
    private static final String FIELDCODE= "fieldCode";

    /**
     * 分页查询
     */
    public Page<DynamicFormInstanceDto> queryForDynamicFormInstancePage(Page<DynamicFormInstanceDto> page) {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<DynamicFormInstanceDto> queryForDynamicFormInstanceList() {
        return this.queryForList("", false);
    }


    public List<DynamicFormInstanceDto> queryByCalledId(Long instanceId) {
        return this.queryForList(null, false, instanceId);
    }

    public List<DynamicFormInstanceDto> listByCalledId(Long instanceId) {
        return this.baseMapper.selectListByCalledId(instanceId);
    }

    public List<DynamicFormInstanceDto> listBySeqnum(Long instanceId) {
        return this.baseMapper.listBySeqnum(instanceId);
    }

    public Long commonSave(String groupCode, Map<String, Object> model) {
        Long instanceId = sequence.nextId();
        List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
        List<DynamicFormInstance> instances = columns.stream().map(column -> {
            DynamicFormInstance instance = new DynamicFormInstance();
            buildFormInstanceData(instanceId, model, column, instance);
            return instance;
        }).collect(Collectors.toList());
        if (!instances.isEmpty()) {
            this.saveBatch(instances);
        }
        model.put("instanceId", instanceId);
        model.put("groupCode", groupCode);
        return instanceId;
    }

    private void buildFormInstanceData(Long instanceId, Map<String, Object> map, DynamicFormColumn column, DynamicFormInstance formInstance) {
        fillFormInstanceData(instanceId, map, column, formInstance, sequence.nextId());
    }

    private void fillFormInstanceData(Long instanceId, Map<String, Object> map, DynamicFormColumn column, DynamicFormInstance formInstance, long l) {
        Bean.copyExistPropertis(column, formInstance);
        formInstance.setAppKey(RequestContext.getAppKey());
        formInstance.setInstanceId(instanceId);
        formInstance.setSequenceNbr(l);
        formInstance.setFormColumnId(column.getSequenceNbr());
        formInstance.setFieldValue(map.get(column.getFieldCode()) != null ? map.get(column.getFieldCode()).toString() : "");
    }

    public Map<String, Object> getOneMap(Long instanceId, String groupCode) {
        Map<String, Object> optionListMap = new HashMap<>();
        List<DynamicFormInstance> list = this.queryByInstanceId(instanceId);
        if (!CollectionUtils.isEmpty(list)) {
            List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
            Map<String, Object> instanceMap = Bean.listToMap(list, FIELDCODE, "fieldValue", DynamicFormInstance.class);
            for (DynamicFormColumn optionModel : columns) {
                Optional<DynamicFormInstance> first = list.stream().filter(i -> i.getFieldCode().equals(optionModel.getFieldCode())).findFirst();
                if (first.isPresent()){
                    DynamicFormInstance dyFormInstance =
                            first.get();
                    instanceMap.put(optionModel.getFieldCode(), instanceMap.get(optionModel.getFieldCode()));
                    if ("radio,select,treeSelect".contains(optionModel.getFieldType())) {
                        instanceMap.put(optionModel.getFieldCode() + "Label", dyFormInstance.getFieldValueLabel());
                    }
                }
            }
            optionListMap.putAll(instanceMap);
            optionListMap.put("instanceId", instanceId);
            optionListMap.put("createTime", list.iterator().next().getRecDate());
            optionListMap.put("groupCode", groupCode);
        }
        return optionListMap;
    }

    private List<DynamicFormInstance> queryByInstanceId(Long instanceId) {
        LambdaQueryWrapper<DynamicFormInstance> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DynamicFormInstance::getInstanceId, instanceId);
        return this.baseMapper.selectList(wrapper);
    }

    public IPage<Map<String, Object>> pageList(int current, int size, String groupCode) {
        Map<String, String> params = this.getRequestParamMap();
        List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
        Map<String, Object> fieldCodes = Bean.listToMap(columns, FIELDCODE, QUERYSTRATEGY, DynamicFormColumn.class);
        Page<Map<String, Object>> page = new Page<Map<String, Object>>();
        if (current > 0){
            page.setCurrent((long) (current - 1) *size);
            page.setSize(size);
        }

           if (!params.isEmpty()&&!params.get("sort").isEmpty() && params.get("sort") != null){
               String[] sorts = params.get("sort").split(",");
               params.put("date",sorts[0]);
               params.put("lift",sorts[1]);
         }

        return this.getBaseMapper().pageList(page, RequestContext.getAppKey(), fieldCodes, groupCode, params);
    }
    // 不存在值班数据则不查找 修改sql 方法去除 by kongfm 2021-09-14
    public IPage<Map<String, Object>> pageListNew(int current, int size, String groupCode, String beginDate, String endDate) {
        Map<String, String> params = this.getRequestParamMap();
        if (!ObjectUtils.isEmpty(beginDate) && params.get("beginDate") == null) {
            params.put("stratTime", beginDate);
            params.put("endTime", endDate);
        }
        List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
        Map<String, Object> fieldCodes = Bean.listToMap(columns, FIELDCODE, QUERYSTRATEGY, DynamicFormColumn.class);
        Page<Map<String, Object>> page = new Page<Map<String, Object>>(current, size);
        return this.getBaseMapper().pageListNew(page, RequestContext.getAppKey(), fieldCodes, groupCode, params, beginDate, endDate);
    }

    public List<Map<String, Object>> personInfoList(String groupCode, HashSet<String> userIdSet) {
        return this.getBaseMapper().personInfoList(groupCode, userIdSet);
    }

    public IPage<Map<String, Object>> pageList(int current, int size, String groupCode, Map<String, String> params) {
        List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
        Map<String, Object> fieldCodes = Bean.listToMap(columns, FIELDCODE, QUERYSTRATEGY, DynamicFormColumn.class);
        Page<Map<String, Object>> page = new Page<Map<String, Object>>(current, size);
        return this.getBaseMapper().pageList(page, RequestContext.getAppKey(), fieldCodes, groupCode, params);
    }

    public List<Map<String, Object>> listAll(String groupCode) {
        Map<String, String> params = this.getRequestParamMap();
        List<DynamicFormColumn> columns = dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
        Map<String, Object> fieldCodes = Bean.listToMap(columns, FIELDCODE, QUERYSTRATEGY, DynamicFormColumn.class);
        return this.getBaseMapper().listAll(RequestContext.getAppKey(), fieldCodes, groupCode, params);
    }


    private Map<String, String> getRequestParamMap() {
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, String[]> localMap = new HashMap<>();
        localMap.putAll(parameterMap);
        localMap.remove("current");
        localMap.remove("size");
        Map<String, String> params = new HashMap<>();
        if (!ValidationUtil.isEmpty(localMap)) {
            for (String key : localMap.keySet()) {
                if (!ValidationUtil.isEmpty(localMap.get(key))) {
                    params.put(key, localMap.get(key)[0]);
                }
            }
        }
        return params;
    }

    @Override
    public List<DynamicFormInstance> getInstanceByCodeAndValue(String code, String value) {
        List<DynamicFormInstance> list = dynamicFormInstanceMapper.getInstanceByCodeAndValue(code, value);
        if (!CollectionUtils.isEmpty(list)) {
            return list;
        }
        return Lists.newArrayList();
    }
}

