package com.agri.system.service.impl;

import com.agri.common.enums.AgriEnum;
import com.agri.common.utils.DateUtils;
import com.agri.common.utils.SecurityUtils;
import com.agri.common.utils.wechat.WxUtil;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.SysUserAgri;
import com.agri.system.domain.vo.AgriAutoInfoVo;
import com.agri.system.domain.vo.AgriInfoView;
import com.agri.system.mapper.SysAgriInfoMapper;
import com.agri.system.service.ISysAgriInfoService;
import com.agri.system.service.ISysUserAgriService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 大棚管理Service业务层处理
 *
 * @author agri
 * @date 2026-01-08
 */
@Service
public class SysAgriInfoServiceImpl extends ServiceImpl<SysAgriInfoMapper, SysAgriInfo> implements ISysAgriInfoService
{

    @Value("${agri.manager.num}")
    private Integer agriManagerNum;

    @Autowired
    private ISysUserAgriService userAgriService;

    /**
     * 查询大棚管理
     *
     * @param id 大棚管理主键
     * @return 大棚管理
     */
    @Override
    public SysAgriInfo selectSysAgriInfoById(Long id)
    {
        return baseMapper.selectSysAgriInfoById(id);
    }

    /**
     * 查询大棚管理列表
     *
     * @param sysAgriInfo 大棚管理
     * @return 大棚管理
     */
    @Override
    public List<SysAgriInfo> selectSysAgriInfoList(SysAgriInfo sysAgriInfo)
    {
        return baseMapper.selectSysAgriInfoList(sysAgriInfo);
    }

    /**
     * 新增大棚管理
     *
     * @param sysAgriInfo 大棚管理
     * @return 结果
     */
    @Override
    public int insertSysAgriInfo(SysAgriInfo sysAgriInfo)
    {
        return baseMapper.insertSysAgriInfo(sysAgriInfo);
    }

    /**
     * 修改大棚管理
     *
     * @param sysAgriInfo 大棚管理
     * @return 结果
     */
    @Override
    public int updateSysAgriInfo(SysAgriInfo sysAgriInfo)
    {
        sysAgriInfo.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateSysAgriInfo(sysAgriInfo);
    }

    /**
     * 批量删除大棚管理
     *
     * @param ids 需要删除的大棚管理主键
     * @return 结果
     */
    @Override
    public int deleteSysAgriInfoByIds(Long[] ids)
    {
        return baseMapper.deleteSysAgriInfoByIds(ids);
    }

    /**
     * 删除大棚管理信息
     *
     * @param id 大棚管理主键
     * @return 结果
     */
    @Override
    public int deleteSysAgriInfoById(Long id)
    {
        return baseMapper.deleteSysAgriInfoById(id);
    }


    @Override
    public List<SysAgriInfo> findAgriByUser(SysAgriInfo sysAgriInfo) {
        if (!SecurityUtils.isAdmin()) {
            sysAgriInfo.setUserId(SecurityUtils.getUserId());
        }
        return baseMapper.findAgriByUser(sysAgriInfo);
    }

    @Override
    public List<AgriInfoView> findAgriInfoByUser(SysAgriInfo sysAgriInfo) {
        if (!SecurityUtils.isAdmin()) {
            sysAgriInfo.setUserId(SecurityUtils.getUserId());
        }
        return baseMapper.findAgriInfoByUser(sysAgriInfo);
    }

    /**
     * 来源：扫码0 、 邀请1  邀请userId有问题
     * @param sysAgriInfo
     * @return
     */
    @Override
    public Map<String,Object> addAgriFromMobile(SysAgriInfo sysAgriInfo) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("code", AgriEnum.SUCCESS.getCode());
        resultMap.put("msg", "添加大棚成功");
        Integer sourceCode = sysAgriInfo.getSourceCode();
        // 1. 区分扫码/邀请的userId来源
        Long userId;
        if (sourceCode.equals(AgriEnum.WARN.getCode())) {
            // 扫码：userId取当前登录用户
            userId = SecurityUtils.getUserId();
        } else {
            // 邀请：userId取前端传入的值
            userId = sysAgriInfo.getUserId();
        }
        sysAgriInfo.setUserId(userId);
        try {

            // 2. 查询大棚是否已存在
            SysAgriInfo agriInfo = super.lambdaQuery()
                    .eq(SysAgriInfo::getImei, sysAgriInfo.getImei())
                    .one();

            // 3. 大棚默认参数设置
            sysAgriInfo.setWorkMode(AgriEnum.MANUAL.getCode());// 默认手动模式
            sysAgriInfo.setAlarmStatus(AgriEnum.ALARM_CLOSE.getCode());// 默认关闭告警开关
            sysAgriInfo.setIsDeleted(AgriEnum.NO_DELETE.getCode());

            // 4. 构建用户-大棚绑定基础对象
            SysUserAgri sysUserAgri = new SysUserAgri();
            sysUserAgri.setAgriId(sysAgriInfo.getImei());
            sysUserAgri.setUserId(userId);
            sysUserAgri.setInviteBy(SecurityUtils.getUserId());
            sysUserAgri.setInviteTime(new Date());
            sysUserAgri.setRemark("用户所有者绑定");

            // 方法开头先判断管理员（如需放行新增操作，可在新增逻辑内处理）
            if (SecurityUtils.isAdmin()) {
                // 管理员仅执行大棚新增，不绑定用户
                if (ObjectUtils.isEmpty(agriInfo)) {
                    baseMapper.insert(sysAgriInfo);
                }
                return resultMap;
            }

            // 5. 大棚未添加：新增大棚 + 绑定用户（仅非管理员）
            if (ObjectUtils.isEmpty(agriInfo)) {
                int insert = baseMapper.insert(sysAgriInfo);
                if (insert > 0) {
                    // 扫码/首次绑定场景：后端设置固定值（非邀请场景）
                    sysUserAgri.setRole(AgriEnum.OWNER.getCode());
                    sysUserAgri.setStatus(AgriEnum.ENABLED.getCode());
                    sysUserAgri.setAcceptTime(new Date());
                    userAgriService.save(sysUserAgri);
                    return resultMap;
                }
            }
            // 6. 管理员逻辑：仅新增大棚，不绑定用户 ----->前移


            // 新增逻辑  如果没有绑定卷被卷膜数量，报错
            Integer blindNum = agriInfo.getBlindNum();
            Integer filmNum = agriInfo.getFilmNum();
            Integer quiltNum = agriInfo.getQuiltNum();
            if (blindNum==null || filmNum == null || quiltNum == null) {
                resultMap.put("code", AgriEnum.WARN.getCode());
                resultMap.put("msg","当前大棚尚未完成配置，请联系管理员配置后重新尝试！");
                return resultMap;
            }

            // 7. 大棚已存在：处理绑定逻辑
            List<SysUserAgri> userAgriList = userAgriService.lambdaQuery()
                    .eq(SysUserAgri::getAgriId, sysAgriInfo.getImei())
                    .list();

            // 7.1 大棚已存在但未绑定任何用户：扫码绑定（后端设固定值）
            if (CollectionUtils.isEmpty(userAgriList)) {
                sysUserAgri.setRole(AgriEnum.OWNER.getCode());
                sysUserAgri.setStatus(AgriEnum.ENABLED.getCode());
                sysUserAgri.setAcceptTime(new Date());
                userAgriService.save(sysUserAgri);
                resultMap.put("msg", "关联用户成功！");
                return resultMap;
            }

            // 7.2 校验当前用户是否已绑定该大棚
            Optional<SysUserAgri> optional = userAgriList.stream()
                    .filter(userAgri -> userAgri.getUserId().equals(userId)).findFirst();

            // 7.3 扫码场景：大棚已绑定其他用户 → 直接提示返回
            if (AgriEnum.SCAN.getCode().equals(sourceCode)
                    && (!optional.isPresent() || !optional.get().getRole().equals(3))) {
                resultMap.put("code", AgriEnum.WARN.getCode());
                resultMap.put("msg","当前大棚已被关联，请联系大棚所有者！");
                return resultMap;
            }

            // 7.4 重复绑定/重复邀请 → 提示返回
            if (optional.isPresent()) {
                resultMap.put("code", AgriEnum.WARN.getCode());
                resultMap.put("msg","已关联当前大棚，请勿重复绑定！");
                if (sourceCode.equals(AgriEnum.INVITE.getCode())) {
                    resultMap.put("msg","该用户已被邀请，请勿重复关联！");
                }
                return resultMap;
            }
            // ---------扫码场景到此为止，强制返回，避免进入邀请逻辑--------
            if (AgriEnum.INVITE.getCode().equals(sourceCode)) {
                return resultMap;
            }
            // 8. 邀请场景（仅sourceCode=1能走到这里）
            // 8.1 校验绑定数量上限
            if (userAgriList.size()>=agriManagerNum) {
                resultMap.put("code", AgriEnum.WARN.getCode());
                resultMap.put("msg","当前大棚关联超过限制，请联系大棚所有者！");
                return resultMap;
            }

            // 8.2 邀请场景：从前端入参获取role、status、acceptTime（核心规则）
            sysUserAgri.setStatus(AgriEnum.PENDING_ACCEPTANCE.getCode());
            sysUserAgri.setRemark("用户邀请");
            userAgriService.save(sysUserAgri);
            // todo 向对应人发送通知
            if (AgriEnum.WARN.getCode().equals(sourceCode)) {
                resultMap.put("msg", "邀请已发送，请等待确认");
            }
            return resultMap;
        } catch (Exception e) {
            log.error("绑定大棚用户失败，agriId={}, msg={}", e);
            resultMap.put("code", AgriEnum.ERROR.getCode());
            resultMap.put("msg", "系统异常，绑定失败");
            WxUtil.pushText("【移动端添加大棚失败】来源："+(sourceCode==0?"扫码":"邀请")+"\nuserId: 【"+userId+"】\ncause: "+e);
            return resultMap;
        }
    }


    @Override
    public List<AgriAutoInfoVo> findAgriOfAutoInfo() {

        return baseMapper.findAgriOfAutoInfo();
    }


    /**
     * 实际业务中：查询指定用户名下的所有设备ID（需替换为你的DAO/Service逻辑）
     * @return 设备ID列表
     */
    @Override
    public List<String> queryImeiByUserId(Long userId) {

        SysAgriInfo sysAgriInfo = new SysAgriInfo();
        if (!SecurityUtils.isAdmin()) {
            sysAgriInfo.setUserId(userId);
        }
        List<SysAgriInfo> agriInfos = baseMapper.findAgriByUser(sysAgriInfo);
        if (CollectionUtils.isEmpty(agriInfos)) {
            return Collections.emptyList();
        }
        return agriInfos.stream().map(SysAgriInfo::getImei).collect(Collectors.toList());
    }
}
