package jnpf.personnels.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.ImmutableMap;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.base.entity.SuperBaseEntity;
import jnpf.certificate.service.CertificateInstanceService;
import jnpf.database.util.TenantDataSourceUtil;
import jnpf.exception.LoginException;
import jnpf.model.certificate.vo.app.HealthCertificateDetailVO;
import jnpf.model.personnels.bo.ExportRosterOneVo;
import jnpf.model.personnels.bo.FtbRosterImportConstants;
import jnpf.model.personnels.bo.FtbRosterImportTemplateBO;
import jnpf.model.personnels.dto.staff.field.ExportFormFieldDto;
import jnpf.model.personnels.dto.staff.field.ExportFormTypeDto;
import jnpf.model.personnels.dto.staff.registerform.ProbationPeriodDto;
import jnpf.model.personnels.dto.staff.registerform.WorkAddressDto;
import jnpf.model.personnels.dto.staff.roster.SimpleStoreUserDto;
import jnpf.model.personnels.dto.staff.roster.WorkerGroupDataDto;
import jnpf.model.personnels.po.*;
import jnpf.permission.ContractTypeApi;
import jnpf.permission.V2UserApi;
import jnpf.permission.vo.contract.ContractTypeVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.personnels.mapper.FtbPersonnelsRegistrationFormFieldMapper;
import jnpf.personnels.mapper.FtbPersonnelsRegistrationFormTypeMapper;
import jnpf.personnels.mapper.FtbPersonnelsStaffRegistrationFormDataMapper;
import jnpf.personnels.mapper.FtbPersonnelsStaffRosterSchemeMapper;
import jnpf.personnels.mapper.FtbPersonnelsTurnoverManagementMapper;
import jnpf.store.mapper.StoreUserRelationMapper;
import jnpf.util.Constants;
import jnpf.util.UserProvider;
import jnpf.utils.FeignHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Component
public class RosterExportUtils {

    @Resource
    private FtbPersonnelsRegistrationFormFieldMapper ftbPersonnelsRegistrationFormFieldMapper;

    @Resource
    private FtbPersonnelsStaffRegistrationFormDataMapper ftbPersonnelsStaffRegistrationFormDataMapper;

    @Resource
    private FtbPersonnelsRegistrationFormTypeMapper ftbPersonnelsRegistrationFormTypeMapper;

    @Resource
    private V2UserApi v2UserApi;

    @Resource
    private CertificateInstanceService certificateInstanceService;

    @Autowired
    private StoreUserRelationMapper storeUserRelationMapper;

    @Resource
    private ContractTypeApi contractTypeApi;

    @Resource
    private FtbPersonnelsStaffRosterSchemeMapper ftbPersonnelsStaffRosterSchemeMapper;

    @Resource
    private FtbPersonnelsTurnoverManagementMapper ftbPersonnelsTurnoverManagementMapper;

    public List<ExportFormTypeDto> getExportFormTypes(List<String> formFieldOptionIds,String schemeId) {
        if (StrUtil.isNotBlank(schemeId)) {
            FtbPersonnelsStaffRosterScheme ftbPersonnelsStaffRosterScheme = ftbPersonnelsStaffRosterSchemeMapper.selectById(schemeId);
            formFieldOptionIds = JSON.parseArray(ftbPersonnelsStaffRosterScheme.getFormFields(), String.class);
        }
        ExportFormTypeDto exportFormTypeDto = new ExportFormTypeDto();
        exportFormTypeDto.setName("Sheet1");
        // 入职直属主管ID特殊处理
        if (formFieldOptionIds.contains("currReportsToId")) {
            formFieldOptionIds.remove("currReportsToId");
            formFieldOptionIds.add("affiliatedReportsTo");
        }
        LambdaQueryWrapper<FtbPersonnelsRegistrationFormField> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(SuperBaseEntity.SuperIBaseEntity::getId, formFieldOptionIds);
        queryWrapper.eq(FtbPersonnelsRegistrationFormField::getEnabledMark,0);
        queryWrapper.eq(FtbPersonnelsRegistrationFormField::getStatus,0);
        queryWrapper.orderByAsc(FtbPersonnelsRegistrationFormField::getSorts);
        List<FtbPersonnelsRegistrationFormField> registrationFormFields = ftbPersonnelsRegistrationFormFieldMapper.selectList(queryWrapper);
        // 姓名和手机号置顶
        Predicate<FtbPersonnelsRegistrationFormField> workerNamePredicate = a -> "workerName".equals(a.getId());
        registrationFormFields.stream()
                .filter(workerNamePredicate)
                .findFirst()
                .ifPresent(a -> {
                    registrationFormFields.removeIf(workerNamePredicate);
                    registrationFormFields.add(0, a);
                });
        Predicate<FtbPersonnelsRegistrationFormField> phonePredicate = a -> "phone".equals(a.getId());
        registrationFormFields.stream()
                .filter(phonePredicate)
                .findFirst()
                .ifPresent(a -> {
                    registrationFormFields.removeIf(phonePredicate);
                    registrationFormFields.add(1, a);
                });
        List<ExportFormFieldDto> fieldDtoList = registrationFormFields.stream().map(item -> {
            ExportFormFieldDto exportFormFieldDto = new ExportFormFieldDto();
            exportFormFieldDto.setId(item.getId());
            exportFormFieldDto.setFormTypeId(item.getFormTypeId());
            exportFormFieldDto.setName(item.getName());
            exportFormFieldDto.setSystemType(item.getSystemType());
            exportFormFieldDto.setType(item.getType());
            exportFormFieldDto.setIsUpdateManager(item.getIsUpdateManager());
            exportFormFieldDto.setIsUpdateWorker(item.getIsUpdateWorker());
            exportFormFieldDto.setGroupName(item.getGroupName());
            exportFormFieldDto.setIsNeedFill(item.getIsNeedFill());
            return exportFormFieldDto;
        }).collect(Collectors.toList());
        // 导出时工作信息的完整组织
        if (formFieldOptionIds.contains("completeOrganization")) {
            ExportFormFieldDto exportFormFieldDto = new ExportFormFieldDto();
            exportFormFieldDto.setId("completeOrganization");
            exportFormFieldDto.setName("完整组织");
            exportFormFieldDto.setSystemType(0);
            exportFormFieldDto.setType(0);
            exportFormFieldDto.setIsNeedFill(0);
            fieldDtoList.add(exportFormFieldDto);
        }
        // 健康证状态特殊处理
        if (formFieldOptionIds.contains("healthCertificateStatus")) {
            ExportFormFieldDto exportFormFieldDto = new ExportFormFieldDto();
            exportFormFieldDto.setId("healthCertificateStatus");
            exportFormFieldDto.setName("健康证状态");
            exportFormFieldDto.setSystemType(0);
            exportFormFieldDto.setType(0);
            exportFormFieldDto.setIsNeedFill(0);
            fieldDtoList.add(exportFormFieldDto);
        }
        exportFormTypeDto.setFieldDtoList(fieldDtoList);
        return List.of(exportFormTypeDto);
    }
    public List<ExportFormTypeDto> getExportFormTypesWithOnboarding(String[]... nams) {
        LambdaQueryWrapper<FtbPersonnelsRegistrationFormType> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(FtbPersonnelsRegistrationFormType::getStatus, 0);
        lambdaQueryWrapper.eq(FtbPersonnelsRegistrationFormType::getEnabledMark,0);
        List<FtbPersonnelsRegistrationFormType> formTypeList = ftbPersonnelsRegistrationFormTypeMapper.selectList(lambdaQueryWrapper);
        if (CollUtil.isEmpty(formTypeList)) {
            return new ArrayList<>();
        }
        ExportFormTypeDto exportFormTypeDto = new ExportFormTypeDto();
        exportFormTypeDto.setName("Sheet2");
        List<String> typeIds = formTypeList.stream().map(SuperBaseEntity.SuperIBaseEntity::getId).collect(Collectors.toList());
        // 入职直属主管 ID 特殊处理
        LambdaQueryWrapper<FtbPersonnelsRegistrationFormField> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(FtbPersonnelsRegistrationFormField::getStatus, 0);
        queryWrapper.eq(FtbPersonnelsRegistrationFormField::getEnabledMark,0);
        queryWrapper.in(FtbPersonnelsRegistrationFormField::getFormTypeId, typeIds);
        queryWrapper.notIn(FtbPersonnelsRegistrationFormField::getType,5,6);
        // 将可变参数转换为 List
        List<String> nameList = new ArrayList<>();
        if (nams != null) {
            for (String[] namArray : nams) {
                if (namArray != null) {
                    nameList.addAll(Arrays.asList(namArray));
                }
            }
        }
        if (CollUtil.isNotEmpty(nameList)) {
            queryWrapper.notIn(FtbPersonnelsRegistrationFormField::getName, nameList);
        }
        queryWrapper.orderByAsc(FtbPersonnelsRegistrationFormField::getSorts);
        List<FtbPersonnelsRegistrationFormField> ftbPersonnelsRegistrationFormFields = ftbPersonnelsRegistrationFormFieldMapper.selectList(queryWrapper);
        // 额外项排除
        List<ExportFormFieldDto> fieldDtoList = ftbPersonnelsRegistrationFormFields.stream().map(item -> {
            ExportFormFieldDto exportFormFieldDto = new ExportFormFieldDto();
            exportFormFieldDto.setId(item.getId());
            exportFormFieldDto.setFormTypeId(item.getFormTypeId());
            exportFormFieldDto.setName(item.getName());
            exportFormFieldDto.setSystemType(item.getSystemType());
            exportFormFieldDto.setType(item.getType());
            exportFormFieldDto.setIsUpdateManager(item.getIsUpdateManager());
            exportFormFieldDto.setIsUpdateWorker(item.getIsUpdateWorker());
            exportFormFieldDto.setGroupName(item.getGroupName());
            return exportFormFieldDto;
        }).distinct().collect(Collectors.toList());
        sortPriorityFields(fieldDtoList);
        exportFormTypeDto.setFieldDtoList(fieldDtoList);
        return List.of(exportFormTypeDto);
    }

    /**
     * 对字段列表进行排序，按照指定的优先级顺序排序
     *
     * @param fieldDtoList 字段列表
     */
    private void sortPriorityFields(List<ExportFormFieldDto> fieldDtoList) {
        // 定义优先字段的固定顺序
        Map<String, Integer> priorityOrder = new LinkedHashMap<>();
        priorityOrder.put("姓名", 0);
        priorityOrder.put("性别", 1);
        priorityOrder.put("身份证号码", 2);
        priorityOrder.put("出生日期", 3);
        priorityOrder.put("年龄", 4);
        priorityOrder.put("手机号码", 5);
        priorityOrder.put("民族", 6);
        priorityOrder.put("婚姻状况", 7);
        priorityOrder.put("学历", 8);
        priorityOrder.put("员工状态", 9);
        priorityOrder.put("员工类型", 10);
        priorityOrder.put("所属组织", 11);
        priorityOrder.put("岗位", 12);
        priorityOrder.put("职级", 13);
        priorityOrder.put("班组", 14);
        priorityOrder.put("直属主管", 15);
        priorityOrder.put("紧急联系人姓名", 16);
        priorityOrder.put("联系人关系", 17);
        priorityOrder.put("联系人电话", 18);
        priorityOrder.put("住址", 19);

        java.text.Collator collator = java.text.Collator.getInstance(java.util.Locale.CHINA);
        fieldDtoList.sort((field1, field2) -> {
            String name1 = field1.getName();
            String name2 = field2.getName();

            Integer order1 = priorityOrder.get(name1);
            Integer order2 = priorityOrder.get(name2);

            // 如果两个字段都在优先级列表中，按优先级顺序排序
            if (order1 != null && order2 != null) {
                return order1.compareTo(order2);
            }
            // 如果只有其中一个在优先级列表中，则在列表中的排在前面
            if (order1 != null) {
                return -1;
            }
            if (order2 != null) {
                return 1;
            }
            // 如果两个字段都不在优先级列表中，则按拼音排序
            return collator.compare(name1, name2);
        });
    }

    public List<FtbRosterImportTemplateBO> convertToFtbRosterImportTemplateBO(List<ExportFormTypeDto> fieldList,
                                                                              List<FtbPersonnelsRegistrationFormFieldOption> optionList,
                                                                              List<ExportRosterOneVo> rosterDataList) {
        if (CollectionUtil.isEmpty(rosterDataList)) {
            return new ArrayList<>();
        }
        //分组
        List<List<ExportRosterOneVo>> allList = groupByBatch(rosterDataList);
        // 主线程中获取
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        UserInfo userInfo = UserProvider.getUser();
        String tenantId = userInfo.getTenantId();
        String token = userInfo.getToken();
        Map<String, String> headers = ImmutableMap.of(Constants.AUTHORIZATION.toLowerCase(), token);
        //多线程调用 convertToFtbRosterImportTemplateBatch 这个方法
        List<CompletableFuture<List<FtbRosterImportTemplateBO>>> futures = allList.stream()
                .map(rosterData -> CompletableFuture.supplyAsync(() -> {
                    try {
                        return convertToFtbRosterImportTemplateBatch(fieldList, optionList, rosterData, requestAttributes, tenantId, headers);
                    } finally {
                        FeignHolder.clear();
                    }
                }))
                .collect(Collectors.toList());
        //搜集结果并返回
        return futures.stream()
                .map(CompletableFuture::join)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
    }

    public List<List<ExportRosterOneVo>> groupByBatch(List<ExportRosterOneVo> rosterDataList) {
        List<List<ExportRosterOneVo>> groupedData = new ArrayList<>();
        int batchSize = 100;

        for (int i = 0; i < rosterDataList.size(); i += batchSize) {
            int end = Math.min(i + batchSize, rosterDataList.size());
            groupedData.add(new ArrayList<>(rosterDataList.subList(i, end)));
        }

        return groupedData;
    }

    public List<FtbRosterImportTemplateBO> convertToFtbRosterImportTemplateBatch(List<ExportFormTypeDto> allFields, List<FtbPersonnelsRegistrationFormFieldOption> optionList, List<ExportRosterOneVo> rosterDataList, RequestAttributes requestAttributes, String tenantCode, Map<String, String> headers) {
        log.info("requestAttr={},tenantId={}", JSONUtil.toJsonStr(requestAttributes), tenantCode);
        FeignHolder.set(headers);
        try {
            TenantDataSourceUtil.switchTenant(tenantCode);
        } catch (LoginException e) {
            throw new RuntimeException(e);
        }
        // 用户组织信息
        List<String> userIds = rosterDataList.stream().map(item -> item.getRoster().getUserId()).collect(Collectors.toList());
        List<String> rosterIds = rosterDataList.stream().map(item -> item.getRoster().getId()).collect(Collectors.toList());
        Map<String, String> contractInformationMap = getContractInformation(rosterIds);
        // 获取健康证状态信息
        Map<String, String> healthStatusMap = getHealthStatus(userIds);
        Map<String, WorkerGroupDataDto> workerGroupDataDtoMap = getUserOrgBoundInfoForUserList(userIds, tenantCode);
        Map<String, FtbPersonnelsRegistrationFormFieldOption> optionMap = optionList.stream()
                .collect(Collectors.toMap(FtbPersonnelsRegistrationFormFieldOption::getId, Function.identity(), (a, b) -> a));
        // 预处理表头数据，避免在循环中重复创建
        List<FtbRosterImportTemplateBO> list = new ArrayList<>(allFields.size());
        Map<String, List<ExportFormFieldDto>> formTypeFieldMap = new HashMap<>();

        // 预先构建表头和字段映射
        for (ExportFormTypeDto formType : allFields) {
            FtbRosterImportTemplateBO bo = new FtbRosterImportTemplateBO();
            list.add(bo);

            List<ExportFormFieldDto> fieldList = formType.getFieldDtoList();
            formTypeFieldMap.put(formType.getName(), fieldList);
            
            // 构建表头
            List<List<String>> header = new ArrayList<>(fieldList.size());
            for (ExportFormFieldDto field : fieldList) {
                if (field.getIsNeedFill() != null &&  field.getIsNeedFill() == 1) {
                    header.add(List.of("*"+field.getName()));
                } else {
                  header.add(List.of(field.getName()));
                }
            }
            bo.setHeader(header);
            bo.setSheetName(formType.getName());
        }
        
        // 预先构建系统字段处理器映射，避免每次重复判断
        Map<String, Function<WorkerGroupDataDto, String>> systemFieldProcessor = Map.of(
            "affiliatedOrg", dto -> dto != null ? dto.getAffiliatedOrgName() : "",
            "affiliatedPosition", dto -> dto != null ? dto.getAffiliatedPositionName() : "",
            "affiliatedRank", dto -> dto != null ? dto.getAffiliatedRankName() : "",
            "affiliatedReportsTo", dto -> dto != null ? dto.getReportsToName() : "",
            "affiliatedShop", dto -> dto != null ? dto.getAffiliatedShopName() : "",
            "team", dto -> dto != null ? dto.getStoreTeamName() : ""
        );
        
        // 批量处理每种表单类型的数据
        for (ExportFormTypeDto formType : allFields) {
            FtbRosterImportTemplateBO bo = list.stream()
                .filter(b -> formType.getName().equals(b.getSheetName()))
                .findFirst()
                .orElse(null);

            if (bo != null) {
                List<ExportFormFieldDto> fieldList = formTypeFieldMap.get(formType.getName());

                // 使用预分配容量的列表提高性能
                List<List<Object>> data = new ArrayList<>(rosterDataList.size());

                // 批量处理数据
                for (ExportRosterOneVo exportRosterOneVo : rosterDataList) {
                    FtbPersonnelsStaffRoster roster = exportRosterOneVo.getRoster();
                    List<FtbPersonnelsStaffRegistrationFormData> formValueList = exportRosterOneVo.getFormValue();

                    // 查询用户组织信息
                    WorkerGroupDataDto workerGroupDataDto = workerGroupDataDtoMap.get(roster.getUserId());
                    
                    // 将表单值转换为映射，避免重复构建
                    Map<String, FtbPersonnelsStaffRegistrationFormData> valueMap = convertFormValueMap(formValueList);

                    // 预分配容量，避免动态扩容
                    List<Object> exportDataList = new ArrayList<>(fieldList.size());

                    // 批量处理字段值
                    for (ExportFormFieldDto field : fieldList) {
                        String showValue = calculateFieldValue(
                            field,
                            workerGroupDataDto,
                            valueMap,
                            roster,
                            optionMap,
                            systemFieldProcessor,contractInformationMap,
                            healthStatusMap
                        );
                        exportDataList.add(showValue);
                    }

                    data.add(exportDataList);
                }

                bo.setData(data);
            }
        }
        return list;
    }

    private Map<String, String> getHealthStatus(List<String> userIds) {
        List<HealthCertificateDetailVO> healthCertificateDetails = certificateInstanceService.getHealthCertificateDetails(userIds);
        return healthCertificateDetails.stream().collect(Collectors.toMap(HealthCertificateDetailVO::getUserId, HealthCertificateDetailVO::getStatusDesc));
    }

    /**
     * 计算字段显示值
     */
    private String calculateFieldValue(
            ExportFormFieldDto field,
            WorkerGroupDataDto workerGroupDataDto,
            Map<String, FtbPersonnelsStaffRegistrationFormData> valueMap,
            FtbPersonnelsStaffRoster roster,
            Map<String, FtbPersonnelsRegistrationFormFieldOption> optionMap,
            Map<String, Function<WorkerGroupDataDto, String>> systemFieldProcessor,
            Map<String, String> contractInformationMap,
            Map<String, String> healthStatusMap) {
        
        // 添加空值检查
        if (field == null) {
            return "";
        }

        // 检查是否为系统字段
        if (systemFieldProcessor != null && systemFieldProcessor.containsKey(field.getId())) {
            Function<WorkerGroupDataDto, String> processor = systemFieldProcessor.get(field.getId());
            if (processor != null) {
                return processor.apply(workerGroupDataDto);
            }
        }

        String showValue = "";
        FtbPersonnelsStaffRegistrationFormData formFieldValue = null;
        if (valueMap != null) {
            formFieldValue = valueMap.get(field.getId());
        }
        FtbPersonnelsRegistrationFormFieldOption optionEntity = null;

        if (formFieldValue != null) {
            if (field.getType() == 2 || field.getType() == 3) {
                if (StringUtils.isNotEmpty(formFieldValue.getValue())) {
                    String fieldValue = formFieldValue.getValue();
                    if ("probationPeriod".equals(field.getId()) && fieldValue != null && fieldValue.startsWith("{")) {
                        try {
                            ProbationPeriodDto bean = JSONUtil.toBean(fieldValue, ProbationPeriodDto.class);
                            String key = bean != null ? bean.getType() : null;
                            if ("101".equals(key)) {
                                showValue = bean.getDays() + "天";
                            } else {
                                if (optionMap != null && key != null) {
                                    optionEntity = optionMap.get(key);
                                    if (optionEntity != null) {
                                        showValue = optionEntity.getName();
                                    }
                                }
                            }
                        } catch (Exception e) {
                            log.warn("Failed to parse probationPeriod JSON: " + fieldValue, e);
                        }
                    }  else if ("contractType".equals(field.getId()) && MapUtil.isNotEmpty(contractInformationMap)) {
                        // 完整组织
                        showValue = contractInformationMap.getOrDefault(fieldValue, "");
                    } else {
                        if (field.getType() == 3) {
                            if (optionMap != null ) {
                                String value = formFieldValue.getValue();
                                // {"label":"多选2,多选3","value":"1958346454656946178,1958346454656946179"}
                                if (value != null && value.startsWith("{")) {
                                    JSONObject jsonObject = JSONUtil.parseObj(value);
                                    if (jsonObject.containsKey("label")) {
                                        showValue = jsonObject.getStr("label");
                                    }
                                }else if (value != null ) {
                                    showValue = Stream.of(value.split(","))
                                            .map(optionMap::get)
                                            .filter(Objects::nonNull)
                                            .map(FtbPersonnelsRegistrationFormFieldOption::getName)
                                            .collect(Collectors.joining(","));
                                }
                            }
                        } else {
                            if (optionMap != null) {
                                String value = formFieldValue.getValue();
                                if (value != null) {
                                    optionEntity = optionMap.get(value);
                                    if (optionEntity != null) {
                                        showValue = optionEntity.getName();
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                if ("workAddress".equals(field.getId()) ) {
                    String fieldValue = formFieldValue.getValue();
                    if (fieldValue != null && fieldValue.startsWith("{")) {
                        try {
                            WorkAddressDto bean = JSONUtil.toBean(fieldValue, WorkAddressDto.class);
                            showValue = bean != null ? bean.getAddress() : "";
                        } catch (Exception e) {
                            log.warn("Failed to parse workAddress JSON: " + fieldValue, e);
                        }
                    }
                } else if ("completeOrganization".equals(field.getId())) {
                    // 完整组织
                    showValue = workerGroupDataDto.getOrganizeTreeName();
                } else {
                    String fieldValue = formFieldValue.getValue();
                    showValue = fieldValue != null ? fieldValue : "";
                }
            }
        }

        // 特殊字段处理
        if ("age".equals(field.getId())) {
            // 根据出生日期计算
            FtbPersonnelsStaffRegistrationFormData birthdayFieldValue = null;
            if (valueMap != null) {
                birthdayFieldValue = valueMap.get("birthday");
            }
            if (Objects.nonNull(birthdayFieldValue) && StrUtil.isNotBlank(birthdayFieldValue.getValue())) {
                try {
                    Date dateBirthday = DateUtil.parse(birthdayFieldValue.getValue());
                    long age = DateUtil.betweenYear(dateBirthday, DateUtil.date(), false);
                    showValue = String.valueOf(age);
                } catch (Exception e) {
                    log.warn("Failed to parse birthday: " + birthdayFieldValue.getValue(), e);
                }
            }
        } else if ("companyAge".equals(field.getId())) {
            if (roster != null) {
                Date departDate = roster.getDepartDate();
                String workerStatus = roster.getWorkerStatus();
                // 实际入职时间
                Date actualStartDate = roster.getActualStartDate();
                String day = "";
                if ("305".equals(workerStatus) && ObjectUtil.isNotEmpty(departDate)) {
                    day = CompanyAgeUtil.calculateServiceAgeShort(actualStartDate,departDate);
                } else if (ObjectUtil.isNotEmpty(actualStartDate)) {
                    day = CompanyAgeUtil.calculateServiceAgeShort(actualStartDate,new Date());
                }
                showValue = day;
            }
        } else if ("workAge".equals(field.getId())) {
            FtbPersonnelsStaffRegistrationFormData firstWorkDate = null;
            if (valueMap != null) {
                firstWorkDate = valueMap.get("firstWorkDate");
            }
            if (Objects.nonNull(firstWorkDate) && StrUtil.isNotBlank(firstWorkDate.getValue())) {
                try {
                    Date ageWorkAge = DateUtil.parse(firstWorkDate.getValue());
                    long age = DateUtil.betweenYear(ageWorkAge, DateUtil.date(), false);
                    showValue = age + "年";
                } catch (Exception e) {
                    log.warn("Failed to parse firstWorkDate: " + firstWorkDate.getValue(), e);
                }
            }
        } else if ("completeOrganization".equals(field.getId()) && Objects.nonNull(workerGroupDataDto)) {
            // 完整组织
            showValue = workerGroupDataDto.getOrganizeTreeName();
        } else if ("healthCertificateStatus".equals(field.getId())) {
            // 健康状态
            showValue = healthStatusMap.get(roster.getUserId());
        }

        return showValue;
    }

    private Map<String, FtbPersonnelsStaffRegistrationFormData> convertFormValueMap(List<FtbPersonnelsStaffRegistrationFormData> formFieldValueList) {
        if (CollectionUtil.isEmpty(formFieldValueList)) {
            return new HashMap<>();
        }
        return formFieldValueList.stream().filter(v->ObjectUtil.isNotEmpty(v.getFormFieldId()))
                .collect(Collectors.toMap(FtbPersonnelsStaffRegistrationFormData::getFormFieldId, a -> a, (a, b) -> b));

    }

    private Map<String, WorkerGroupDataDto> getUserOrgBoundInfoForUserList(List<String> userIdList, String tenantId) {
        ActionResult<List<UserBoundVO>> remoteResult = v2UserApi.getUserPrimaryBoundBatch(userIdList, tenantId);
        if (Objects.isNull(remoteResult)) {
            return new HashMap<>();
        }
        Map<String, WorkerGroupDataDto> retMap = new HashMap<>();
        LambdaQueryWrapper<FtbPersonnelsTurnoverManagement> lambdaedQuery = Wrappers.lambdaQuery();
        lambdaedQuery.select(FtbPersonnelsTurnoverManagement::getUserId,FtbPersonnelsTurnoverManagement::getOrganizationInfo);
        lambdaedQuery.in(FtbPersonnelsTurnoverManagement::getUserId, userIdList);
        List<FtbPersonnelsTurnoverManagement> personnelsTurnoverManagements = ftbPersonnelsTurnoverManagementMapper.selectList(lambdaedQuery);
        Map<String, List<FtbPersonnelsTurnoverManagement>> turUserMaps = personnelsTurnoverManagements.stream().collect(Collectors.groupingBy(FtbPersonnelsTurnoverManagement::getUserId));
        List<UserBoundVO> data = remoteResult.getData();
        Map<String, UserBoundVO> map = data.stream().collect(Collectors.toMap(UserBoundVO::getId, Function.identity(), (k1, k2) -> k1));
        //补充门店，如果为 true 表示要查询门店信息
        // 合并在职和离职人员的 userId（去重）
        Set<String> userIds = new HashSet<>();
        if (CollUtil.isNotEmpty(map)) {
            userIds.addAll(map.keySet());
        }
        if (CollUtil.isNotEmpty(personnelsTurnoverManagements)) {
            personnelsTurnoverManagements.stream()
                    .map(FtbPersonnelsTurnoverManagement::getUserId)
                    .filter(Objects::nonNull)
                    .forEach(userIds::add);
        }
        if (CollUtil.isEmpty(userIds)) {
            return retMap;
        }
        List<SimpleStoreUserDto> simpleStoreUserDtos = storeUserRelationMapper.querySimpleStoreUserDto(userIds);
        // 在职数据构建组织信息（优先级高）
        for (Map.Entry<String, UserBoundVO> entry : map.entrySet()) {
            String userId = entry.getKey(); // 用户 ID
            UserBoundVO list = entry.getValue(); // 获取值列表
            WorkerGroupDataDto workerGroupDataDto = new WorkerGroupDataDto();
            workerGroupDataDto.setAffiliatedOrgName(list.getOrganizeName());
            workerGroupDataDto.setAffiliatedPositionName(list.getPositionName());
            workerGroupDataDto.setAffiliatedRankName(list.getGradeName());
            workerGroupDataDto.setReportsToName(list.getLeaderName());
            workerGroupDataDto.setStoreTeamName(list.getStoreTeamName());
            workerGroupDataDto.setOrganizeTreeName(list.getOrganizeTreeName());
            simpleStoreUserDtos.stream().filter(a -> a.getUserId().equals(userId)).findFirst().ifPresent(a -> {
                workerGroupDataDto.setAffiliatedShopName(a.getStoreName());
            });
            retMap.put(userId, workerGroupDataDto);
        }

        // 离职数据补全组织信息（优先级低，仅当 retMap 中不存在该 userId 时才补充）
        for (Map.Entry<String, List<FtbPersonnelsTurnoverManagement>> entry : turUserMaps.entrySet()) {
            String userId = entry.getKey();
            // 只有当 retMap 中没有该 userId 的数据时，才从 turUserMaps 中补充
            if (!retMap.containsKey(userId)) {
                List<FtbPersonnelsTurnoverManagement> turnoverList = entry.getValue();
                if (CollUtil.isNotEmpty(turnoverList)) {
                    FtbPersonnelsTurnoverManagement turnover = turnoverList.get(0);
                    WorkerGroupDataDto workerGroupDataDto = new WorkerGroupDataDto();
                    // 从离职人员表中获取组织信息
                    String organizationInfo = turnover.getOrganizationInfo();
                    if (StrUtil.isNotBlank(organizationInfo)) {
                        // 假设 organizationInfo 是 JSON 格式，需要解析
                        // 这里根据实际的 organizationInfo 格式进行解析
                        List<WorkerGroupDataDto> dtos = JSONArray.parseArray(organizationInfo, WorkerGroupDataDto.class);
                        workerGroupDataDto = dtos.stream().findFirst().orElse(workerGroupDataDto);
                    }
                    retMap.put(userId, workerGroupDataDto);
                }
            }
        }

        return retMap;
    }

    private Map<String,String> getContractInformation(List<String> rosterIds) {
        LambdaQueryWrapper<FtbPersonnelsStaffRegistrationFormData> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(FtbPersonnelsStaffRegistrationFormData::getRosterId,rosterIds);
        queryWrapper.eq(FtbPersonnelsStaffRegistrationFormData::getFormFieldId,"contractType");
        List<FtbPersonnelsStaffRegistrationFormData> ftbPersonnelsStaffRegistrationFormData = ftbPersonnelsStaffRegistrationFormDataMapper.selectList(queryWrapper);
        List<String> contractTypeIds = ftbPersonnelsStaffRegistrationFormData.stream()
                .map(FtbPersonnelsStaffRegistrationFormData::getValue)
                .filter(StrUtil::isNotBlank)
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(contractTypeIds)) {
            ActionResult<List<ContractTypeVO>> contractTypeApiListInfo = contractTypeApi.getListInfo(contractTypeIds);
            if (null != contractTypeApiListInfo && CollectionUtil.isNotEmpty(contractTypeApiListInfo.getData())) {
                return contractTypeApiListInfo.getData().stream().collect(Collectors.toMap(ContractTypeVO::getId, ContractTypeVO::getFullName));
            }
        }
        return Map.of();
    }


    /**
     * 通用方法：从对象列表中提取指定注解的字段值
     * @param list 对象列表
     * @param clazz 对象的 Class
     * @return 包含所有指定注解字段值的二维列表
     */
    public <T> List<List<Object>> extractAnnotatedFieldValues(List<T> list, Class<T> clazz) {
        if (list == null || list.isEmpty()) {
            return new ArrayList<>();
        }

        List<List<Object>> result = new ArrayList<>();
        Field[] fields = clazz.getDeclaredFields();

        // 获取所有带有指定注解的字段
        List<Field> annotatedFields = Arrays.stream(fields)
                .filter(field -> field.isAnnotationPresent(ExcelProperty.class))
                .collect(Collectors.toList());

        // 遍历每个对象
        for (T obj : list) {
            List<Object> row = new ArrayList<>();
            
            // 对于每个对象，按顺序提取指定注解字段的值
            for (Field field : annotatedFields) {
                try {
                    field.setAccessible(true); // 设置访问权限以获取 private 字段
                    Object value = field.get(obj);
                    row.add(value);
                } catch (IllegalAccessException e) {
                    log.warn("无法访问字段：" + field.getName(), e);
                    row.add(null); // 如果无法访问字段，则添加 null 作为默认值
                }
            }
            result.add(row);
        }

        return result;
    }

}
