package com.ruoyi.bst.driver.service.impl;

import java.time.LocalDateTime;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import com.github.pagehelper.PageHelper;
import com.ruoyi.bst.driver.domain.Driver;
import com.ruoyi.bst.driver.domain.DriverQuery;
import com.ruoyi.bst.driver.domain.DriverVO;
import com.ruoyi.bst.driver.domain.dto.DriverVerifyDTO;
import com.ruoyi.bst.driver.domain.enums.DriverStatus;
import com.ruoyi.bst.driver.mapper.DriverMapper;
import com.ruoyi.bst.driver.service.DriverService;
import com.ruoyi.common.core.domain.vo.UserVO;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.redis.enums.RedisLockKey;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.system.user.domain.enums.UserAuthType;
import com.ruoyi.system.user.service.UserService;
import com.ruoyi.system.user.utils.UserUtil;

/**
 * 驾驶证认证Service业务层处理
 *
 * @author ruoyi
 * @date 2025-06-03
 */
@Service
public class DriverServiceImpl implements DriverService
{
    @Autowired
    private DriverMapper driverMapper;

    @Autowired
    private RedisLock redisLock;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private UserService userService;

    /**
     * 查询驾驶证认证
     *
     * @param id 驾驶证认证主键
     * @return 驾驶证认证
     */
    @Override
    public DriverVO selectDriverById(Long id)
    {
        return driverMapper.selectDriverById(id);
    }

    /**
     * 查询驾驶证认证列表
     *
     * @param driver 驾驶证认证
     * @return 驾驶证认证
     */
    @Override
    public List<DriverVO> selectDriverList(DriverQuery driver)
    {
        return driverMapper.selectDriverList(driver);
    }

    /**
     * 新增驾驶证认证
     *
     * @param driver 驾驶证认证
     * @return 结果
     */
    @Override
    public int insertDriver(Driver driver)
    {
        ServiceUtil.assertion(driver.getUserId() == null, "用户ID不能为空");
        // 加锁
        Long lockKey = driver.getUserId();
        boolean lock = redisLock.lock(RedisLockKey.DRIVER_INSERT, lockKey);
        ServiceUtil.assertion(!lock, "提交过于频繁，请稍后再试");
        try {
            // 查询用户
            UserVO user = userService.selectUserById(driver.getUserId());
            ServiceUtil.assertion(UserUtil.hasAuth(user, UserAuthType.DRIVER.getCode()), "您已通过驾驶证认证，请勿重复提交");

            // 查询上次提交的信息
            DriverVO lastOne = this.selectLastOneByUserId(driver.getUserId());
            ServiceUtil.assertion(lastOne != null && DriverStatus.WAIT_VERIFY.getCode().equals(lastOne.getStatus()), "您已提交过驾驶证认证，请勿重复提交");

            driver.setCreateTime(DateUtils.getNowDate());
            return driverMapper.insertDriver(driver);
        } finally {
            redisLock.unlock(RedisLockKey.DRIVER_INSERT, lockKey);
        }
    }

    /**
     * 修改驾驶证认证
     *
     * @param driver 驾驶证认证
     * @return 结果
     */
    @Override
    public int updateDriver(Driver driver)
    {
        return driverMapper.updateDriver(driver);
    }

    /**
     * 批量删除驾驶证认证
     *
     * @param ids 需要删除的驾驶证认证主键
     * @return 结果
     */
    @Override
    public int deleteDriverByIds(Long[] ids)
    {
        return driverMapper.deleteDriverByIds(ids);
    }

    /**
     * 删除驾驶证认证信息
     *
     * @param id 驾驶证认证主键
     * @return 结果
     */
    @Override
    public int deleteDriverById(Long id)
    {
        return driverMapper.deleteDriverById(id);
    }

    @Override
    public DriverVO selectLastOneByUserId(Long userId) {
        if (userId == null) {
            return null;
        }
        DriverQuery query = new DriverQuery();
        query.setUserId(userId);
        PageHelper.orderBy("create_time desc");
        return this.selectOne(query);
    }

    private DriverVO selectOne(DriverQuery query) {
        PageHelper.startPage(1, 1);
        List<DriverVO> list = this.selectDriverList(query);
        return CollectionUtils.firstElement(list);
    }

    @Override
    public int verify(DriverVerifyDTO dto) {
        DriverVO driver = this.selectDriverById(dto.getId());
        ServiceUtil.assertion(driver == null, "驾驶证认证不存在");
        ServiceUtil.assertion(!DriverStatus.canVerify().contains(driver.getStatus()), "当前驾驶证认证状态不支持审核");

        boolean pass = dto.getPass();
        String driverStatus = pass ? DriverStatus.SUCCESS.getCode() : DriverStatus.FAILED.getCode();

        Integer result = transactionTemplate.execute(status -> {
            Driver data = new Driver();
            data.setStatus(driverStatus);
            data.setVerifyId(dto.getVerifyId());
            data.setVerifyRemark(dto.getRemark());
            data.setVerifyTime(LocalDateTime.now());
            DriverQuery query = new DriverQuery();
            query.setId(dto.getId());
            query.setStatusList(DriverStatus.canVerify());
            int rows = driverMapper.updateByQuery(data, query);
            ServiceUtil.assertion(rows != 1, "当前数据已发生变化，请刷新后重试");

            if (pass) {
                int authType = userService.addAuthType(driver.getUserId(), UserAuthType.DRIVER);
                ServiceUtil.assertion(authType != 1, "为用户添加驾驶证认证失败,id=" + driver.getUserId());
            }

            return rows;
        });

        return result == null ? 0 : result;
    }
}
