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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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;
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 javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 动态表单实例表服务实现类
 *
 * @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
    HttpServletRequest request;

    /**
     * 分页查询
     */
    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 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) {
                DynamicFormInstance dyFormInstance =
                        list.stream().filter(i -> i.getFieldCode().equals(optionModel.getFieldCode())).findFirst().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 page = new Page(current, size);
        return this.getBaseMapper().pageList(page, RequestContext.getAppKey(), fieldCodes, groupCode, params);
    }
    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 page = new Page(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;
    }
}

