package com.liquidnet.service.sweet.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.sweet.entity.SweetLostFoundAdmin;
import com.liquidnet.service.sweet.mapper.SweetLostFoundAdminMapper;
import com.liquidnet.service.sweet.param.SweetLostFoundAdminParam;
import com.liquidnet.service.sweet.service.ISweetLostFoundAdminService;
import com.liquidnet.service.sweet.utils.LostFoundRedisUtils;
import com.liquidnet.service.sweet.vo.SweetLostFoundAdminVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 失物招领管理员服务实现类
 *
 * @author liquidnet
 * @since 2025-01-18
 */
@Service
public class SweetLostFoundAdminServiceImpl extends ServiceImpl<SweetLostFoundAdminMapper, SweetLostFoundAdmin> implements ISweetLostFoundAdminService {

    @Autowired
    private LostFoundRedisUtils lostFoundRedisUtils;

    @Override
    public ResponseDto<Boolean> addAdmin(SweetLostFoundAdminParam admin) {
        String phone = admin.getPhone().trim();
        String performanceId = admin.getPerformanceId().trim();
        Integer authScope = admin.getAuthScope();

        // 统一查询：检查当前手机号在所有相关场景下的冲突
        QueryWrapper<SweetLostFoundAdmin> conflictWrapper = new QueryWrapper<>();
        conflictWrapper.eq("phone", phone)
                .eq("is_deleted", 0);

        // 规则1：如果创建的是全站管理员，检查是否已存在全站管理员
        if (authScope != null && authScope == 2) {
            conflictWrapper.eq("auth_scope", 2);
        }
        // 规则2：如果创建的是特定演出管理员，检查是否已存在该演出记录或全站管理员
        else {
            conflictWrapper.and(wrapper ->
                    wrapper.eq("performance_id", performanceId)
                            .or()
                            .eq("auth_scope", 2)
            );
        }

        if (baseMapper.selectCount(conflictWrapper) > 0) {
            return ResponseDto.failure("该手机号已存在");
        }

        SweetLostFoundAdmin foundAdmin = SweetLostFoundAdmin.getNew();
        foundAdmin.setAdminId(IDGenerator.nextSnowId());
        foundAdmin.setPhone(phone);
        foundAdmin.setName(admin.getName());
        foundAdmin.setPermissionType(admin.getPermissionType());
        foundAdmin.setAuthScope(admin.getAuthScope());
        foundAdmin.setPerformanceId(performanceId);
        boolean result = baseMapper.insert(foundAdmin) > 0;

        SweetLostFoundAdminVo vo = new SweetLostFoundAdminVo();
        BeanUtils.copyProperties(foundAdmin, vo);
        lostFoundRedisUtils.setAdminCache(phone, performanceId, vo);

        return ResponseDto.success(result);
    }

    //    假设：
    //            - 已存在记录：phone=13800138000, performanceId="A", authScope=1
    //            - 现在创建：phone=13800138000, performanceId="B", authScope=2
    //
    //    当前写法：允许创建（因为只在全站管理员场景检查）
    //    建议写法：会报错（因为会查到performanceId="A"的记录）
    //    假设：
    //            - 已存在记录：phone=13800138000, performanceId="A", authScope=2
    //            - 现在创建：phone=13800138000, performanceId="B", authScope=1
    //
    //    当前行为：会允许创建，但这可能不符合业务需求
    @Override
    public ResponseDto<Boolean> editAdmin(SweetLostFoundAdminParam admin) {
        Long id = admin.getId();
        String phone = admin.getPhone().trim();
        String performanceId = admin.getPerformanceId().trim();
        Integer authScope = admin.getAuthScope();

        // 检查要修改的管理员是否存在
        SweetLostFoundAdmin existingAdmin = baseMapper.selectById(id);
        if (existingAdmin == null || existingAdmin.getIsDeleted() == 1) {
            return ResponseDto.failure("管理员记录不存在或已删除");
        }

        // 统一查询：检查修改后手机号在所有相关场景下的冲突（排除自身）
        QueryWrapper<SweetLostFoundAdmin> conflictWrapper = new QueryWrapper<>();
        conflictWrapper.eq("phone", phone)
                .ne("id", id)
                .eq("is_deleted", 0);

        // 规则1：如果修改为全站管理员，检查是否已存在全站管理员
        if (authScope != null && authScope == 2) {
            conflictWrapper.eq("auth_scope", 2);
        }
        // 规则2：如果修改为特定演出管理员，检查是否已存在该演出记录或全站管理员
        else {
            conflictWrapper.and(wrapper ->
                    wrapper.eq("performance_id", performanceId)
                            .or()
                            .eq("auth_scope", 2)
            );
        }

        if (baseMapper.selectCount(conflictWrapper) > 0) {
            return ResponseDto.failure("该手机号已存在");
        }

        SweetLostFoundAdmin foundAdmin = SweetLostFoundAdmin.getNew();
        foundAdmin.setId(id);
        foundAdmin.setPhone(phone);
        foundAdmin.setName(admin.getName());
        foundAdmin.setPermissionType(admin.getPermissionType());
        foundAdmin.setAuthScope(admin.getAuthScope());
        foundAdmin.setPerformanceId(performanceId);

        // 缓存
        SweetLostFoundAdminVo vo = new SweetLostFoundAdminVo();
        BeanUtils.copyProperties(foundAdmin, vo);
        lostFoundRedisUtils.setAdminCache(phone, performanceId, vo);
        // 因为可能会更改权限范围 写入有范围的判断 所以直接删除老的
        lostFoundRedisUtils.deleteAdminCache(existingAdmin.getPhone(), existingAdmin.getPerformanceId(), existingAdmin.getAuthScope());

        return ResponseDto.success(baseMapper.updateById(foundAdmin) > 0);
    }

    @Override
    public boolean deleteAdmin(Long id) {
        // 检查管理员是否存在
        SweetLostFoundAdmin admin = baseMapper.selectById(id);
        if (admin == null) {
            return false;
        }

        // 逻辑删除：更新is_deleted字段为1
        admin.setIsDeleted(1);

        lostFoundRedisUtils.deleteAdminCache(admin.getPhone(), admin.getPerformanceId(), admin.getAuthScope());

        return baseMapper.updateById(admin) > 0;
    }

    @Override
    public SweetLostFoundAdminVo getAdminDetail(Long id) {
        SweetLostFoundAdmin admin = baseMapper.selectById(id);
        if (admin == null || admin.getIsDeleted() == 1) {
            return null;
        }

        SweetLostFoundAdminVo vo = new SweetLostFoundAdminVo();
        BeanUtils.copyProperties(admin, vo);
        return vo;
    }

    @Override
    public List<SweetLostFoundAdminVo> getAdminList(String performanceId) {
        // 构建查询条件
        QueryWrapper<SweetLostFoundAdmin> queryWrapper = new QueryWrapper<>();

        // 过滤逻辑删除的记录
        queryWrapper.eq("is_deleted", 0);

        // 查询条件：performanceId = 指定演出ID OR authScope = 2(全站)
        queryWrapper.and(wrapper ->
                wrapper.eq("performance_id", performanceId.trim())
                        .or()
                        .eq("auth_scope", 2)
        );

        // 默认按创建时间降序
        queryWrapper.orderByDesc("create_time");

        // 执行查询
        List<SweetLostFoundAdmin> adminList = baseMapper.selectList(queryWrapper);

        // 转换为VO对象
        List<SweetLostFoundAdminVo> voList = adminList.stream()
                .map(admin -> {
                    SweetLostFoundAdminVo vo = new SweetLostFoundAdminVo();
                    BeanUtils.copyProperties(admin, vo);
                    return vo;
                })
                .collect(Collectors.toList());

        return voList;
    }

    @Override
    public SweetLostFoundAdminVo hasPermission(String phone, String performanceId) {
        SweetLostFoundAdminVo adminCache = lostFoundRedisUtils.getAdminCache(phone, performanceId);
//        if (adminCache == null) {
//            QueryWrapper<SweetLostFoundAdmin> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("phone", phone.trim())
//                    .eq("is_deleted", 0);
//            queryWrapper.and(wrapper ->
//                    wrapper.eq("performance_id", performanceId.trim())
//                            .or()
//                            .eq("auth_scope", 2)
//            );
//            SweetLostFoundAdmin admin = baseMapper.selectOne(queryWrapper);
//            if (admin == null) {
//                return null;
//            }
//            SweetLostFoundAdminVo vo = new SweetLostFoundAdminVo();
//            BeanUtils.copyProperties(admin, vo);
//            lostFoundRedisUtils.setAdminCache(phone, performanceId, vo);
//            return vo;
//        }
        return adminCache;
    }
}