package com.seer.teach.admin.convert;

import com.seer.teach.admin.response.AdminModificationLogResp;
import com.seer.teach.teacher.common.utils.JsonDiffUtils;
import com.seer.teach.teacher.module.entity.ModificationLogEntity;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers;

import java.util.List;
import java.util.Map;

/**
 * 修改日志转换器
 *
 * @author Lingma
 * @since 2025-11-27
 */
@Mapper
public interface AdminModificationLogConvert {

    AdminModificationLogConvert INSTANCE = Mappers.getMapper(AdminModificationLogConvert.class);

    /**
     * 将实体转换为响应对象
     *
     * @param entity 修改日志实体
     * @return 修改日志响应对象
     */
    AdminModificationLogResp entityToResponse(ModificationLogEntity entity);

    /**
     * 将实体列表转换为响应对象列表
     *
     * @param entities 修改日志实体列表
     * @return 修改日志响应对象列表
     */
    List<AdminModificationLogResp> entityListToResponseList(List<ModificationLogEntity> entities);

    /**
     * 在映射完成后计算数据变化
     *
     * @param entity 修改日志实体
     * @param resp   修改日志响应对象
     */
    @AfterMapping
    default void calculateChanges(ModificationLogEntity entity, @MappingTarget AdminModificationLogResp resp) {
        // 只有在操作类型为修改时才计算差异
        if (ModificationLogEntity.OPERATION_TYPE_UPDATE != null && 
            ModificationLogEntity.OPERATION_TYPE_UPDATE.equals(entity.getOperationType())) {
            Map<String, String> changes = JsonDiffUtils.diff(entity.getBeforeData(), entity.getAfterData());
            resp.setChanges(changes);
            resp.setHasChanges(!changes.isEmpty());
        } else {
            // 对于新增、删除、查看操作，设置为无变化
            resp.setHasChanges(false);
        }
        
        // 对于新增操作，可以显示新增的数据
        if (ModificationLogEntity.OPERATION_TYPE_ADD != null && 
            ModificationLogEntity.OPERATION_TYPE_ADD.equals(entity.getOperationType())) {
            resp.setHasChanges(true);
        }
        
        // 对于删除操作，可以显示删除前的数据
        if (ModificationLogEntity.OPERATION_TYPE_DELETE != null && 
            ModificationLogEntity.OPERATION_TYPE_DELETE.equals(entity.getOperationType())) {
            resp.setHasChanges(true);
        }
    }
}