package com.njzscloud.supervisory.customer.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.core.utils.GroupUtil;
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.pojo.entity.BizAuditConfigEntity;
import com.njzscloud.supervisory.biz.service.BizAuditConfigService;
import com.njzscloud.supervisory.customer.mapper.CustomerMapper;
import com.njzscloud.supervisory.customer.pojo.param.SearchCustomerParam;
import com.njzscloud.supervisory.customer.pojo.result.SearchCustomerResult;
import com.njzscloud.supervisory.customer.pojo.result.ShortBargeInfoResult;
import com.njzscloud.supervisory.sys.user.service.UserRoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

import static com.njzscloud.supervisory.constant.Constant.ROLE_JG;

@Slf4j
@Service
@RequiredArgsConstructor
public class CustomerService {
    private final CustomerMapper customerMapper;
    private final UserRoleService userRoleService;
    private final BizAuditConfigService bizAuditConfigService;

    public static List<String> mergeLists(List<String> list1, List<String> list2) {
        Set<String> set = new HashSet<>(list1);
        set.addAll(list2);
        return new ArrayList<>(set);
    }

    public PageResult<SearchCustomerResult> paging(PageParam pageParam, SearchCustomerParam searchCustomerParam) {
        Page<SearchCustomerResult> page = pageParam.toPage();
        page.addOrder(OrderItem.desc("b.regdate"), OrderItem.desc("a.id"));
        String customerName = searchCustomerParam.getCustomerName();

        QueryWrapper<Object> ew = Wrappers.query()
                .and(StrUtil.isNotBlank(customerName), it ->
                        it.like("a.nickname", customerName)
                                .or().like("c.contacts", customerName)
                                .or().like("d.driver_name", customerName)
                                .or().like("c.company_name", customerName)
                );
        BizObj bizObj = searchCustomerParam.getBizObj();
        if (bizObj != null) {
            Assert.isTrue(bizObj == BizObj.GeRen
                            || bizObj == BizObj.ChanFeiDanWei
                            || bizObj == BizObj.QingYunGongSi
                    , () -> Exceptions.clierr("客户类型错误"));
            if (bizObj == BizObj.GeRen) {
                ew.eq("a.biz_obj", bizObj);
            } else if (bizObj == BizObj.ChanFeiDanWei) {
                ew.in("a.biz_obj", Stream.of(
                                BizObj.WuYe,
                                BizObj.ShiGongDanWei,
                                BizObj.ChaiQian,
                                BizObj.SheQu,
                                BizObj.QiTa).map(BizObj::getVal).collect(Collectors.toList()))
                        .eq("c.audit_status", AuditStatus.TongGuo);
                ;
            } else if (bizObj == BizObj.QingYunGongSi) {
                ew.in("a.biz_obj", Stream.of(
                                BizObj.QiYe,
                                BizObj.GeTi).map(BizObj::getVal).collect(Collectors.toList()))
                        .eq("c.audit_status", AuditStatus.TongGuo);
            }
        } else {
            ew.in("a.biz_obj", Stream.of(
                            BizObj.GeRen,
                            BizObj.WuYe,
                            BizObj.ShiGongDanWei,
                            BizObj.ChaiQian,
                            BizObj.SheQu,
                            BizObj.QiTa,
                            BizObj.QiYe,
                            BizObj.GeTi).map(BizObj::getVal).collect(Collectors.toList()))
                    .and(it -> it.eq("c.audit_status", AuditStatus.TongGuo).or().isNull("c.audit_status"));
        }

        UserDetail userDetail = SecurityUtil.loginUser();
        Set<String> roles = userDetail.getRoles();
        if (CollUtil.isNotEmpty(roles) && !SecurityUtil.isAdmin() && roles.contains(ROLE_JG)) {
            List<String> areaList = bizAuditConfigService.list(Wrappers.<BizAuditConfigEntity>lambdaQuery().in(BizAuditConfigEntity::getAreaRole, roles))
                    .stream().map(BizAuditConfigEntity::getArea).distinct().collect(Collectors.toList());
            List<String> cityList = bizAuditConfigService.list(Wrappers.<BizAuditConfigEntity>lambdaQuery().in(BizAuditConfigEntity::getCityRole, roles))
                    .stream().map(BizAuditConfigEntity::getArea).distinct().collect(Collectors.toList());
            List<String> list = mergeLists(areaList, cityList);
            ew.in(CollUtil.isNotEmpty(list), "c.area", list);
        }
        IPage<SearchCustomerResult> paging = customerMapper.paging(page, ew);
        List<SearchCustomerResult> records = paging.getRecords();
        if (CollUtil.isEmpty(records)) return PageResult.of(paging);
        List<Long> collect = records.stream().map(SearchCustomerResult::getId).collect(Collectors.toList());
        List<ShortBargeInfoResult> shortBargeInfoResults = customerMapper.shortBargeInfo(Wrappers.query()
                .in("a.user_id", collect).groupBy("a.user_id"));

        Map<Long, Boolean> map = GroupUtil.k_o(shortBargeInfoResults, ShortBargeInfoResult::getUserId, ShortBargeInfoResult::getShortBarge);
        for (SearchCustomerResult record : records) {
            record.setShortBarge(map.getOrDefault(record.getId(), false));
        }
        return PageResult.of(paging);
    }

    public void shortBarge(Boolean enable, Long customerId) {
        userRoleService.shortBarge(enable, customerId);
    }
}
