package com.kiisoo.ic.customer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.kiisoo.ic.common.utils.httpClientUtil.HttpClientUtil;
import com.kiisoo.ic.constants.Constants;
import com.kiisoo.ic.customer.bean.CustomerDTO;
import com.kiisoo.ic.customer.bean.CustomerModifyDTO;
import com.kiisoo.ic.customer.bean.FriendDTO;
import com.kiisoo.ic.customer.bean.OpCustomerDTO;
import com.kiisoo.ic.customer.entity.OpCustomer;
import com.kiisoo.ic.customer.entity.OpSellerCustomerRelation;
import com.kiisoo.ic.customer.entity.OpVip;
import com.kiisoo.ic.customer.mapper.OpCustomerDOMapper;
import com.kiisoo.ic.customer.mapper.OpSellerCustomerRelationDOMapper;
import com.kiisoo.ic.customer.mapper.OpVipDOMapper;
import com.kiisoo.ic.domain.service.PrivilageDomainService;
import com.kiisoo.ic.generalize.service.RetailCompanyService;
import com.kiisoo.ic.store.entity.PoiStore;
import com.kiisoo.ic.store.entity.PoiStoreStaff;
import com.kiisoo.ic.store.mapper.PoiStoreDOMapper;
import com.kiisoo.ic.store.mapper.PoiStoreStaffDOMapper;
import com.kiisoo.ic.store.service.PoiStoreService;
import com.kiisoo.ic.synchronous.entity.TurnBackDTO;
import com.kiisoo.ic.synchronous.entity.VipDataDTO;
import com.kiisoo.ic.system.enums.RoleEnum;
import com.kiisoo.ic.webappmy.vo.StafferInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @ClassName: CustomerService
 * @Description: 客户业务类
 * @Auther: Caps
 * @Date: 2020/4/2 0002 17:06
 * @Version: v1
 */
@Service
public class CustomerService {

    @Autowired
    private OpCustomerDOMapper opCustomerDOMapper;

    @Autowired
    private OpSellerCustomerRelationDOMapper opSellerCustomerRelationDOMapper;

    @Autowired
    private OpVipDOMapper opVipDOMapper;

    @Autowired
    private PoiStoreDOMapper poiStoreDOMapper;

    @Autowired
    private PoiStoreStaffDOMapper poiStoreStaffDOMapper;

    @Autowired
    private PoiStoreService poiStoreService;

    @Autowired
    private PrivilageDomainService privilageDomainService;

    @Autowired
    private RetailCompanyService retailCompanyService;


    /**
     * token
     */
    private final static String TOKEN = "BOSIDENG";

    /**
     * 绑定客户的关系
     * @param customerDTO 传输实体
     * @Description: 根据客户联系方式查询客户id 1.判断客户是否存在，不存在就添加，存在就进行下一步 2.判断客户id和导购是否绑定了关系如果绑定了就直接下一步，如果没有就绑定 3.判断客户id和vip是否绑定了关系如果绑定了就直接下一步，如果没有就绑定
     */
    @Transactional(rollbackFor = Exception.class)
    public Long customerRelation(CustomerDTO customerDTO){
        //客户信息
        QueryWrapper<OpCustomer> customerWrapper = new QueryWrapper<>();
        customerWrapper.eq("wechat_uni_id",customerDTO.getUniId()).last("limit 1");
        OpCustomer opCustomer = opCustomerDOMapper.selectOne(customerWrapper);
        //店铺信息
        QueryWrapper<PoiStore> poiWrapper = new QueryWrapper<>();
        poiWrapper.eq("code",customerDTO.getShopCode()).last("limit 1");
        PoiStore poiStore = poiStoreDOMapper.selectOne(poiWrapper);

        //导购信息
        QueryWrapper<PoiStoreStaff> wrapper = new QueryWrapper<>();
        wrapper.eq("staff_code",customerDTO.getStaffCode()).eq("store_code",customerDTO.getShopCode()).last("limit 1");
        PoiStoreStaff poiStoreStaff = poiStoreStaffDOMapper.selectOne(wrapper);
        if(poiStoreStaff == null || poiStore == null){
            return null;
        }

        //做插入使用
        OpCustomer insertCustomer = new OpCustomer();
        insertCustomer.setWechatUniId(customerDTO.getUniId());
        insertCustomer.setName(customerDTO.getName());
        if(null != opCustomer){
            //存在--1.处理客户导购关系。
            sellerCustomerRelation(opCustomer,customerDTO.getStaffCode(),poiStore.getId(),poiStoreStaff.getUserId());
            return opCustomer.getId();
        }else {
            insertCustomer.setCreateBy(Constants.SYS_OPERATION);
            //不存在
            opCustomerDOMapper.insert(insertCustomer);
            //添加关系
            sellerCustomerRelation(insertCustomer,customerDTO.getStaffCode(),poiStore.getId(),poiStoreStaff.getUserId());
            return insertCustomer.getId();
        }
    }

    /**
     * 录入客户信息/绑定客户vip关系（如果是VIP的话）
     * @param customerModifyDTO 更新实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void customerVipRelation(CustomerModifyDTO customerModifyDTO){
        OpCustomer opCustomer = new OpCustomer(customerModifyDTO.getName(),customerModifyDTO.getPhone());
        opCustomer.setUpdateBy(Constants.SYS_OPERATION);
        QueryWrapper<OpVip> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",customerModifyDTO.getPhone()).last("limit 1");
        OpVip opVip = opVipDOMapper.selectOne(wrapper);
        if(null != opVip){
            //有vip信息就绑定信息
            opCustomer.setMemberId(opVip.getId());
        }
        QueryWrapper<OpCustomer> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("wechat_uni_id",customerModifyDTO.getUniId());
        opCustomerDOMapper.update(opCustomer,wrapper1);
    }

    /**
     * 好友添加回调通知
     * @param turnBackDTOS 数据实体
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    public void turnBack(TurnBackDTO turnBackDTOS){
        //客户信息
        QueryWrapper<OpCustomer> customerWrapper = new QueryWrapper<>();
        customerWrapper.eq("wechat_uni_id",turnBackDTOS.getWx_data().getUnit_id()).last("limit 1");
        OpCustomer opCustomer = opCustomerDOMapper.selectOne(customerWrapper);
        //店铺信息
        QueryWrapper<PoiStore> poiWrapper = new QueryWrapper<>();
        poiWrapper.eq("code",turnBackDTOS.getShop_code()).last("limit 1");
        PoiStore poiStore = poiStoreDOMapper.selectOne(poiWrapper);
        //导购信息
        QueryWrapper<PoiStoreStaff> wrapper = new QueryWrapper<>();
        wrapper.eq("staff_code",turnBackDTOS.getEa_code()).eq("store_code",turnBackDTOS.getShop_code()).last("limit 1");
        PoiStoreStaff poiStoreStaff = poiStoreStaffDOMapper.selectOne(wrapper);
        if(poiStoreStaff == null || poiStore == null){
            return;
        }

        //做插入使用 --如果没有客户信息就先创建客户信息如果有就判断是否有客户导购得关系，如果没有就添加有就不管
        OpCustomer insertCustomer = new OpCustomer();
        insertCustomer.setWechatUniId(turnBackDTOS.getWx_data().getUnit_id());
        insertCustomer.setName(turnBackDTOS.getName());
        insertCustomer.setAvatarUrl(turnBackDTOS.getWx_data().getAvatar_url());
        if(null != opCustomer){
            //存在--1.处理客户导购关系。
            sellerCustomerRelation(opCustomer,turnBackDTOS.getEa_code(),poiStore.getId(),poiStoreStaff.getUserId());
        }else {
            insertCustomer.setCreateBy(Constants.SYS_OPERATION);
            //不存在
            opCustomerDOMapper.insert(insertCustomer);
            //添加关系
            sellerCustomerRelation(insertCustomer,turnBackDTOS.getEa_code(),poiStore.getId(),poiStoreStaff.getUserId());
        }

        //处理客户vip的关系
        if(turnBackDTOS.getVip_data() != null){
            //有vip数据就不需要重新请求bsd的vip接口
            vipCheck(turnBackDTOS);
            //查询是否有这个vip如果有就绑定关系如果没有就先添加vip然后再绑定关系
        }else {
            //需要请求bsd的vip接口获取vip数据
            JSONObject jsonObject2 = JSON.parseObject(HttpClientUtil.httpGet("http://vtest.bsd.cn/BSD_WXAPP/miniProgram/getMemberDtlByUnionId?token=" + TOKEN + "&unionId=" + turnBackDTOS.getWx_data().getUnit_id()).getMessage());
            VipDataDTO vipDataDTO = new VipDataDTO();
            vipDataDTO.setBirthday(jsonObject2.getDate("birthday"));
            vipDataDTO.setName(jsonObject2.getString("memberName"));
            vipDataDTO.setPhone(jsonObject2.getString("mobileNo"));
            vipDataDTO.setRegister_time(String.valueOf(LocalDate.now()));
            vipData(vipDataDTO,turnBackDTOS.getWx_data().getUnit_id());
        }
    }

    /**
     * 添加会员数据
     * @param vipDataDTO
     */
    private void vipData(VipDataDTO vipDataDTO, String unionId){
        OpCustomer opCustomer = new OpCustomer(vipDataDTO.getName(),vipDataDTO.getPhone());
        opCustomer.setUpdateBy(Constants.SYS_OPERATION);

        QueryWrapper<OpVip> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",vipDataDTO.getPhone()).eq("name",vipDataDTO.getName());
        OpVip opVip = opVipDOMapper.selectOne(wrapper);
        if(opVip == null){
            //数据库没有这个数据--新建数据
            OpVip opVip1 = new OpVip();
            opVip1.setStatus(1L);
            opVip1.setPhone(vipDataDTO.getPhone());
            opVip1.setName(vipDataDTO.getName());
            opVip1.setBirthday(vipDataDTO.getBirthday());
            opVip1.setRegisterTime(new Date(vipDataDTO.getRegister_time()));
            opVip1.setCreateTime(new Date());
            opVip1.setUpdateTime(new Date());
            opVip1.setCreateBy(Constants.SYS_OPERATION);
            opVip1.setUpdateBy(Constants.SYS_OPERATION);
            opVipDOMapper.insert(opVip1);
            //有vip信息就绑定信息
            opCustomer.setMemberId(opVip1.getId());
        }else {
            //有vip信息就绑定信息
            opCustomer.setMemberId(opVip.getId());
        }
        QueryWrapper<OpCustomer> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("wechat_uni_id",unionId);
        opCustomerDOMapper.update(opCustomer,wrapper1);
    }

    /**
     * vip数据检验
     * @param turnBackDTO vip数据
     */
    private void vipCheck(TurnBackDTO turnBackDTO){
        OpCustomer opCustomer = new OpCustomer(turnBackDTO.getName(),turnBackDTO.getPhone());
        opCustomer.setUpdateBy(Constants.SYS_OPERATION);

        QueryWrapper<OpVip> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",turnBackDTO.getVip_data().getPhone()).eq("name",turnBackDTO.getVip_data().getName());
        OpVip opVip = opVipDOMapper.selectOne(wrapper);
        if(opVip == null){
            //数据库没有这个数据--新建数据
            OpVip opVip1 = new OpVip();
            opVip1.setStatus(1L);
            opVip1.setPhone(turnBackDTO.getVip_data().getPhone());
            opVip1.setName(turnBackDTO.getVip_data().getName());
            opVip1.setBirthday(turnBackDTO.getVip_data().getBirthday());
            opVip1.setRegisterTime(new Date(turnBackDTO.getVip_data().getRegister_time()));
            opVip1.setCreateTime(new Date());
            opVip1.setUpdateTime(new Date());
            opVip1.setCreateBy(Constants.SYS_OPERATION);
            opVip1.setUpdateBy(Constants.SYS_OPERATION);
            opVipDOMapper.insert(opVip1);
            //有vip信息就绑定信息
            opCustomer.setMemberId(opVip1.getId());
        }else {
            //有vip信息就绑定信息
            opCustomer.setMemberId(opVip.getId());
        }
        QueryWrapper<OpCustomer> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("wechat_uni_id",turnBackDTO.getWx_data().getUnit_id());
        opCustomerDOMapper.update(opCustomer,wrapper1);
    }

    /**
     * 处理客户和导购的关系
     * @param opCustomer 客户的数据信息
     * @param staffCode 导购Code
     */
    private void sellerCustomerRelation(OpCustomer opCustomer,String staffCode,long shopId,long sellerId){
        QueryWrapper<PoiStoreStaff> staf = new QueryWrapper<PoiStoreStaff>();
        staf.eq("staff_code",staffCode);
        PoiStoreStaff poiStoreStaff = poiStoreStaffDOMapper.selectOne(staf);
        QueryWrapper<OpSellerCustomerRelation> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("customer_id",opCustomer.getId()).eq("user_id",poiStoreStaff.getUserId()).eq("store_id",shopId).last("limit 1");
        OpSellerCustomerRelation opSellerCustomerRelation = opSellerCustomerRelationDOMapper.selectOne(wrapper1);
        if(null == opSellerCustomerRelation){
            //不存在就添加
            OpSellerCustomerRelation insertRelation = new OpSellerCustomerRelation();
            insertRelation.setCreateTime(new Date());
            insertRelation.setUpdateTime(new Date());
            insertRelation.setCustomerId(opCustomer.getId());
            insertRelation.setStoreId(shopId);
            insertRelation.setUserId(sellerId);
            insertRelation.setCreateBy(Constants.SYS_OPERATION);
            insertRelation.setUpdateBy(Constants.SYS_OPERATION);

            //判断是否有效
            QueryWrapper<OpSellerCustomerRelation> wrapper = new QueryWrapper<>();
            wrapper.eq("customer_id",opCustomer.getId()).last("limit 1");
            OpSellerCustomerRelation op = opSellerCustomerRelationDOMapper.selectOne(wrapper);
            if(op == null){
                //有效
                insertRelation.setType(1);
            }else {
                //无效
                insertRelation.setType(2);
            }
            opSellerCustomerRelationDOMapper.insert(insertRelation);
        }
    }

    /**
     * 根据店铺id找到顾客信息
     * @param shopIds
     */
    public List<OpCustomerDTO> getCustomerInfoByShopIds(Set<Long> shopIds, Date startDate, Date endDate, int pageNum, int pageSize){
        PageHelper.startPage(pageNum,pageSize);
        List<OpCustomerDTO> customers = opCustomerDOMapper.selectCustomerInfoByShopIds(shopIds, startDate, endDate);

        AtomicInteger number = new AtomicInteger(1 + ((pageNum-1) * pageSize));
        //求分页总数
        Page<OpCustomerDTO> pageList = (Page<OpCustomerDTO>)customers;
        Long totalSize = pageList.getTotal();
        for (OpCustomerDTO m : customers ) {
            m.setTotalSize(totalSize);
            m.setNumber(number.get());
            number.incrementAndGet();
        }
        return customers;
    }

    /**
     * 根据导购id找到顾客信息
     * @param sellerId
     */
    public List<OpCustomerDTO> getCustomerInfoBySellerId(long sellerId, Date startDate, Date endDate, int pageNum, int pageSize){
        PageHelper.startPage(pageNum,pageSize);
        List<OpCustomerDTO> customers = opCustomerDOMapper.selectCustomerInfoBySellerId(sellerId, startDate, endDate);

        AtomicInteger number = new AtomicInteger(1 + ((pageNum-1) * pageSize));
        //求分页总数
        Page<OpCustomerDTO> pageList = (Page<OpCustomerDTO>)customers;
        Long totalSize = pageList.getTotal();
        for (OpCustomerDTO m : customers ) {
            m.setTotalSize(totalSize);
            m.setNumber(number.get());
            number.incrementAndGet();
        }
        return customers;
    }

    /**
     * 根据条件查询扫码推广的客户信息
     * @param userId 用户id
     * @param shopId 店铺id
     * @param regionId 区域id
     * @param startDate 开始时间
     * @param endDate 结束时间
     */
    public List<OpCustomerDTO> getCustomerByUserAndDate(long userId,Long shopId, Long regionId , Long sellerId, Long companyId, Date startDate, Date endDate, int pageNum, int pageSize){
        Set<Long> shopIds = new HashSet<>();

        //根据店铺查询所有扫码客户信息
        List<OpCustomerDTO> opCustomerDTOS;
        if(sellerId != null){
            opCustomerDTOS = getCustomerInfoBySellerId(sellerId, startDate, endDate,pageNum,pageSize);
            return opCustomerDTOS;
        }else if(shopId != null){
            //如果有店铺则查店铺
            shopIds.add(shopId);
        }else if(regionId != null){
            //如果有区域则查区域店铺
            List<PoiStore> shops = poiStoreService.getRegionShop(regionId);
            shopIds = shops.stream().map(p -> p.getId()).collect(Collectors.toSet());
            List<Long> userAllShops = privilageDomainService.listUserDatePermission(userId);
            shopIds.retainAll(userAllShops);
        }else if(companyId != null){
            //如果有公司则查公司店铺
            List<PoiStore> shops = retailCompanyService.selectShopByCompany(companyId);
            shopIds = shops.stream().map(p -> p.getId()).collect(Collectors.toSet());
            List<Long> userAllShops = privilageDomainService.listUserDatePermission(userId);
            shopIds.retainAll(userAllShops);
        }else{
            //查询用户权限店铺
            shopIds = new HashSet<>(privilageDomainService.listUserDatePermission(userId));
        }

        //根据店铺查询所有扫码客户信息
        opCustomerDTOS = getCustomerInfoByShopIds(shopIds, startDate, endDate,pageNum,pageSize);
        return opCustomerDTOS;
    }

    /**
     * 修改客户信息
     * @param opCustomer
     */
    public void editCustomerInfo(OpCustomer opCustomer){
        opCustomerDOMapper.updateById(opCustomer);
    }

    /**
     *
     * @param userId
     * @param sellerId
     * @param search
     * @param roleCode
     */
    public Map<String,Object> listCustomer(Long userId,Long sellerId,String search,String roleCode, Integer type) throws Exception{
        Map<String,Object> results = new HashMap<>();
        Date thisDate = new Date();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, -24);
        Date lastDate = dateFormat.parse(dateFormat.format(calendar.getTime()));
        calendar.set(Calendar.HOUR_OF_DAY, -24);
        Date earlyDate = dateFormat.parse(dateFormat.format(calendar.getTime()));
        if (roleCode.equals(RoleEnum.ROLE_CODE_DZ.getRoleCode())){
            List<StafferInfoVO> stafferInfoVOS = poiStoreStaffDOMapper.selectInfoById(userId);
            Long shopId = stafferInfoVOS.get(0).getStoreId();
            List<FriendDTO> thisList = opSellerCustomerRelationDOMapper.selectShopListByDate(shopId,null,sellerId,search,thisDate,thisDate, type);
            results.put("this",thisList);
            List<FriendDTO> lastList = opSellerCustomerRelationDOMapper.selectShopListByDate(shopId,null,sellerId,search,lastDate,lastDate, type);
            results.put("last",lastList);
            List<FriendDTO> earlyList = opSellerCustomerRelationDOMapper.selectShopListByDate(shopId,null,sellerId,search,null,earlyDate, type);
            results.put("early",earlyList);
        }else{
            List<FriendDTO> thisList = opSellerCustomerRelationDOMapper.selectShopListByDate(null,userId,null,search,thisDate,thisDate, type);
            results.put("this",thisList);
            List<FriendDTO> lastList = opSellerCustomerRelationDOMapper.selectShopListByDate(null,userId,null,search,lastDate,lastDate, type);
            results.put("last",lastList);
            List<FriendDTO> earlyList = opSellerCustomerRelationDOMapper.selectShopListByDate(null,userId,null,search,null,earlyDate, type);
            results.put("early",earlyList);
        }
        return results;
    }

}