package com.cclotus.register.service

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.cclotus.register.domain.WXUser
import com.cclotus.register.mapper.WXUserMapper
import com.cclotus.register.vo.WXUserInfoDetail
import com.github.pagehelper.PageInfo
import com.ruoyi.common.constant.HttpStatus
import com.ruoyi.common.core.page.TableDataInfo
import com.ruoyi.common.exception.ServiceException
import com.ruoyi.common.reqParam.PageParam
import com.ruoyi.common.utils.PageUtils
import org.springframework.beans.BeanUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

/**
 * 微信用户服务
 */
@Service
class WXUserService : ServiceImpl<WXUserMapper, WXUser>() {

    @Autowired
    lateinit var wxUserMapper: WXUserMapper

    /**
     * 分页查询用户列表
     * @param user 用户过滤条件
     * @param pageParam 分页参数
     * @return 分页列表
     */
    @JvmOverloads
    fun selectWXUserDetailList(user: WXUser, pageParam: PageParam? = null): TableDataInfo {
        val users = selectWXUserList(user, pageParam)
        val details = users.map {
            WXUserInfoDetail().apply {
                BeanUtils.copyProperties(it, this)
            }
        }
        return TableDataInfo().apply {
            this.code = HttpStatus.SUCCESS
            this.msg = "查询成功"
            this.rows = details
            this.total = PageInfo<Any?>(users).total
        }
    }

    /**
     * 分页查询用户列表
     * @param user 用户过滤条件
     * @param pageParam 分页参数
     * @return 分页列表
     */
    @JvmOverloads
    fun selectWXUserList(user: WXUser, pageParam: PageParam? = null): List<WXUser> {
        pageParam?.let {
            PageUtils.startPage(it)
        }
        return wxUserMapper.selectWXUserList(user)
    }

    /**
     * 查询指定用户ID的用户信息
     * @param userId 用户ID
     * @return 用户信息
     */
    fun selectWXUserByUserId(userId: String): WXUserInfoDetail {
        val user = wxUserMapper.selectWXUserByUserId(userId) ?: throw ServiceException("指定用户信息不存在")
        val wxUserInfoDetail = WXUserInfoDetail().apply {
            BeanUtils.copyProperties(user, this)
        }
        return wxUserInfoDetail
    }

    /**
     * 修改用户信息
     * @param userId 用户ID
     * @return 修改结果
     */
    fun updateUser(userId: String, wxUser: WXUser): WXUser {
        val user = wxUserMapper.selectById(userId) ?: throw ServiceException("指定用户ID的用户数据不存在")
        BeanUtils.copyProperties(wxUser, user, "userId", "name", "phone", "openid", "deleted", "referrer")
        wxUserMapper.updateById(user)
        return user
    }

    /**
     * 根据openID查找用户信息
     * @param openId 微信openID
     * @param deleted 是否只查询未注销用户 0是 null否
     * @return 用户信息，未找到返回null
     */
    @JvmOverloads
    fun findUserByOpenID(openId: String, deleted: Int? = 0): WXUser? {
        return QueryWrapper<WXUser>()
            .eq("openid", openId)
            .eq(deleted != null, "deleted", deleted)
            ?.let {
                wxUserMapper.selectList(it).getOrNull(0)
            }
    }

    /**
     * 检查手机号在所有未注销用户中是否存在
     *
     * @param phone 待检查的手机号码
     * @return 手机号是否存在
     */
    fun checkPhoneExistence(phone: String): Boolean {
        val user = QueryWrapper<WXUser>()
            .eq("phone", phone)
            .eq("deleted", 0)
            .let {
                wxUserMapper.selectOne(it)
            }
        return user != null
    }

    /**
     * 软删除用户信息
     *
     * @param userId 待删除的用户ID
     */
    fun deleteUserById(userId: String): Int {
        val user = wxUserMapper.selectById(userId) ?: throw ServiceException("指定用户ID的用户数据不存在")
        user.deleted = 1
        return wxUserMapper.updateById(user)
    }

    /**
     * 根据用户ID列表批量软删除用户信息
     * @param userIds 待删除的用户ID列表
     */
    fun deleteWXUserByUserIds(userIds: Array<String>) {
        UpdateWrapper<WXUser>()
            .`in`("user_id", *userIds)
            .set("deleted", 1)
            .let {
                update(it)
            }
    }
}
