package com.yami.shop.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.yami.shop.bean.app.dto.ShopCartItemDto;
import com.yami.shop.bean.dto.XsbMemberDiscountInfo;
import com.yami.shop.bean.model.User;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.HttpUtil;
import com.yami.shop.service.UserService;
import com.yami.shop.service.XsbMemberSupportService;
import com.yami.shop.utils.SmqjhUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriUtils;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class XsbMemberSupportServiceImpl implements XsbMemberSupportService {

    private static final String XSB = "XSB";

    private final UserService userService;
    private final SmqjhUtil smqjhUtil;

    @Override
    public void enrichShopCartItems(List<ShopCartItemDto> shopCartItems, String userId) {
        if (shopCartItems == null || shopCartItems.isEmpty()) {
            return;
        }
        Map<String, String> businessTypeMap = queryBusinessTypeMap(shopCartItems);
        XsbMemberDiscountInfo memberInfo = getMemberDiscountInfo(userId);
        for (ShopCartItemDto shopCartItem : shopCartItems) {
            String businessType = businessTypeMap.get(String.valueOf(shopCartItem.getSkuId()));
            shopCartItem.setBusinessType(businessType);
            shopCartItem.setMemberDiscountShareAmount(0.0);
            if (!XSB.equalsIgnoreCase(businessType)) {
                shopCartItem.setIsMember(Boolean.FALSE);
                shopCartItem.setMemberPrice(null);
                continue;
            }
            shopCartItem.setIsMember(Boolean.TRUE.equals(memberInfo.getMember()));
            if (Boolean.TRUE.equals(memberInfo.getMember())) {
                shopCartItem.setMemberPrice(calculateMemberPrice(shopCartItem.getPrice(), memberInfo.getDiscountRate()));
            } else {
                shopCartItem.setMemberPrice(null);
            }
        }
    }

    @Override
    public XsbMemberDiscountInfo getMemberDiscountInfo(String userId) {
        XsbMemberDiscountInfo emptyInfo = defaultMemberInfo();
        if (StringUtils.isBlank(userId)) {
            return emptyInfo;
        }
        User user = userService.getUserByUserId(userId);
        if (user == null || StringUtils.isBlank(user.getUserMobile()) || StringUtils.isBlank(smqjhUtil.getSystemUrl())) {
            return emptyInfo;
        }
        try {
            String mobile = UriUtils.encodeQueryParam(user.getUserMobile(), StandardCharsets.UTF_8);
            String response = HttpUtil.get(smqjhUtil.getSystemUrl() + "/sys-api/member/discount/mobile?mobile=" + mobile);
            if (StringUtils.isBlank(response)) {
                return emptyInfo;
            }
            JSONObject root = JSONObject.parseObject(response);
            JSONObject data = root.getJSONObject("data");
            if (data == null) {
                return emptyInfo;
            }
            XsbMemberDiscountInfo info = new XsbMemberDiscountInfo();
            info.setMember(Boolean.TRUE.equals(data.getBoolean("isMember")));
            info.setDiscountRate(normalizeDiscountRate(data.getDouble("discountRate")));
            info.setMemberTypeName(data.getString("memberTypeName"));
            return info;
        } catch (Exception e) {
            log.warn("查询XSB会员折扣失败,userId={}", userId, e);
            return emptyInfo;
        }
    }

    @Override
    public boolean isXsbItem(ShopCartItemDto shopCartItem) {
        return shopCartItem != null && XSB.equalsIgnoreCase(shopCartItem.getBusinessType());
    }

    @Override
    public boolean hasXsbBusinessType(List<Long> skuIds) {
        if (CollectionUtils.isEmpty(skuIds)) {
            return false;
        }
        return queryBusinessTypeMapBySkuIds(skuIds.stream()
                        .filter(Objects::nonNull)
                        .map(String::valueOf)
                        .distinct()
                        .collect(Collectors.toList()))
                .values()
                .stream()
                .anyMatch(XSB::equalsIgnoreCase);
    }

    private Map<String, String> queryBusinessTypeMap(List<ShopCartItemDto> shopCartItems) {
        if (CollectionUtils.isEmpty(shopCartItems)) {
            return Collections.emptyMap();
        }
        List<String> skuIds = shopCartItems.stream()
                .map(ShopCartItemDto::getSkuId)
                .filter(Objects::nonNull)
                .map(String::valueOf)
                .distinct()
                .collect(Collectors.toList());
        return queryBusinessTypeMapBySkuIds(skuIds);
    }

    private Map<String, String> queryBusinessTypeMapBySkuIds(List<String> skuIds) {
        if (StringUtils.isBlank(smqjhUtil.getSmqjhPmsUrl()) || CollectionUtils.isEmpty(skuIds)) {
            return Collections.emptyMap();
        }
        try {
            String response = HttpUtil.post(smqjhUtil.getSmqjhPmsUrl() + "/querySkuBusinessTypes", skuIds);
            if (StringUtils.isBlank(response)) {
                return Collections.emptyMap();
            }
            JSONObject root = JSONObject.parseObject(response);
            JSONObject data = root.getJSONObject("data");
            return data == null ? Collections.emptyMap() : data.getInnerMap().entrySet().stream()
                    .collect(Collectors.toMap(Map.Entry::getKey, entry -> String.valueOf(entry.getValue()), (left, right) -> left));
        } catch (Exception e) {
            log.warn("查询SKU业务类型失败, skuIds={}", skuIds, e);
            return Collections.emptyMap();
        }
    }

    private Double calculateMemberPrice(Double basePrice, Double discountRate) {
        if (basePrice == null) {
            return null;
        }
        double normalizedRate = normalizeDiscountRate(discountRate);
        BigDecimal price = BigDecimal.valueOf(basePrice);
        BigDecimal memberPrice = price.multiply(BigDecimal.valueOf(normalizedRate)).setScale(2, BigDecimal.ROUND_HALF_UP);
        if (memberPrice.compareTo(price) > 0) {
            memberPrice = price;
        }
        if (memberPrice.compareTo(BigDecimal.ZERO) < 0) {
            memberPrice = BigDecimal.ZERO;
        }
        return memberPrice.doubleValue();
    }

    private Double normalizeDiscountRate(Double discountRate) {
        if (discountRate == null || discountRate <= 0 || discountRate > 1) {
            return 1.0;
        }
        return discountRate;
    }

    private XsbMemberDiscountInfo defaultMemberInfo() {
        XsbMemberDiscountInfo info = new XsbMemberDiscountInfo();
        info.setMember(Boolean.FALSE);
        info.setDiscountRate(1.0);
        info.setMemberTypeName(null);
        return info;
    }
}
