package com.njzscloud.supervisory.biz.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.common.security.support.UserDetail;
import com.njzscloud.common.security.util.SecurityUtil;
import com.njzscloud.supervisory.biz.constant.AuditStatus;
import com.njzscloud.supervisory.biz.constant.BizObj;
import com.njzscloud.supervisory.biz.mapper.BizDriverMapper;
import com.njzscloud.supervisory.biz.pojo.entity.BizDriverEntity;
import com.njzscloud.supervisory.biz.pojo.param.AddDriverParam;
import com.njzscloud.supervisory.biz.pojo.param.AuditDriverParam;
import com.njzscloud.supervisory.biz.pojo.param.ModifyDriverParam;
import com.njzscloud.supervisory.biz.pojo.result.DriverCantDelResult;
import com.njzscloud.supervisory.biz.pojo.result.SearchCompanyResult;
import com.njzscloud.supervisory.sys.auth.pojo.result.MyResult;
import com.njzscloud.supervisory.sys.user.pojo.param.AddUserAccountParam;
import com.njzscloud.supervisory.sys.user.pojo.param.AddUserParam;
import com.njzscloud.supervisory.sys.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 司机信息
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BizDriverService extends ServiceImpl<BizDriverMapper, BizDriverEntity> {
    private final UserService sysUserService;

    /**
     * 新增
     *
     * @param addDriverParam 数据
     */
    @Transactional(rollbackFor = Exception.class)
    public void add(AddDriverParam addDriverParam) {
        UserDetail userDetail = SecurityUtil.loginUser();
        SearchCompanyResult searchCompanyResult = baseMapper.selectCompanyByUserId(userDetail.getUserId());

        AddUserParam user = addDriverParam.getUser();
        AddUserAccountParam account = user.getAccount();
        user.setPhone(account.getPhone())
                .setBizObj(BizObj.SiJi);
        account.setPhone(null);

        Long driverUserId = sysUserService.add(user);
        BizDriverEntity bizDriverEntity = BeanUtil.copyProperties(addDriverParam, BizDriverEntity.class)
                .setAuditStatus(AuditStatus.DaiShenHe)
                .setUserId(driverUserId)
                .setCompanyId(searchCompanyResult.getId());
        this.save(bizDriverEntity);
    }

    /**
     * 修改
     */
    @Transactional(rollbackFor = Exception.class)
    public void modify(ModifyDriverParam modifyDriverParam) {
        Long id = modifyDriverParam.getId();
        BizDriverEntity oldData = this.getById(id);
        Assert.notNull(oldData, () -> Exceptions.clierr("数据不存在"));
        AuditStatus auditStatus = oldData.getAuditStatus();
        Long driverUserId = oldData.getUserId();

        if (auditStatus == AuditStatus.DaiShenHe || auditStatus == AuditStatus.BoHui) {
            sysUserService.del(Collections.singletonList(driverUserId));
            AddUserParam user = modifyDriverParam.getUser();
            AddUserAccountParam account = user.getAccount();
            user.setPhone(account.getPhone())
                    .setBizObj(BizObj.SiJi);
            account.setPhone(null);

            driverUserId = sysUserService.add(user);
        }

        BizDriverEntity bizDriverEntity = BeanUtil.copyProperties(modifyDriverParam, BizDriverEntity.class)
                .setAuditStatus(auditStatus == AuditStatus.BoHui ? AuditStatus.DaiShenHe : null)
                .setAuditMemo(auditStatus == AuditStatus.BoHui ? "" : null)
                .setUserId(driverUserId);
        this.updateById(bizDriverEntity);
    }

    /**
     * 删除
     *
     * @param ids Ids
     */
    @Transactional(rollbackFor = Exception.class)
    public void del(List<Long> ids) {
        Assert.notEmpty(ids, () -> Exceptions.clierr("未指定要删除的数据"));
        List<BizDriverEntity> bizDriverEntities = this.listByIds(ids);
        Assert.isTrue(bizDriverEntities.size() == ids.size(), () -> Exceptions.clierr("未找到要删除的数据"));
        List<DriverCantDelResult> idList = baseMapper.driverCantDel(Wrappers.query()
                .eq("a.deleted", 0)
                .in("b.id", ids));
        Assert.isTrue(idList.isEmpty(), () -> Exceptions.clierr(MapUtil.builder()
                .put("reason", "存在已关联的订单")
                .put("details", idList)
                .build()));
        List<Long> userIds = bizDriverEntities.stream().map(BizDriverEntity::getUserId).collect(Collectors.toList());
        sysUserService.del(userIds);
        this.removeBatchByIds(ids);
    }

    /**
     * 详情
     *
     * @param id Id
     * @return BizDriverEntity 结果
     */
    public BizDriverEntity detail(Long id) {
        BizDriverEntity entity = this.getById(id);
        if (null != entity && null != entity.getUserId()) {
            SearchCompanyResult result = baseMapper.selectCompanyById(entity.getCompanyId());
            if (null != result) {
                entity.setCompanyName(result.getCompanyName());
            }
        }
        return entity;
    }

    /**
     * 分页查询
     *
     * @param bizDriverEntity 筛选条件
     * @param pageParam       分页参数
     * @return PageResult&lt;BizDriverEntity&gt; 分页结果
     */
    public PageResult<BizDriverEntity> paging(PageParam pageParam, BizDriverEntity bizDriverEntity) {
        String driverName = bizDriverEntity.getDriverName();
        String phone = bizDriverEntity.getPhone();
        AuditStatus auditStatus = bizDriverEntity.getAuditStatus();
        String aStatus = "";
        if (null != auditStatus) {
            aStatus = auditStatus.getVal();
        }
        QueryWrapper<BizDriverEntity> ew = Wrappers.<BizDriverEntity>query()
                .eq("d.deleted", 0)
                .like(StrUtil.isNotBlank(driverName), "d.driver_name", driverName)
                .like(StrUtil.isNotBlank(phone), "d.phone", phone)
                .eq(StrUtil.isNotBlank(aStatus), "d.audit_status", aStatus);

        MyResult userDetail = SecurityUtil.loginUser();
        BizObj parse = userDetail.getBizObj();
        if (parse == BizObj.QiYe
                || parse == BizObj.GeTi
        ) {
            SearchCompanyResult searchCompanyResult = baseMapper.selectCompanyByUserId(userDetail.getUserId());
            ew.eq("d.company_id", searchCompanyResult.getId());
        }
        Page<BizDriverEntity> page = new Page<>(pageParam.getCurrent(), pageParam.getSize());
        return PageResult.of(baseMapper.selectPageWithCompanyName(page, ew));
    }

    public PageResult<BizDriverEntity> dispensabilityList(PageParam pageParam, String keywords) {
        UserDetail userDetail = SecurityUtil.loginUser();
        SearchCompanyResult searchCompanyResult = baseMapper.selectCompanyByUserId(userDetail.getUserId());

        return PageResult.of(this.page(pageParam.toPage(), Wrappers.<BizDriverEntity>lambdaQuery()
                // .eq(BizDriverEntity::getBusy, false)
                .eq(BizDriverEntity::getCompanyId, searchCompanyResult.getId())
                .eq(BizDriverEntity::getAuditStatus, AuditStatus.TongGuo)
                .and(StrUtil.isNotBlank(keywords), it ->
                        it.like(BizDriverEntity::getDriverName, keywords)
                                .or().like(BizDriverEntity::getPhone, keywords))
        ));
    }

    /**
     * 审核司机
     *
     * @param auditDriverParam 审核参数
     */
    @Transactional(rollbackFor = Exception.class)
    public void audit(AuditDriverParam auditDriverParam) {
        Assert.isTrue(auditDriverParam.getAuditStatus() == AuditStatus.TongGuo ||
                auditDriverParam.getAuditStatus() == AuditStatus.BoHui, "错误的审核状态");

        BizDriverEntity oldData = getById(auditDriverParam.getId());
        if (oldData == null) {
            throw Exceptions.exception("未找到要审核的司机信息");
        }

        if (oldData.getAuditStatus() != AuditStatus.DaiShenHe) {
            throw Exceptions.exception("当前状态不能审核");
        }

        boolean updated = update(Wrappers.<BizDriverEntity>lambdaUpdate()
                .set(BizDriverEntity::getAuditStatus, auditDriverParam.getAuditStatus())
                .set(BizDriverEntity::getAuditMemo, auditDriverParam.getAuditMemo())
                .eq(BizDriverEntity::getId, auditDriverParam.getId())
                .eq(BizDriverEntity::getAuditStatus, AuditStatus.DaiShenHe));

        if (!updated) {
            throw Exceptions.exception("数据状态已改变，无法审核");
        }
    }

    public void cancel(Long id) {
        BizDriverEntity oldData = getById(id);
        if (oldData == null) {
            throw Exceptions.exception("未找到要撤销的数据");
        }
        update(Wrappers.<BizDriverEntity>lambdaUpdate()
                .set(BizDriverEntity::getAuditStatus, AuditStatus.YiCheXiao)
                .eq(BizDriverEntity::getId, id)
        );
    }

    public void changeCompany(Long id, Long companyId) {
        this.updateById(new BizDriverEntity()
                .setId(id)
                .setCompanyId(companyId)
        );
    }
}
