package com.njzscloud.dispose.cst.customer.service;

import cn.hutool.core.bean.BeanUtil;
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.dispose.cst.customer.constant.IdentityCategory;
import com.njzscloud.dispose.cst.customer.constant.SettlementWay;
import com.njzscloud.dispose.cst.customer.mapper.CustomerMapper;
import com.njzscloud.dispose.cst.customer.pojo.entity.CustomerEntity;
import com.njzscloud.dispose.cst.customer.pojo.param.AddCustomerParam;
import com.njzscloud.dispose.cst.customer.pojo.param.SearchCustomerParam;
import com.njzscloud.dispose.cst.customer.pojo.result.AddCustomerResult;
import com.njzscloud.dispose.cst.customer.pojo.result.SearchCustomerResult;
import com.njzscloud.dispose.cst.org.pojo.param.AddOrgParam;
import com.njzscloud.dispose.cst.org.service.OrgService;
import com.njzscloud.dispose.sys.auth.pojo.result.IdentityInfo;
import com.njzscloud.dispose.sys.auth.pojo.result.MyResult;
import com.njzscloud.dispose.sys.auth.service.AuthService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 客户信息
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CustomerService extends ServiceImpl<CustomerMapper, CustomerEntity> implements IService<CustomerEntity> {
    private final OrgService orgService;
    private final AuthService authService;

    /**
     * 新增
     */
    @Transactional(rollbackFor = Exception.class)
    public AddCustomerResult add(AddCustomerParam addCustomerParam) {
        Boolean manager = addCustomerParam.getManager();
        Long orgId = null;
        AddOrgParam addOrgParam = addCustomerParam.getAddOrgParam();
        if (manager) {
            Assert.notNull(addOrgParam, () -> Exceptions.exception("组织信息不能为空"));
            orgId = orgService.add(addOrgParam);
        }
        IdentityCategory identityCategory = addCustomerParam.getIdentityCategory();
        boolean exists = this.exists(Wrappers.lambdaQuery(CustomerEntity.class)
            .eq(CustomerEntity::getUserId, addCustomerParam.getUserId())
            .eq(CustomerEntity::getIdentityCategory, identityCategory)
        );
        Assert.isFalse(exists, () -> Exceptions.exception("当前用户已拥有身份：{}", identityCategory.getVal()));

        CustomerEntity entity = BeanUtil
            .copyProperties(addCustomerParam, CustomerEntity.class)
            .setOrgId(orgId);

        if (!manager && addOrgParam != null) {
            orgId = addOrgParam.getOrgId();
            if (orgId != null) {
                orgService.apply(entity.getId(), orgId);
            }
        }

        this.save(entity);
        AddCustomerResult customerResult = new AddCustomerResult();
        customerResult.setCustomerId(entity.getId());
        customerResult.setOrgId(orgId);
        return customerResult;
    }

    /**
     * 修改
     */
    public void modify(CustomerEntity customerEntity) {
        this.updateById(customerEntity);
    }

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

    /**
     * 详情
     */
    public SearchCustomerResult detail(Long id) {
        return baseMapper.detail(id);
    }

    /**
     * 分页查询
     */
    public PageResult<SearchCustomerResult> paging(PageParam pageParam, SearchCustomerParam searchCustomerParam) {
        String keywords = searchCustomerParam.getKeywords();
        SettlementWay settlementWay = searchCustomerParam.getSettlementWay();
        IdentityCategory identityCategory = searchCustomerParam.getIdentityCategory();
        return PageResult.of(baseMapper.paging(pageParam.toPage(), Wrappers.query()
            .eq("a.deleted", 0)
            .and(StrUtil.isNotBlank(keywords), it -> it
                .like("a.customer_name", keywords)
                .or().like("a.phone", keywords)
                .or().like("b.nickname", keywords)
                .or().like("c.username", keywords)
                .or().like("c.wechat_openid", keywords)
                .or().like("d.org_name", keywords)
                .or().like("d.legal_representative", keywords)
            )
            .eq(settlementWay != null, "a.settlement_way", settlementWay)
            .eq(identityCategory != null, "a.identity_category", identityCategory)
        ));
    }

    @Transactional(rollbackFor = Exception.class)
    public MyResult changeIdentity(Long targetCustomerId, MyResult myResult) {
        List<IdentityInfo> identities = myResult.getIdentities();
        Assert.notEmpty(identities, () -> Exceptions.exception("无需切换"));
        Optional<IdentityInfo> identityInfo = identities.stream().filter(it -> Objects.equals(it.getCustomerId(), targetCustomerId)).findFirst();
        Assert.isTrue(identityInfo.isPresent(), () -> Exceptions.exception("目标身份不存在，无法切换"));
        Long currentCustomerId = myResult.getCurrentCustomerId();
        IdentityInfo currentIdentity = myResult.currentIdentity();
        Assert.isTrue(Objects.equals(currentCustomerId, targetCustomerId), () -> Exceptions.exception("已是【{}】身份，无需切换", currentIdentity.getIdentityCategory().getTxt()));
        myResult.setCurrentCustomerId(targetCustomerId);
        SecurityUtil.updateUser(myResult);
        Long userId = myResult.getUserId();
        Integer client = myResult.getClient();
        return (MyResult) authService.my(userId, client);
    }
}
