package com.ycwl.basic.repository;

import com.ycwl.basic.facebody.enums.FaceBodyAdapterType;
import com.ycwl.basic.integration.common.util.ConfigValueUtil;
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
import com.ycwl.basic.integration.common.response.PageResponse;
import com.ycwl.basic.integration.scenic.service.ScenicIntegrationService;
import com.ycwl.basic.integration.scenic.service.ScenicConfigIntegrationService;
import com.ycwl.basic.integration.scenic.dto.config.ScenicConfigV2DTO;
import com.ycwl.basic.mapper.MpConfigMapper;
import com.ycwl.basic.mapper.MpNotifyConfigMapper;
import com.ycwl.basic.model.pc.mp.MpConfigEntity;
import com.ycwl.basic.model.pc.mp.MpNotifyConfigEntity;
import com.ycwl.basic.model.pc.mp.ScenicMpNotifyVO;
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
import com.ycwl.basic.model.pc.scenic.entity.ScenicEntity;
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
import com.ycwl.basic.pay.enums.PayAdapterType;
import com.ycwl.basic.storage.enums.StorageType;
import com.ycwl.basic.utils.JacksonUtil;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Objects;

@Component
public class ScenicRepository {
    @Autowired
    private MpConfigMapper mpConfigMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private ScenicIntegrationService scenicIntegrationService;
    @Autowired
    private ScenicConfigIntegrationService scenicConfigIntegrationService;

    public static final String SCENIC_MP_CACHE_KEY = "scenic:%s:mp";
    public static final String SCENIC_MP_NOTIFY_CACHE_KEY = "scenic:%s:mpNotify";
    @Autowired
    private MpNotifyConfigMapper mpNotifyConfigMapper;

    public ScenicV2DTO getScenicBasic(Long id) {
        ScenicV2DTO scenicDTO = scenicIntegrationService.getScenic(id);
        return scenicDTO;
    }

    public ScenicEntity getScenic(Long id) {
        // 分别获取景区基础信息和配置信息
        ScenicV2DTO scenicBasic = scenicIntegrationService.getScenic(id);
        ScenicConfigManager configManager = getScenicConfigManager(id);

        ScenicEntity scenicEntity = convertToScenicEntity(scenicBasic, configManager);
        return scenicEntity;
    }

    @Deprecated
    public ScenicConfigEntity getScenicConfig(Long scenicId) {
        ScenicConfigManager scenicConfigManager = getScenicConfigManager(scenicId);
        ScenicConfigEntity config = new ScenicConfigEntity();

        // 基础配置
        config.setScenicId(scenicId);
        if (scenicConfigManager == null) {
            return config;
        }

        // 业务流程配置
        config.setBookRoutine(scenicConfigManager.getInteger("book_routine"));
        config.setForceFinishTime(scenicConfigManager.getInteger("force_finish_time"));
        config.setTourTime(scenicConfigManager.getInteger("tour_time"));
        
        // 存储时间配置
        config.setSampleStoreDay(scenicConfigManager.getInteger("sample_store_day"));
        config.setFaceStoreDay(scenicConfigManager.getInteger("face_store_day"));
        config.setVideoStoreDay(scenicConfigManager.getInteger("video_store_day"));
        config.setVideoSourceStoreDay(scenicConfigManager.getInteger("video_source_store_day"));
        config.setImageSourceStoreDay(scenicConfigManager.getInteger("image_source_store_day"));
        config.setUserSourceExpireDay(scenicConfigManager.getInteger("user_source_expire_day"));
        
        // 功能开关配置
        config.setAllFree(scenicConfigManager.getBoolean("all_free"));
        config.setDisableSourceVideo(scenicConfigManager.getBoolean("disable_source_video"));
        config.setDisableSourceImage(scenicConfigManager.getBoolean("disable_source_image"));
        config.setVoucherEnable(scenicConfigManager.getBoolean("voucher_enable"));
        
        // 模板和防录屏配置
        config.setTemplateNewVideoType(scenicConfigManager.getInteger("template_new_video_type"));
        config.setAntiScreenRecordType(scenicConfigManager.getInteger("anti_screen_record_type"));
        
        // 人脸识别配置
        config.setFaceScoreThreshold(scenicConfigManager.getFloat("face_score_threshold"));
        config.setFaceDetectHelperThreshold(scenicConfigManager.getInteger("face_detect_helper_threshold"));
        config.setFaceType(scenicConfigManager.getEnum("face_type", FaceBodyAdapterType.class));
        config.setFaceConfigJson(scenicConfigManager.getString("face_config_json"));
        
        // 存储配置
        config.setStoreType(scenicConfigManager.getEnum("store_type", StorageType.class));
        config.setStoreConfigJson(scenicConfigManager.getString("store_config_json"));
        config.setTmpStoreType(scenicConfigManager.getEnum("tmp_store_type", StorageType.class));
        config.setTmpStoreConfigJson(scenicConfigManager.getString("tmp_store_config_json"));
        config.setLocalStoreType(scenicConfigManager.getEnum("local_store_type", StorageType.class));
        config.setLocalStoreConfigJson(scenicConfigManager.getString("local_store_config_json"));
        
        // 支付配置
        config.setPayType(scenicConfigManager.getEnum("pay_type", PayAdapterType.class));
        config.setPayConfigJson(scenicConfigManager.getString("pay_config_json"));
        
        // 推客配置
        config.setBrokerDirectRate(scenicConfigManager.getBigDecimal("broker_direct_rate"));
        
        // 水印配置
        config.setWatermarkType(scenicConfigManager.getString("watermark_type"));
        config.setWatermarkScenicText(scenicConfigManager.getString("watermark_scenic_text"));
        config.setWatermarkDtFormat(scenicConfigManager.getString("watermark_dt_format"));
        
        // 提示信息配置
        config.setImageSourcePackHint(scenicConfigManager.getString("image_source_pack_hint"));
        config.setVideoSourcePackHint(scenicConfigManager.getString("video_source_pack_hint"));
        config.setExtraNotificationTime(scenicConfigManager.getString("extra_notification_time"));
        
        // 免费数量配置
        config.setPhotoFreeNum(scenicConfigManager.getInteger("photo_free_num"));
        config.setVideoFreeNum(scenicConfigManager.getInteger("video_free_num"));

        return config;
    }

    public MpConfigEntity getScenicMpConfig(Long scenicId) {
        if (redisTemplate.hasKey(String.format(SCENIC_MP_CACHE_KEY, scenicId))) {
            return JacksonUtil.parseObject(redisTemplate.opsForValue().get(String.format(SCENIC_MP_CACHE_KEY, scenicId)), MpConfigEntity.class);
        }
        ScenicEntity scenic = getScenic(scenicId);
        MpConfigEntity mpConfigEntity = mpConfigMapper.selectById(scenic.getMpId());
        if (mpConfigEntity != null) {
            redisTemplate.opsForValue().set(String.format(SCENIC_MP_CACHE_KEY, scenicId), JacksonUtil.toJSONString(mpConfigEntity));
        }
        return mpConfigEntity;
    }

    public ScenicMpNotifyVO getScenicMpNotifyConfig(Long scenicId) {
        if (redisTemplate.hasKey(String.format(SCENIC_MP_NOTIFY_CACHE_KEY, scenicId))) {
            return JacksonUtil.parseObject(redisTemplate.opsForValue().get(String.format(SCENIC_MP_NOTIFY_CACHE_KEY, scenicId)), ScenicMpNotifyVO.class);
        }
        MpConfigEntity mpConfig = getScenicMpConfig(scenicId);
        if (mpConfig == null) {
            return null;
        }
        ScenicMpNotifyVO mpNotifyConfig = new ScenicMpNotifyVO();
        mpNotifyConfig.setAppId(mpConfig.getAppId());
        mpNotifyConfig.setAppSecret(mpConfig.getAppSecret());
        mpNotifyConfig.setMpId(mpConfig.getId());
        mpNotifyConfig.setAppState(mpConfig.getState());
        List<MpNotifyConfigEntity> mpNotifyConfigList = mpNotifyConfigMapper.listByMpId(mpConfig.getId());
        mpNotifyConfigList.forEach(item -> {
            switch (item.getType()) {
                case 0:
                    mpNotifyConfig.setVideoGeneratedTemplateId(item.getTemplateId());
                    break;
                case 1:
                    mpNotifyConfig.setVideoDownloadTemplateId(item.getTemplateId());
                    break;
                case 2:
                    mpNotifyConfig.setVideoPreExpireTemplateId(item.getTemplateId());
                    break;
            }
        });
        redisTemplate.opsForValue().set(String.format(SCENIC_MP_NOTIFY_CACHE_KEY, scenicId), JacksonUtil.toJSONString(mpNotifyConfig));
        return mpNotifyConfig;
    }

    public String getVideoGeneratedTemplateId(Long scenicId) {
        ScenicMpNotifyVO scenicMpNotifyConfig = getScenicMpNotifyConfig(scenicId);
        if (scenicMpNotifyConfig != null) {
            return scenicMpNotifyConfig.getVideoGeneratedTemplateId();
        }
        return null;
    }

    public String getVideoDownloadTemplateId(Long scenicId) {
        ScenicMpNotifyVO scenicMpNotifyConfig = getScenicMpNotifyConfig(scenicId);
        if (scenicMpNotifyConfig != null) {
            return scenicMpNotifyConfig.getVideoDownloadTemplateId();
        }
        return null;
    }

    public String getVideoPreExpireTemplateId(Long scenicId) {
        ScenicMpNotifyVO scenicMpNotifyConfig = getScenicMpNotifyConfig(scenicId);
        if (scenicMpNotifyConfig != null) {
            return scenicMpNotifyConfig.getVideoPreExpireTemplateId();
        }
        return null;
    }

    public List<ScenicV2DTO> list(ScenicReqQuery scenicReqQuery) {
        try {
            // 将 ScenicReqQuery 参数转换为 zt-scenic 服务需要的参数
            Integer page = scenicReqQuery.getPageNum();
            Integer pageSize = scenicReqQuery.getPageSize();
            Integer status = null;
            if (scenicReqQuery.getStatus() != null) {
                status = Integer.valueOf(scenicReqQuery.getStatus());
            }
            String name = scenicReqQuery.getName();
            
            // 调用 zt-scenic 服务的 list 方法
            PageResponse<ScenicV2DTO> response = scenicIntegrationService.listScenics(page, pageSize, status, name);
            
            // 将 ScenicV2DTO 列表转换为 ScenicEntity 列表
            if (response != null && response.getList() != null) {
                return response.getList();
            }
            return new java.util.ArrayList<>();
        } catch (Exception e) {
            // 如果调用失败，返回空列表
            return new java.util.ArrayList<>();
        }
    }

    private ScenicEntity convertToScenicEntity(ScenicV2DTO dto, ScenicConfigManager configManager) {
        if (dto == null) {
            return null;
        }
        ScenicEntity entity = new ScenicEntity();
        entity.setId(Long.parseLong(dto.getId()));
        entity.setName(dto.getName());
        entity.setMpId(dto.getMpId());
        entity.setStatus(dto.getStatus().toString());
        entity.setAddress(configManager.getString("address"));
        entity.setArea(configManager.getString("area"));
        entity.setCity(configManager.getString("city"));
        entity.setProvince(configManager.getString("province"));
        entity.setLatitude(configManager.getBigDecimal("latitude"));
        entity.setLongitude(configManager.getBigDecimal("longitude"));
        entity.setRadius(configManager.getBigDecimal("radius"));
        entity.setPhone(configManager.getString("phone"));
        entity.setLogoUrl(configManager.getString("logo_url"));
        entity.setCoverUrl(configManager.getString("cover_url"));
        entity.setKfCodeUrl(configManager.getString("kf_code_url"));
        return entity;
    }

    /**
     * 获取景区配置管理器
     * 
     * @param scenicId 景区ID
     * @return ScenicConfigManager实例，如果获取失败返回null
     */
    public ScenicConfigManager getScenicConfigManager(Long scenicId) {
        try {
            List<ScenicConfigV2DTO> configList = scenicConfigIntegrationService.listConfigs(scenicId);
            return new ScenicConfigManager(Objects.requireNonNullElse(configList, Collections.emptyList()));
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 批量获取景区名称
     * @param scenicIds 景区ID列表
     * @return 景区ID到景区名称的映射
     */
    public Map<Long, String> batchGetScenicNames(List<Long> scenicIds) {
        if (scenicIds == null || scenicIds.isEmpty()) {
            return new HashMap<>();
        }

        Map<Long, String> result = new HashMap<>();
        for (Long scenicId : scenicIds) {
            try {
                ScenicV2DTO scenic = getScenicBasic(scenicId);
                if (scenic != null) {
                    result.put(scenicId, scenic.getName());
                }
            } catch (Exception e) {
                // 获取失败时使用默认值
                result.put(scenicId, "未知景区");
            }
        }
        return result;
    }

    /**
     * 批量获取景区完整信息
     * @param scenicIds 景区ID列表
     * @return 景区ID到景区实体的映射
     */
    public Map<Long, ScenicEntity> batchGetScenics(List<Long> scenicIds) {
        if (scenicIds == null || scenicIds.isEmpty()) {
            return new HashMap<>();
        }

        Map<Long, ScenicEntity> result = new HashMap<>();
        for (Long scenicId : scenicIds) {
            try {
                ScenicEntity scenic = getScenic(scenicId);
                if (scenic != null) {
                    result.put(scenicId, scenic);
                }
            } catch (Exception e) {
                // 获取失败时记录日志但不中断处理
                System.err.println("获取景区信息失败: " + scenicId + ", 错误: " + e.getMessage());
            }
        }
        return result;
    }

    /**
     * 批量获取景区基础信息DTO
     * @param scenicIds 景区ID列表
     * @return 景区ID到景区DTO的映射
     */
    public Map<Long, ScenicV2DTO> batchGetScenicBasics(List<Long> scenicIds) {
        if (scenicIds == null || scenicIds.isEmpty()) {
            return new HashMap<>();
        }

        Map<Long, ScenicV2DTO> result = new HashMap<>();
        for (Long scenicId : scenicIds) {
            try {
                ScenicV2DTO scenic = getScenicBasic(scenicId);
                if (scenic != null) {
                    result.put(scenicId, scenic);
                }
            } catch (Exception e) {
                // 获取失败时记录日志但不中断处理
                System.err.println("获取景区基础信息失败: " + scenicId + ", 错误: " + e.getMessage());
            }
        }
        return result;
    }

}
