package com.czg.service.account.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.czg.account.entity.ShopUser;
import com.czg.account.entity.ShopUserFlow;
import com.czg.account.service.ShopUserSyncService;
import com.czg.service.account.mapper.ShopUserMapper;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

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

/**
 * 店铺用户同步Service实现类
 *
 * @author tankaikai
 * @since 2025-04-08 10:18
 */
@Service
public class ShopUserSyncServiceImpl implements ShopUserSyncService {

    @Resource
    private ShopUserMapper shopUserMapper;

    /**
     * 同步合并主分店会员信息
     *
     * @param headShopId   主店id
     * @param branchShopId 分店id
     */
    @Override
    public synchronized void syncMergeShopUser(Long headShopId, Long branchShopId) {
        // 合并前置逻辑：查询主店、分店手机号码不为空的会员信息，分店和主店手机号码进行匹配
        // 合并逻辑0：分店没有绑定手机号的会员，把shop_id改为主店shop_id，把分店会员信息jsonArray格式化存储至主店用户信息的merged_users字段中
        // 合并逻辑1：（主店、分店一致）如果手机号码一致，则把分店会员信息中的 积分、余额、消费金额、消费次数合并到主店会员信息中，把分店会员信息jsonArray格式化存储至主店用户信息的merged_users字段中，再把分店用户信息删除
        // 合并逻辑2：（主店有、分店没有）不用采取任何操作，使用主店的会员信息
        // 合并逻辑3：（主店没有、分店有）把shop_id改为主店shop_id，把分店会员信息jsonArray格式化存储至merged_users字段中
        // 合并逻辑4：当用户补充了手机号码或则修改了手机号码，则需要按照手机号码进行会员信息合并，把逻辑1，2，3重新执行一遍
        List<ShopUser> branchShopNotPhoneUserList = shopUserMapper.selectListByQuery(QueryWrapper.create().eq(ShopUser::getShopId, branchShopId)
                .and(q -> {
                    q.isNull(ShopUser::getPhone).or(q1 -> {
                        q1.eq(ShopUser::getPhone, "");
                    });
                }));
        // 分店没有绑定手机号的会员
        for (ShopUser shopUser : branchShopNotPhoneUserList) {
            Long historyShopId = shopUser.getShopId();
            Long historyUserId = shopUser.getUserId();
            JSONObject branch = JSONObject.from(shopUser, JSONWriter.Feature.WriteMapNullValue);
            JSONArray objects = new JSONArray();
            objects.add(branch);
            shopUser.setShopId(headShopId);
            shopUser.setMergedUsers(objects.toJSONString(JSONWriter.Feature.WriteMapNullValue));
            shopUserMapper.update(shopUser);
            // 更新会员流水记录到主店
            UpdateChain.of(ShopUserFlow.class)
                    .set(ShopUserFlow::getShopId, headShopId)
                    .eq(ShopUserFlow::getShopId, historyShopId)
                    .eq(ShopUserFlow::getUserId, historyUserId)
                    .update();
        }
        List<ShopUser> headShopUserList = shopUserMapper.selectListByQuery(QueryWrapper.create().eq(ShopUser::getShopId, headShopId).isNotNull(ShopUser::getPhone));
        List<ShopUser> branchShopUserList = shopUserMapper.selectListByQuery(QueryWrapper.create().eq(ShopUser::getShopId, branchShopId).isNotNull(ShopUser::getPhone));
        // 如果分店没有符合条件的会员，则不进行合并
        if (CollUtil.isEmpty(branchShopUserList)) {
            return;
        }
        Map<String, ShopUser> headShopUserKv = headShopUserList.stream().collect(Collectors.toMap(ShopUser::getPhone, shopUser -> shopUser));
        Map<String, ShopUser> branchShopUserKv = branchShopUserList.stream().collect(Collectors.toMap(ShopUser::getPhone, shopUser -> shopUser));

        Set<String> headShopPhoneList = headShopUserList.stream().map(ShopUser::getPhone).collect(Collectors.toSet());
        Set<String> branchShopPhoneList = branchShopUserList.stream().map(ShopUser::getPhone).collect(Collectors.toSet());

        Set<String> phoneSet = new HashSet<>();
        phoneSet.addAll(headShopPhoneList);
        phoneSet.addAll(branchShopPhoneList);

        // 执行合并逻辑
        for (String phone : phoneSet) {
            ShopUser headShopUser = headShopUserKv.get(phone);
            ShopUser branchShopUser = branchShopUserKv.get(phone);
            // 1.如果都有
            if (ObjUtil.isNotNull(headShopUser) && ObjUtil.isNotNull(branchShopUser)) {
                toMergeCase1(headShopUser, branchShopUser);
                // 2.如果主店有，分店没有
            } else if (ObjUtil.isNotNull(headShopUser) && ObjUtil.isNull(branchShopUser)) {
                toMergeCase2(headShopUser, branchShopId);
                // 3.如果主店没有，分店有
            } else if (ObjUtil.isNull(headShopUser) && ObjUtil.isNotNull(branchShopUser)) {
                toMergeCase3(headShopId, branchShopUser);
            }
        }
    }

    /**
     * 合并会员信息 1.如果都有
     *
     * @param headShopUser   主店会员
     * @param branchShopUser 分店会员
     */
    public void toMergeCase1(ShopUser headShopUser, ShopUser branchShopUser) {
        // 合并逻辑1：（主店、分店一致）如果手机号码一致，则把分店会员信息中的 积分、余额、消费金额、消费次数合并到主店会员信息中，把分店会员信息jsonArray格式化存储至主店用户信息的merged_users字段中，再把分店用户信息删除
        headShopUser.setAccountPoints(NumberUtil.nullToZero(headShopUser.getAccountPoints()) + (NumberUtil.nullToZero(branchShopUser.getAccountPoints())));
        headShopUser.setAmount(NumberUtil.nullToZero(headShopUser.getAmount()).add(NumberUtil.nullToZero(branchShopUser.getAmount())));
        headShopUser.setConsumeCount(NumberUtil.nullToZero(headShopUser.getConsumeCount()) + (NumberUtil.nullToZero(branchShopUser.getConsumeCount())));
        headShopUser.setConsumeAmount(NumberUtil.nullToZero(headShopUser.getConsumeAmount()).add(NumberUtil.nullToZero(branchShopUser.getConsumeAmount())));
        headShopUser.setUpdateTime(LocalDateTime.now());
        String mergedUsers = StrUtil.emptyToDefault(headShopUser.getMergedUsers(), "[]");
        JSONArray objects = JSON.parseArray(mergedUsers);
        objects.add(JSONObject.from(branchShopUser, JSONWriter.Feature.WriteMapNullValue));
        headShopUser.setMergedUsers(JSON.toJSONString(objects, JSONWriter.Feature.WriteMapNullValue));
        shopUserMapper.update(headShopUser);
        // 更新会员流水记录到主店
        UpdateChain.of(ShopUserFlow.class)
                .set(ShopUserFlow::getShopId, headShopUser.getShopId())
                .eq(ShopUserFlow::getShopId, branchShopUser.getShopId())
                .eq(ShopUserFlow::getUserId, branchShopUser.getUserId())
                .update();
        shopUserMapper.delete(branchShopUser);
    }

    /**
     * 合并会员信息 2.如果主店有，分店没有
     *
     * @param headShopUser 主店会员
     * @param branchShopId 分店id
     */
    public void toMergeCase2(ShopUser headShopUser, Long branchShopId) {
        // 合并逻辑2：（主店有、分店没有）不用采取任何操作，使用主店的会员信息
    }

    /**
     * 合并会员信息 3.如果主店没有，分店有
     *
     * @param headShopId     主店id
     * @param branchShopUser 分店会员信息
     */
    public void toMergeCase3(Long headShopId, ShopUser branchShopUser) {
        // 合并逻辑3：（主店没有、分店有）把shop_id改为主店shop_id，把分店会员信息jsonArray格式化存储至merged_users字段中
        Long historyShopId = branchShopUser.getShopId();
        Long historyUserId = branchShopUser.getUserId();
        JSONObject branch = JSONObject.from(branchShopUser, JSONWriter.Feature.WriteMapNullValue);
        JSONArray objects = new JSONArray();
        objects.add(branch);
        branchShopUser.setShopId(headShopId);
        branchShopUser.setMergedUsers(objects.toJSONString(JSONWriter.Feature.WriteMapNullValue));
        shopUserMapper.update(branchShopUser);
        // 更新会员流水记录到主店
        UpdateChain.of(ShopUserFlow.class)
                .set(ShopUserFlow::getShopId, headShopId)
                .eq(ShopUserFlow::getShopId, historyShopId)
                .eq(ShopUserFlow::getUserId, historyUserId)
                .update();
    }

}
