package com.ycwl.basic.repository;

import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.pricing.dto.VoucherInfo;
import com.ycwl.basic.pricing.enums.VoucherDiscountType;
import com.ycwl.basic.pricing.service.IVoucherService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Component
public class SourceRepository {
    @Autowired
    private SourceMapper sourceMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private IVoucherService iVoucherService;
    @Autowired
    private FaceRepository faceRepository;
    @Autowired
    private TemplateRepository templateRepository;
    @Autowired
    private DeviceRepository deviceRepository;
    @Autowired
    private MemberRelationRepository memberRelationRepository;

    public void addSource(SourceEntity source) {
        sourceMapper.add(source);
    }

    public void setUserIsBuyItem(Long memberId, int type, Long faceId, Long orderId) {
        MemberSourceEntity memberSource = new MemberSourceEntity();
        memberSource.setMemberId(memberId);
        memberSource.setFaceId(faceId);
        memberSource.setType(type);
        memberSource.setOrderId(orderId);
        memberSource.setIsBuy(1);
        sourceMapper.updateRelation(memberSource);
        memberRelationRepository.clearSCacheByFace(faceId);
    }

    public void setUserNotBuyItem(Long memberId, int type, Long faceId) {
        MemberSourceEntity memberSource = new MemberSourceEntity();
        memberSource.setMemberId(memberId);
        memberSource.setFaceId(faceId);
        memberSource.setType(type);
        memberSource.setOrderId(null);
        memberSource.setIsBuy(0);
        sourceMapper.updateRelation(memberSource);
        memberRelationRepository.clearSCacheByFace(faceId);
    }

    public boolean getUserIsBuy(Long userId, int type, Long faceId) {
        FaceEntity face = faceRepository.getFace(faceId);
        if (face == null) {
            log.info("faceId:{} is not exist", faceId);
            return false;
        }
        // 确认人员faceId是否有券码
        List<VoucherInfo> voucherDetails = iVoucherService.getVoucherDetails(faceId, face.getScenicId());
        if (voucherDetails != null && !voucherDetails.isEmpty()) {
            VoucherInfo voucherInfo = voucherDetails.getFirst();
            if (voucherInfo.getDiscountType().equals(VoucherDiscountType.FREE_ALL)) {
                return true;
            }
        }
        switch (type) {
            case 1:
                List<SourceEntity> videoSourceList = sourceMapper.listVideoByFaceRelation(userId, faceId);
                if (videoSourceList == null || videoSourceList.isEmpty()) {
                    return false;
                }
                return videoSourceList.stream().filter(Objects::nonNull).anyMatch(item -> Integer.valueOf(1).equals(item.getIsBuy()));
            case 2:
                List<SourceEntity> imageSourceList = sourceMapper.listImageByFaceRelation(userId, faceId);
                if (imageSourceList == null || imageSourceList.isEmpty()) {
                    return false;
                }
                return imageSourceList.stream().filter(Objects::nonNull).anyMatch(item -> Integer.valueOf(1).equals(item.getIsBuy()));
            default:
                return false;
        }
    }

    public SourceEntity getSource(Long id) {
        return sourceMapper.getEntity(id);
    }

    public Map<String, List<SourceEntity>> getTaskParams(Long faceId, Long templateId) {
        FaceEntity face = faceRepository.getFace(faceId);
        if (face == null) {
            log.info("getTaskParams: faceId:{} is not exist", faceId);
            return Map.of();
        }

        List<SourceEntity> videoSourceList = sourceMapper.listVideoByScenicFaceRelation(face.getScenicId(), faceId);
        Map<String, List<SourceEntity>> sourcesMap = videoSourceList.stream()
                .peek(item -> item.setUrl(item.getVideoUrl()))
                .filter(item -> item.getDeviceId() != null)
                .filter(item -> {
                    DeviceEntity device = deviceRepository.getDevice(item.getDeviceId());
                    if (device == null) {
                        log.info("getTaskParams: deviceId:{} is not exist", item.getDeviceId());
                        return false;
                    }
                    return Integer.valueOf(1).equals(device.getStatus());
                })
                .collect(Collectors.groupingBy(item -> item.getDeviceId().toString()));

        if (sourcesMap.isEmpty()) {
            log.info("getTaskParams: 没有视频源，templateId: {}", templateId);
            return Map.of();
        }

        List<String> templatePlaceholder = templateRepository.getTemplatePlaceholder(templateId);
        if (templatePlaceholder.stream().distinct().count() == templatePlaceholder.size()) {
            sourcesMap.forEach((key, value) -> {
                value.removeIf(item -> !value.getFirst().equals(item));
            });
        } else {
            // 找出重复的templatePlaceholder，修改对应的sourceMap[key]中的list顺序为倒序
            Map<String, Long> placeholderCounts = templatePlaceholder.stream()
                    .collect(Collectors.groupingBy(placeholder -> placeholder, Collectors.counting()));
            
            placeholderCounts.entrySet().stream()
                    .filter(entry -> entry.getValue() > 1)
                    .map(Map.Entry::getKey)
                    .forEach(duplicatePlaceholder -> {
                        // 对于重复的占位符，找到对应的设备ID并倒序sourceMap中的列表
                        if (sourcesMap.containsKey(duplicatePlaceholder)) {
                            List<SourceEntity> sourceList = sourcesMap.get(duplicatePlaceholder);
                            java.util.Collections.reverse(sourceList);
                        }
                    });
        }

        boolean hasPPlaceholder = templatePlaceholder.stream().anyMatch(placeholder -> placeholder.startsWith("P"));
        if (hasPPlaceholder) {
            List<SourceEntity> imageSourceList = sourceMapper.listImageSourcesByFaceId(faceId);
            if (!imageSourceList.isEmpty()) {
                Map<String, List<SourceEntity>> imageSourceMap = imageSourceList.stream()
                        .peek(item -> item.setUrl(item.getUrl()))
                        .filter(item -> item.getDeviceId() != null)
                        .filter(item -> {
                            DeviceEntity device = deviceRepository.getDevice(item.getDeviceId());
                            if (device == null) {
                                return false;
                            }
                            return Integer.valueOf(1).equals(device.getStatus());
                        })
                        .collect(Collectors.groupingBy(item -> "P" + item.getDeviceId().toString()));

                imageSourceMap.forEach((key, value) -> {
                    sourcesMap.merge(key, value, (existing, replacement) -> {
                        existing.addAll(replacement);
                        return existing;
                    });
                });
            }
        }

        return sourcesMap;
    }
}
