package com.engine.salary.service.impl;

import com.alibaba.fastjson.JSON;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.biz.AttendQuoteFieldBiz;
import com.engine.salary.biz.AttendQuoteFieldSettingBiz;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.entity.datacollection.dto.AttendQuoteFieldSettingFieldListDTO;
import com.engine.salary.entity.datacollection.dto.AttendQuoteFieldSettingListDTO;
import com.engine.salary.entity.datacollection.param.AttendModuleSettingFieldParam;
import com.engine.salary.entity.datacollection.param.AttendQuoteFieldSettingQueryParam;
import com.engine.salary.entity.datacollection.param.AttendQuoteFieldSettingRecoverParam;
import com.engine.salary.entity.datacollection.param.AttendQuoteFieldSettingSaveParam;
import com.engine.salary.entity.datacollection.po.AttendQuoteFieldPO;
import com.engine.salary.entity.datacollection.po.AttendQuoteFieldSettingPO;
import com.engine.salary.enums.datacollection.AttendQuoteFieldSourceTypeEnum;
import com.engine.salary.enums.datacollection.AttendQuoteSourceTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.AttendQuoteFieldService;
import com.engine.salary.service.AttendQuoteFieldSettingService;
import com.engine.salary.util.valid.ValidUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import weaver.hrm.User;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 数据采集-考勤引用字段设置
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class AttendQuoteFieldSettingServiceImpl extends Service implements AttendQuoteFieldSettingService {

    private AttendQuoteFieldSettingBiz biz = new AttendQuoteFieldSettingBiz();

    private AttendQuoteFieldBiz fieldBiz = new AttendQuoteFieldBiz();

    //    
//    private AttendQuoteFieldSettingMapper mapper;
//    
//    private AttendQuoteFieldMapper attendQuoteFieldMapper;
//    
//    private LoggerTemplate attendQuoteFieldSettingLoggerTemplate;
    private AttendQuoteFieldService getAttendQuoteFieldService(User user) {
        return (AttendQuoteFieldService) ServiceUtil.getService(AttendQuoteFieldServiceImpl.class, user);
    }
    @Override
    public List<AttendQuoteFieldSettingListDTO> list(AttendQuoteFieldSettingQueryParam queryParam) {
        //同步字段
        getAttendQuoteFieldService(user).syncAttendFields();
        // 获取字段设置
        List<AttendQuoteFieldSettingPO> list = biz.getAttendQuoteFieldSetting(queryParam.getSourceType());

        List<AttendQuoteFieldSettingListDTO> resultList = new ArrayList<>();
        // 考勤模块分组字段
        resultList.add(buildAttendQuoteFieldSetting(CollectionUtils.isEmpty(list) ? null : list.get(0), AttendQuoteFieldSourceTypeEnum.ATTEND, "", queryParam.getKeyword(), queryParam.getIsViewChecked()));
        // 如果是导入还包含自定义分组
        if (queryParam.getSourceType().equals(AttendQuoteSourceTypeEnum.IMPORT)) {
            resultList.add(buildAttendQuoteFieldSetting(CollectionUtils.isEmpty(list) ? null : list.get(0), AttendQuoteFieldSourceTypeEnum.DEFAULT, "", queryParam.getKeyword(), queryParam.getIsViewChecked()));
        }
        return resultList;
    }


    /**
     * 获取所有字段
     */
    private List<AttendQuoteFieldPO> getAllAttendQuoteFields() {
        return fieldBiz.listSome(AttendQuoteFieldPO.builder().build());
    }

    @Override
    public List<AttendQuoteFieldSettingListDTO> listNoSync(AttendQuoteFieldSettingQueryParam queryParam) {
        // 获取字段设置
        List<AttendQuoteFieldSettingPO> list = biz.getAttendQuoteFieldSetting(queryParam.getSourceType());

        List<AttendQuoteFieldSettingListDTO> resultList = new ArrayList<>();
        // 考勤模块分组字段
        resultList.add(buildAttendQuoteFieldSetting(CollectionUtils.isEmpty(list) ? null : list.get(0), AttendQuoteFieldSourceTypeEnum.ATTEND, "", queryParam.getKeyword(), queryParam.getIsViewChecked()));
        // 如果是导入还包含自定义分组
        if (queryParam.getSourceType().equals(AttendQuoteSourceTypeEnum.IMPORT)) {
            resultList.add(buildAttendQuoteFieldSetting(CollectionUtils.isEmpty(list) ? null : list.get(0), AttendQuoteFieldSourceTypeEnum.DEFAULT, "", queryParam.getKeyword(), queryParam.getIsViewChecked()));
        }

        return resultList;
    }


    /**
     * 构建字段组设置
     *
     * @param po
     * @param fieldSourceType
     * @param keyword
     * @param isViewChecked
     * @return
     */
    private AttendQuoteFieldSettingListDTO buildAttendQuoteFieldSetting(AttendQuoteFieldSettingPO po, AttendQuoteFieldSourceTypeEnum fieldSourceType, String type, String keyword, Boolean isViewChecked) {
        // 根据来源获取字段
        List<AttendQuoteFieldPO> attendQuoteFields = getAllAttendQuoteFields();
        attendQuoteFields = attendQuoteFields.stream().filter(f -> f.getSourceType() == fieldSourceType.getValue()).collect(Collectors.toList());

        List<AttendQuoteFieldSettingFieldListDTO> fieldList = new ArrayList<>();
        // 没有设置过
        if (po == null) {
            fieldList = attendQuoteFields.stream().map(m ->
                    AttendQuoteFieldSettingFieldListDTO.builder()
                            .id(m.getId())
                            .name(m.getFieldName())
                            .checked(Boolean.FALSE)
                            .build()
            ).collect(Collectors.toList());
        } else {
            // 设置过，则解析
            List<AttendQuoteFieldSettingFieldListDTO> settingFields;
            // 如果是恢复默认设置
            if ("recoverAsDefault".equals(type)) {
                settingFields = JSON.parseArray(po.getDefaultSettingContent(), AttendQuoteFieldSettingFieldListDTO.class);
            } else {
                settingFields = JSON.parseArray(po.getCurrentSettingContent(), AttendQuoteFieldSettingFieldListDTO.class);
            }

            for (AttendQuoteFieldPO attendQuoteField : attendQuoteFields) {
                Optional<AttendQuoteFieldSettingFieldListDTO> optional = settingFields.stream().filter(e -> e.getId().equals(attendQuoteField.getId())).findFirst();
                if (optional.isPresent()) {
                    fieldList.add(AttendQuoteFieldSettingFieldListDTO.builder()
                            .id(attendQuoteField.getId())
                            .name(attendQuoteField.getFieldName())
                            .checked(optional.get().getChecked())
                            .build());
                } else {
                    fieldList.add(AttendQuoteFieldSettingFieldListDTO.builder()
                            .id(attendQuoteField.getId())
                            .name(attendQuoteField.getFieldName())
                            .checked(Boolean.FALSE)
                            .build());
                }
            }
        }
        // 关键字过滤
        if (StringUtils.isNotEmpty(keyword)) {
            fieldList = fieldList.stream().filter(e -> e.getName().contains(keyword)).collect(Collectors.toList());
        }
        // 是否只显示已选中字段
        if (isViewChecked != null && isViewChecked) {
            fieldList = fieldList.stream().filter(AttendQuoteFieldSettingFieldListDTO::getChecked).collect(Collectors.toList());
        }

        return AttendQuoteFieldSettingListDTO.builder()
                .groupId(fieldSourceType.name())
                .groupName(fieldSourceType.getDefaultLabel())
                .items(fieldList)
                .build();
    }


    @Override
    public List<AttendQuoteFieldSettingListDTO> recoverAsDefault(AttendQuoteFieldSettingRecoverParam recoverParam) {

        ValidUtil.doValidator(recoverParam);

        // 获取字段设置
        List<AttendQuoteFieldSettingPO> list = biz.getAttendQuoteFieldSetting(recoverParam.getSourceType());
        List<AttendQuoteFieldSettingListDTO> resultList = new ArrayList<>();
        // 考勤模块分组字段
        resultList.add(buildAttendQuoteFieldSetting(CollectionUtils.isEmpty(list) ? null : list.get(0), AttendQuoteFieldSourceTypeEnum.ATTEND, "recoverAsDefault", "", Boolean.FALSE));
        // 如果是导入还包含自定义分组
        if (recoverParam.getSourceType().equals(AttendQuoteSourceTypeEnum.IMPORT)) {
            resultList.add(buildAttendQuoteFieldSetting(CollectionUtils.isEmpty(list) ? null : list.get(0), AttendQuoteFieldSourceTypeEnum.DEFAULT, "recoverAsDefault", "", Boolean.FALSE));
        }
        return resultList;
    }

    @Override
    public String save(AttendQuoteFieldSettingSaveParam saveParam) {

        if (saveParam == null) {
            throw new SalaryRunTimeException("参数异常");
        }
        if (CollectionUtils.isEmpty(saveParam.getCurrentSettingFields())) {
            throw new SalaryRunTimeException("字段不能为空");
        }
        // 所有字段
        List<AttendQuoteFieldPO> allAttendFields = getAllAttendQuoteFields();

        List<AttendModuleSettingFieldParam> attendFields = saveParam.getCurrentSettingFields();
        for (AttendModuleSettingFieldParam attendField : attendFields) {
            Optional<AttendQuoteFieldPO> optional = allAttendFields.stream().filter(e -> e.getId().equals(attendField.getId())).findFirst();
            if (!optional.isPresent()) {
                throw new SalaryRunTimeException(String.format("字段不存在[id:%s]", attendField.getId()));
            }
        }
        String currentSettingContent = JSON.toJSONString(attendFields);
        // 获取字段设置
        List<AttendQuoteFieldSettingPO> list = biz.getAttendQuoteFieldSetting(saveParam.getSourceType());

        String sourceTypeName = saveParam.getSourceType() == AttendQuoteSourceTypeEnum.QUOTE ? "引用考勤" : "导入数据";
        Date now = new Date();
        if (CollectionUtils.isEmpty(list)) {
            AttendQuoteFieldSettingPO po = AttendQuoteFieldSettingPO.builder()
                    .sourceType(saveParam.getSourceType().getValue())
                    .currentSettingContent(currentSettingContent)
                    .createTime(now)
                    .updateTime(now)
                    .creator((long) user.getUID())
                    .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                    .build();
            // todo 记录日志
            biz.insert(po);
        } else {
            AttendQuoteFieldSettingPO oldObject = list.get(0);
            AttendQuoteFieldSettingPO newObject = new AttendQuoteFieldSettingPO();
            BeanUtils.copyProperties(oldObject, newObject);
            newObject.setCurrentSettingContent(currentSettingContent);
            newObject.setUpdateTime(now);
            // 更新
            biz.updateById(newObject);
            // todo 记录日志

        }
        return null;
    }

    @Override
    public String saveAsDefault(AttendQuoteFieldSettingSaveParam saveParam) {
        if (CollectionUtils.isEmpty(saveParam.getCurrentSettingFields())) {
            throw new SalaryRunTimeException("字段不能为空");
        }
        // 所有字段
        List<AttendQuoteFieldPO> allAttendFields = getAllAttendQuoteFields();

        List<AttendModuleSettingFieldParam> attendFields = saveParam.getCurrentSettingFields();
        for (AttendModuleSettingFieldParam attendField : attendFields) {
            Optional<AttendQuoteFieldPO> optional = allAttendFields.stream().filter(e -> e.getId().equals(attendField.getId())).findFirst();
            if (!optional.isPresent()) {
                throw new SalaryRunTimeException(String.format("字段不存在[id:%s]", attendField.getId()));
            }
        }

        String currentSettingContent = JSON.toJSONString(attendFields);
        Date now = new Date();
        // 获取字段设置
        List<AttendQuoteFieldSettingPO> list = biz.getAttendQuoteFieldSetting(saveParam.getSourceType());
        String sourceTypeName = saveParam.getSourceType() == AttendQuoteSourceTypeEnum.QUOTE ? "引用考勤" : "导入数据";
        if (CollectionUtils.isEmpty(list)) {
            AttendQuoteFieldSettingPO po = AttendQuoteFieldSettingPO.builder()
                    .sourceType(saveParam.getSourceType().getValue())
                    .currentSettingContent(currentSettingContent)
                    .defaultSettingContent(currentSettingContent)
                    .createTime(now)
                    .updateTime(now)
                    .creator((long) user.getUID())
                    .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                    .build();
            // todo 记录日志
            biz.insert(po);
        } else {
            AttendQuoteFieldSettingPO oldObject = list.get(0);
            AttendQuoteFieldSettingPO newObject = new AttendQuoteFieldSettingPO();
            BeanUtils.copyProperties(oldObject, newObject);
            newObject.setCurrentSettingContent(currentSettingContent);
            newObject.setDefaultSettingContent(currentSettingContent);
            newObject.setUpdateTime(now);
            // 更新
            biz.updateById(newObject);
            // todo 记录日志

        }

        return null;
    }
}
