package com.njzscloud.supervisory.order.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
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.util.SecurityUtil;
import com.njzscloud.supervisory.biz.contant.AuditStatus;
import com.njzscloud.supervisory.biz.pojo.entity.BizAuditConfigEntity;
import com.njzscloud.supervisory.biz.service.BizAuditConfigService;
import com.njzscloud.supervisory.order.mapper.OrderInfoMapper;
import com.njzscloud.supervisory.order.pojo.entity.OrderInfoEntity;
import com.njzscloud.supervisory.order.pojo.param.AuditOrderParam;
import com.njzscloud.supervisory.order.pojo.param.OrderPagingSearchParam;
import com.njzscloud.supervisory.order.pojo.result.OrderPagingResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 订单信息
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEntity> implements IService<OrderInfoEntity> {

    private final BizAuditConfigService bizAuditConfigService;

    /**
     * 新增
     */
    public void add(OrderInfoEntity orderInfoEntity) {
        this.save(orderInfoEntity);
    }

    /**
     * 修改
     */
    public void modify(OrderInfoEntity orderInfoEntity) {
        this.updateById(orderInfoEntity);
    }

    /**
     * 删除
     */
    @Transactional(rollbackFor = Exception.class)
    public void del(List<Long> ids) {
        this.removeBatchByIds(ids);
    }

    /**
     * 详情
     */
    public OrderPagingResult detail(Long id) {
        return baseMapper.detail(Wrappers.<OrderPagingResult>query()
                .in("a.id", id));
    }

    /**
     * 分页查询
     */
    public PageResult<OrderPagingResult> paging(PageParam pageParam, OrderPagingSearchParam orderPagingSearchParam) {
        AuditStatus auditStatus = orderPagingSearchParam.getAuditStatus();
        String orderStatus = orderPagingSearchParam.getOrderStatus();
        String sn = orderPagingSearchParam.getSn();
        String licensePlate = orderPagingSearchParam.getLicensePlate();
        String nickname = orderPagingSearchParam.getNickname();
        String phone = orderPagingSearchParam.getPhone();
        LocalDateTime startTime = orderPagingSearchParam.getStartTime();
        LocalDateTime endTime = orderPagingSearchParam.getEndTime();
        return PageResult.of(baseMapper.paging(pageParam.toPage(), Wrappers.<OrderPagingResult>query()
                .like(StrUtil.isNotBlank(sn), "a.sn", sn)
                .like(StrUtil.isNotBlank(licensePlate), "a.license_plate", licensePlate)
                .like(StrUtil.isNotBlank(nickname), "h.nickname", nickname)
                .like(StrUtil.isNotBlank(phone), "h.phone", phone)
                .eq(auditStatus != null, "a.audit_status", auditStatus)
                .eq(orderStatus != null, "a.order_status", orderStatus)
                .between(startTime != null && endTime != null, "a.create_time", startTime, endTime)
        ));
    }

    public PageResult<OrderPagingResult> auditPaging(PageParam pageParam, OrderPagingSearchParam orderPagingSearchParam) {
        Set<String> roles = orderPagingSearchParam.getRoles();
        List<String> areas = bizAuditConfigService.list(Wrappers.<BizAuditConfigEntity>query()
                .select("DISTINCT area")
                .in("area_role", roles)
                .or().in("city_role", roles)
        ).stream().map(BizAuditConfigEntity::getArea).collect(Collectors.toList());
        if (CollUtil.isEmpty(areas)) {
            return PageResult.of(pageParam.toPage());
        }

        return PageResult.of(baseMapper.paging(pageParam.toPage(), Wrappers.<OrderPagingResult>query()
                .in("b.area", areas)));
    }

    public void audit(AuditOrderParam auditOrderParam) {
        OrderPagingResult detail = detail(auditOrderParam.getId());
        Assert.notNull(detail, () -> Exceptions.clierr("订单不存在"));
        AuditStatus auditStatus = detail.getAuditStatus();
        Assert.isTrue(auditStatus == AuditStatus.QuDaiShenHe
                        || auditStatus == AuditStatus.ShiDaiShenHe,
                () -> Exceptions.clierr("订单已审核"));

        Assert.isTrue(auditStatus == AuditStatus.TongGuo || auditStatus == AuditStatus.BoHui);

        Set<String> roles = SecurityUtil.loginUser().getRoles();
        String area = detail.getArea();
        BizAuditConfigEntity config = bizAuditConfigService.getOne(Wrappers.<BizAuditConfigEntity>query()
                .eq("area", detail.getArea()));
        String areaRole = config.getAreaRole();
        String cityRole = config.getCityRole();
        if (!roles.contains(areaRole) && !roles.contains(cityRole)) {
            throw Exceptions.clierr("您没有权限审核该订单");
        }

        AuditStatus newAuditStatus = auditOrderParam.getAuditStatus();
        if (auditStatus == AuditStatus.QuDaiShenHe) {
            if (StrUtil.isBlank(areaRole) && roles.contains(areaRole)) {
                auditStatus = newAuditStatus == AuditStatus.TongGuo ? AuditStatus.ShiDaiShenHe : newAuditStatus;
            } else {
                throw Exceptions.clierr("您没有权限审核该订单");
            }
        } else {
            if (StrUtil.isBlank(cityRole) && roles.contains(cityRole)) {
                auditStatus = newAuditStatus;
            } else {
                throw Exceptions.clierr("您没有权限审核该订单");
            }
        }

        detail.setAuditStatus(newAuditStatus);
        detail.setAuditMemo(auditOrderParam.getAuditMemo());
        this.updateById(new OrderInfoEntity()
                .setAuditStatus(auditStatus)
                .setAuditMemo(auditOrderParam.getAuditMemo())
        );
    }
}
