package com.ycwl.basic.service.pc.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.fasterxml.jackson.databind.JsonNode;
import com.ycwl.basic.mapper.WechatSubscribeEventTemplateMapper;
import com.ycwl.basic.mapper.WechatSubscribeSceneTemplateMapper;
import com.ycwl.basic.mapper.WechatSubscribeSendLogMapper;
import com.ycwl.basic.mapper.WechatSubscribeTemplateConfigMapper;
import com.ycwl.basic.model.pc.notify.entity.WechatSubscribeEventTemplateEntity;
import com.ycwl.basic.model.pc.notify.entity.WechatSubscribeSceneTemplateEntity;
import com.ycwl.basic.model.pc.notify.entity.WechatSubscribeSendLogEntity;
import com.ycwl.basic.model.pc.notify.entity.WechatSubscribeTemplateConfigEntity;
import com.ycwl.basic.model.pc.notify.req.WechatSubscribeEventTemplatePageReq;
import com.ycwl.basic.model.pc.notify.req.WechatSubscribeEventTemplateSaveReq;
import com.ycwl.basic.model.pc.notify.req.WechatSubscribeSceneTemplatePageReq;
import com.ycwl.basic.model.pc.notify.req.WechatSubscribeSceneTemplateSaveReq;
import com.ycwl.basic.model.pc.notify.req.WechatSubscribeSendLogPageReq;
import com.ycwl.basic.model.pc.notify.req.WechatSubscribeTemplateConfigPageReq;
import com.ycwl.basic.model.pc.notify.req.WechatSubscribeTemplateConfigSaveReq;
import com.ycwl.basic.service.notify.WechatSubscribeNotifyConfigService;
import com.ycwl.basic.service.pc.WechatSubscribeNotifyAdminService;
import com.ycwl.basic.utils.ApiResponse;
import com.ycwl.basic.utils.JacksonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 微信小程序订阅消息：配置管理（管理后台）
 *
 * @Author: System
 * @Date: 2025/12/31
 */
@Service
@Slf4j
public class WechatSubscribeNotifyAdminServiceImpl implements WechatSubscribeNotifyAdminService {

    private static final int MAX_PAGE_SIZE = 200;

    private final WechatSubscribeTemplateConfigMapper templateConfigMapper;
    private final WechatSubscribeSceneTemplateMapper sceneTemplateMapper;
    private final WechatSubscribeEventTemplateMapper eventTemplateMapper;
    private final WechatSubscribeSendLogMapper sendLogMapper;
    private final WechatSubscribeNotifyConfigService configService;

    public WechatSubscribeNotifyAdminServiceImpl(WechatSubscribeTemplateConfigMapper templateConfigMapper,
                                                 WechatSubscribeSceneTemplateMapper sceneTemplateMapper,
                                                 WechatSubscribeEventTemplateMapper eventTemplateMapper,
                                                 WechatSubscribeSendLogMapper sendLogMapper,
                                                 WechatSubscribeNotifyConfigService configService) {
        this.templateConfigMapper = templateConfigMapper;
        this.sceneTemplateMapper = sceneTemplateMapper;
        this.eventTemplateMapper = eventTemplateMapper;
        this.sendLogMapper = sendLogMapper;
        this.configService = configService;
    }

    @Override
    public ApiResponse<PageInfo<WechatSubscribeTemplateConfigEntity>> pageTemplateConfig(WechatSubscribeTemplateConfigPageReq req) {
        try {
            if (req == null) {
                req = new WechatSubscribeTemplateConfigPageReq();
            }
            sanitizePage(req);

            QueryWrapper<WechatSubscribeTemplateConfigEntity> wrapper = new QueryWrapper<>();
            if (req.getScenicId() != null) {
                wrapper.eq("scenic_id", req.getScenicId());
            }
            if (StringUtils.isNotBlank(req.getTemplateKey())) {
                wrapper.like("template_key", req.getTemplateKey().trim());
            }
            if (StringUtils.isNotBlank(req.getWechatTemplateId())) {
                wrapper.like("wechat_template_id", req.getWechatTemplateId().trim());
            }
            if (req.getEnabled() != null) {
                wrapper.eq("enabled", req.getEnabled());
            }
            wrapper.orderByDesc("scenic_id").orderByDesc("update_time").orderByDesc("id");

            PageHelper.startPage(req.getPageNum(), req.getPageSize());
            List<WechatSubscribeTemplateConfigEntity> list = templateConfigMapper.selectList(wrapper);
            return ApiResponse.success(new PageInfo<>(list));
        } catch (Exception e) {
            log.error("订阅消息|模板配置分页查询失败", e);
            return ApiResponse.fail("模板配置分页查询失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<WechatSubscribeTemplateConfigEntity> getTemplateConfig(Long id) {
        try {
            if (id == null) {
                return ApiResponse.fail("id不能为空");
            }
            return ApiResponse.success(templateConfigMapper.selectById(id));
        } catch (Exception e) {
            log.error("订阅消息|模板配置详情查询失败 id={}", id, e);
            return ApiResponse.fail("模板配置详情查询失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<Boolean> saveTemplateConfig(WechatSubscribeTemplateConfigSaveReq req) {
        try {
            String err = validateTemplateConfigSaveReq(req);
            if (err != null) {
                return ApiResponse.fail(err);
            }

            WechatSubscribeTemplateConfigEntity entity = new WechatSubscribeTemplateConfigEntity();
            entity.setTemplateKey(req.getTemplateKey().trim());
            entity.setScenicId(req.getScenicId());
            entity.setWechatTemplateId(req.getWechatTemplateId().trim());
            entity.setEnabled(req.getEnabled());
            entity.setTitleTemplate(StringUtils.trimToNull(req.getTitleTemplate()));
            entity.setContentTemplate(StringUtils.trimToNull(req.getContentTemplate()));
            entity.setPageTemplate(StringUtils.trimToNull(req.getPageTemplate()));
            entity.setDataTemplateJson(StringUtils.trimToNull(req.getDataTemplateJson()));
            entity.setDescription(StringUtils.trimToNull(req.getDescription()));
            entity.setUpdateTime(new Date());

            boolean success;
            if (req.getId() != null) {
                WechatSubscribeTemplateConfigEntity existing = templateConfigMapper.selectById(req.getId());
                if (existing == null) {
                    return ApiResponse.fail("记录不存在");
                }
                entity.setId(req.getId());
                success = templateConfigMapper.updateById(entity) > 0;
            } else {
                // upsert by (template_key, scenic_id)
                WechatSubscribeTemplateConfigEntity existing = templateConfigMapper.selectOne(new QueryWrapper<WechatSubscribeTemplateConfigEntity>()
                        .eq("template_key", entity.getTemplateKey())
                        .eq("scenic_id", entity.getScenicId()));
                if (existing != null) {
                    entity.setId(existing.getId());
                    success = templateConfigMapper.updateById(entity) > 0;
                } else {
                    entity.setCreateTime(new Date());
                    success = templateConfigMapper.insert(entity) > 0;
                }
            }

            // 清除缓存：模板配置变更影响场景和事件查询
            if (success) {
                clearConfigCacheByScenic(req.getScenicId());
            }
            return ApiResponse.success(success);
        } catch (DuplicateKeyException e) {
            return ApiResponse.fail("保存失败：唯一键冲突（templateKey+scenicId已存在）");
        } catch (Exception e) {
            log.error("订阅消息|模板配置保存失败", e);
            return ApiResponse.fail("模板配置保存失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<Boolean> deleteTemplateConfig(Long id) {
        try {
            if (id == null) {
                return ApiResponse.fail("id不能为空");
            }
            // 先查询获取 scenicId 用于清除缓存
            WechatSubscribeTemplateConfigEntity existing = templateConfigMapper.selectById(id);
            if (existing == null) {
                return ApiResponse.success(false);
            }
            boolean success = templateConfigMapper.deleteById(id) > 0;
            // 清除缓存
            if (success) {
                clearConfigCacheByScenic(existing.getScenicId());
            }
            return ApiResponse.success(success);
        } catch (Exception e) {
            log.error("订阅消息|模板配置删除失败 id={}", id, e);
            return ApiResponse.fail("模板配置删除失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<PageInfo<WechatSubscribeSceneTemplateEntity>> pageSceneTemplate(WechatSubscribeSceneTemplatePageReq req) {
        try {
            if (req == null) {
                req = new WechatSubscribeSceneTemplatePageReq();
            }
            sanitizePage(req);

            QueryWrapper<WechatSubscribeSceneTemplateEntity> wrapper = new QueryWrapper<>();
            if (req.getScenicId() != null) {
                wrapper.eq("scenic_id", req.getScenicId());
            }
            if (StringUtils.isNotBlank(req.getSceneKey())) {
                wrapper.like("scene_key", req.getSceneKey().trim());
            }
            if (StringUtils.isNotBlank(req.getTemplateKey())) {
                wrapper.like("template_key", req.getTemplateKey().trim());
            }
            if (req.getEnabled() != null) {
                wrapper.eq("enabled", req.getEnabled());
            }
            wrapper.orderByDesc("scenic_id").orderByAsc("sort_order").orderByDesc("id");

            PageHelper.startPage(req.getPageNum(), req.getPageSize());
            List<WechatSubscribeSceneTemplateEntity> list = sceneTemplateMapper.selectList(wrapper);
            return ApiResponse.success(new PageInfo<>(list));
        } catch (Exception e) {
            log.error("订阅消息|场景映射分页查询失败", e);
            return ApiResponse.fail("场景映射分页查询失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<WechatSubscribeSceneTemplateEntity> getSceneTemplate(Long id) {
        try {
            if (id == null) {
                return ApiResponse.fail("id不能为空");
            }
            return ApiResponse.success(sceneTemplateMapper.selectById(id));
        } catch (Exception e) {
            log.error("订阅消息|场景映射详情查询失败 id={}", id, e);
            return ApiResponse.fail("场景映射详情查询失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<Boolean> saveSceneTemplate(WechatSubscribeSceneTemplateSaveReq req) {
        try {
            String err = validateSceneTemplateSaveReq(req);
            if (err != null) {
                return ApiResponse.fail(err);
            }

            WechatSubscribeSceneTemplateEntity entity = new WechatSubscribeSceneTemplateEntity();
            entity.setSceneKey(req.getSceneKey().trim());
            entity.setTemplateKey(req.getTemplateKey().trim());
            entity.setScenicId(req.getScenicId());
            entity.setEnabled(req.getEnabled());
            entity.setSortOrder(Objects.requireNonNullElse(req.getSortOrder(), 0));
            entity.setUpdateTime(new Date());

            boolean success;
            if (req.getId() != null) {
                WechatSubscribeSceneTemplateEntity existing = sceneTemplateMapper.selectById(req.getId());
                if (existing == null) {
                    return ApiResponse.fail("记录不存在");
                }
                entity.setId(req.getId());
                success = sceneTemplateMapper.updateById(entity) > 0;
            } else {
                WechatSubscribeSceneTemplateEntity existing = sceneTemplateMapper.selectOne(new QueryWrapper<WechatSubscribeSceneTemplateEntity>()
                        .eq("scene_key", entity.getSceneKey())
                        .eq("template_key", entity.getTemplateKey())
                        .eq("scenic_id", entity.getScenicId()));
                if (existing != null) {
                    entity.setId(existing.getId());
                    success = sceneTemplateMapper.updateById(entity) > 0;
                } else {
                    entity.setCreateTime(new Date());
                    success = sceneTemplateMapper.insert(entity) > 0;
                }
            }

            // 清除场景配置缓存
            if (success) {
                configService.clearSceneConfigsCache(req.getScenicId(), req.getSceneKey().trim());
            }
            return ApiResponse.success(success);
        } catch (DuplicateKeyException e) {
            return ApiResponse.fail("保存失败：唯一键冲突（sceneKey+templateKey+scenicId已存在）");
        } catch (Exception e) {
            log.error("订阅消息|场景映射保存失败", e);
            return ApiResponse.fail("场景映射保存失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<Boolean> deleteSceneTemplate(Long id) {
        try {
            if (id == null) {
                return ApiResponse.fail("id不能为空");
            }
            // 先查询获取 scenicId 和 sceneKey 用于清除缓存
            WechatSubscribeSceneTemplateEntity existing = sceneTemplateMapper.selectById(id);
            if (existing == null) {
                return ApiResponse.success(false);
            }
            boolean success = sceneTemplateMapper.deleteById(id) > 0;
            // 清除场景配置缓存
            if (success) {
                configService.clearSceneConfigsCache(existing.getScenicId(), existing.getSceneKey());
            }
            return ApiResponse.success(success);
        } catch (Exception e) {
            log.error("订阅消息|场景映射删除失败 id={}", id, e);
            return ApiResponse.fail("场景映射删除失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<PageInfo<WechatSubscribeEventTemplateEntity>> pageEventTemplate(WechatSubscribeEventTemplatePageReq req) {
        try {
            if (req == null) {
                req = new WechatSubscribeEventTemplatePageReq();
            }
            sanitizePage(req);

            QueryWrapper<WechatSubscribeEventTemplateEntity> wrapper = new QueryWrapper<>();
            if (req.getScenicId() != null) {
                wrapper.eq("scenic_id", req.getScenicId());
            }
            if (StringUtils.isNotBlank(req.getEventKey())) {
                wrapper.like("event_key", req.getEventKey().trim());
            }
            if (StringUtils.isNotBlank(req.getTemplateKey())) {
                wrapper.like("template_key", req.getTemplateKey().trim());
            }
            if (req.getEnabled() != null) {
                wrapper.eq("enabled", req.getEnabled());
            }
            wrapper.orderByDesc("scenic_id").orderByAsc("sort_order").orderByDesc("id");

            PageHelper.startPage(req.getPageNum(), req.getPageSize());
            List<WechatSubscribeEventTemplateEntity> list = eventTemplateMapper.selectList(wrapper);
            return ApiResponse.success(new PageInfo<>(list));
        } catch (Exception e) {
            log.error("订阅消息|事件映射分页查询失败", e);
            return ApiResponse.fail("事件映射分页查询失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<WechatSubscribeEventTemplateEntity> getEventTemplate(Long id) {
        try {
            if (id == null) {
                return ApiResponse.fail("id不能为空");
            }
            return ApiResponse.success(eventTemplateMapper.selectById(id));
        } catch (Exception e) {
            log.error("订阅消息|事件映射详情查询失败 id={}", id, e);
            return ApiResponse.fail("事件映射详情查询失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<Boolean> saveEventTemplate(WechatSubscribeEventTemplateSaveReq req) {
        try {
            String err = validateEventTemplateSaveReq(req);
            if (err != null) {
                return ApiResponse.fail(err);
            }

            WechatSubscribeEventTemplateEntity entity = new WechatSubscribeEventTemplateEntity();
            entity.setEventKey(req.getEventKey().trim());
            entity.setTemplateKey(req.getTemplateKey().trim());
            entity.setScenicId(req.getScenicId());
            entity.setEnabled(req.getEnabled());
            entity.setSortOrder(Objects.requireNonNullElse(req.getSortOrder(), 0));
            entity.setSendDelaySeconds(Objects.requireNonNullElse(req.getSendDelaySeconds(), 0));
            entity.setDedupSeconds(Objects.requireNonNullElse(req.getDedupSeconds(), 0));
            entity.setUpdateTime(new Date());

            boolean success;
            if (req.getId() != null) {
                WechatSubscribeEventTemplateEntity existing = eventTemplateMapper.selectById(req.getId());
                if (existing == null) {
                    return ApiResponse.fail("记录不存在");
                }
                entity.setId(req.getId());
                success = eventTemplateMapper.updateById(entity) > 0;
            } else {
                WechatSubscribeEventTemplateEntity existing = eventTemplateMapper.selectOne(new QueryWrapper<WechatSubscribeEventTemplateEntity>()
                        .eq("event_key", entity.getEventKey())
                        .eq("template_key", entity.getTemplateKey())
                        .eq("scenic_id", entity.getScenicId()));
                if (existing != null) {
                    entity.setId(existing.getId());
                    success = eventTemplateMapper.updateById(entity) > 0;
                } else {
                    entity.setCreateTime(new Date());
                    success = eventTemplateMapper.insert(entity) > 0;
                }
            }

            // 清除事件配置缓存
            if (success) {
                configService.clearEventConfigsCache(req.getScenicId(), req.getEventKey().trim());
            }
            return ApiResponse.success(success);
        } catch (DuplicateKeyException e) {
            return ApiResponse.fail("保存失败：唯一键冲突（eventKey+templateKey+scenicId已存在）");
        } catch (Exception e) {
            log.error("订阅消息|事件映射保存失败", e);
            return ApiResponse.fail("事件映射保存失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<Boolean> deleteEventTemplate(Long id) {
        try {
            if (id == null) {
                return ApiResponse.fail("id不能为空");
            }
            // 先查询获取 scenicId 和 eventKey 用于清除缓存
            WechatSubscribeEventTemplateEntity existing = eventTemplateMapper.selectById(id);
            if (existing == null) {
                return ApiResponse.success(false);
            }
            boolean success = eventTemplateMapper.deleteById(id) > 0;
            // 清除事件配置缓存
            if (success) {
                configService.clearEventConfigsCache(existing.getScenicId(), existing.getEventKey());
            }
            return ApiResponse.success(success);
        } catch (Exception e) {
            log.error("订阅消息|事件映射删除失败 id={}", id, e);
            return ApiResponse.fail("事件映射删除失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<PageInfo<WechatSubscribeSendLogEntity>> pageSendLog(WechatSubscribeSendLogPageReq req) {
        try {
            if (req == null) {
                req = new WechatSubscribeSendLogPageReq();
            }
            sanitizePage(req);

            QueryWrapper<WechatSubscribeSendLogEntity> wrapper = new QueryWrapper<>();
            if (req.getScenicId() != null) {
                wrapper.eq("scenic_id", req.getScenicId());
            }
            if (req.getMemberId() != null) {
                wrapper.eq("member_id", req.getMemberId());
            }
            if (StringUtils.isNotBlank(req.getEventKey())) {
                wrapper.eq("event_key", req.getEventKey().trim());
            }
            if (StringUtils.isNotBlank(req.getTemplateKey())) {
                wrapper.eq("template_key", req.getTemplateKey().trim());
            }
            if (StringUtils.isNotBlank(req.getStatus())) {
                wrapper.eq("status", req.getStatus().trim());
            }
            wrapper.orderByDesc("create_time").orderByDesc("id");

            PageHelper.startPage(req.getPageNum(), req.getPageSize());
            List<WechatSubscribeSendLogEntity> list = sendLogMapper.selectList(wrapper);
            return ApiResponse.success(new PageInfo<>(list));
        } catch (Exception e) {
            log.error("订阅消息|发送日志分页查询失败", e);
            return ApiResponse.fail("发送日志分页查询失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<WechatSubscribeSendLogEntity> getSendLog(Long id) {
        try {
            if (id == null) {
                return ApiResponse.fail("id不能为空");
            }
            return ApiResponse.success(sendLogMapper.selectById(id));
        } catch (Exception e) {
            log.error("订阅消息|发送日志详情查询失败 id={}", id, e);
            return ApiResponse.fail("发送日志详情查询失败: " + e.getMessage());
        }
    }

    private static void sanitizePage(Object req) {
        if (req instanceof com.ycwl.basic.model.common.BaseQueryParameterReq base) {
            if (base.getPageNum() == null || base.getPageNum() < 1) {
                base.setPageNum(1);
            }
            if (base.getPageSize() == null || base.getPageSize() < 1) {
                base.setPageSize(10);
            }
            if (base.getPageSize() > MAX_PAGE_SIZE) {
                base.setPageSize(MAX_PAGE_SIZE);
            }
        }
    }

    private static String validateEnabled(Integer enabled) {
        if (enabled == null) {
            return "enabled不能为空";
        }
        if (!Objects.equals(enabled, 0) && !Objects.equals(enabled, 1)) {
            return "enabled仅支持0或1";
        }
        return null;
    }

    private static String validateTemplateConfigSaveReq(WechatSubscribeTemplateConfigSaveReq req) {
        if (req == null) {
            return "请求体不能为空";
        }
        if (StringUtils.isBlank(req.getTemplateKey())) {
            return "templateKey不能为空";
        }
        if (req.getScenicId() == null) {
            return "scenicId不能为空";
        }
        if (StringUtils.isBlank(req.getWechatTemplateId())) {
            return "wechatTemplateId不能为空";
        }
        String enabledErr = validateEnabled(req.getEnabled());
        if (enabledErr != null) {
            return enabledErr;
        }
        if (StringUtils.isBlank(req.getDataTemplateJson())) {
            return "dataTemplateJson不能为空";
        }

        // 仅验证 JSON 结构为对象，避免运行时发送失败
        try {
            JsonNode node = JacksonUtil.getJsonNode(req.getDataTemplateJson());
            if (node == null || !node.isObject()) {
                return "dataTemplateJson必须为JSON对象";
            }
        } catch (Exception e) {
            return "dataTemplateJson不是合法JSON: " + e.getMessage();
        }
        return null;
    }

    private static String validateSceneTemplateSaveReq(WechatSubscribeSceneTemplateSaveReq req) {
        if (req == null) {
            return "请求体不能为空";
        }
        if (StringUtils.isBlank(req.getSceneKey())) {
            return "sceneKey不能为空";
        }
        if (StringUtils.isBlank(req.getTemplateKey())) {
            return "templateKey不能为空";
        }
        if (req.getScenicId() == null) {
            return "scenicId不能为空";
        }
        String enabledErr = validateEnabled(req.getEnabled());
        if (enabledErr != null) {
            return enabledErr;
        }
        return null;
    }

    private static String validateEventTemplateSaveReq(WechatSubscribeEventTemplateSaveReq req) {
        if (req == null) {
            return "请求体不能为空";
        }
        if (StringUtils.isBlank(req.getEventKey())) {
            return "eventKey不能为空";
        }
        if (StringUtils.isBlank(req.getTemplateKey())) {
            return "templateKey不能为空";
        }
        if (req.getScenicId() == null) {
            return "scenicId不能为空";
        }
        String enabledErr = validateEnabled(req.getEnabled());
        if (enabledErr != null) {
            return enabledErr;
        }
        if (req.getSendDelaySeconds() != null && req.getSendDelaySeconds() < 0) {
            return "sendDelaySeconds不能小于0";
        }
        if (req.getDedupSeconds() != null && req.getDedupSeconds() < 0) {
            return "dedupSeconds不能小于0";
        }
        return null;
    }

    /**
     * 清除景区相关的配置缓存
     * 模板配置变更会影响场景和事件的查询结果，需要清除该景区下所有缓存
     *
     * @param scenicId 景区ID
     */
    private void clearConfigCacheByScenic(Long scenicId) {
        if (scenicId == null) {
            return;
        }
        // scenicId=0 表示默认配置，变更时需要清除所有缓存
        if (scenicId == 0L) {
            configService.clearAllConfigsCache();
        } else {
            configService.clearAllConfigsCacheByScenic(scenicId);
        }
    }
}

