package com.czg.service.market.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.account.dto.shopuser.ShopUserAddDTO;
import com.czg.account.entity.ShopInfo;
import com.czg.account.entity.ShopUser;
import com.czg.account.entity.UserInfo;
import com.czg.account.entity.table.ShopUserTableDef;
import com.czg.account.entity.table.UserInfoTableDef;
import com.czg.account.service.ShopInfoService;
import com.czg.account.service.ShopUserService;
import com.czg.account.service.UserInfoService;
import com.czg.exception.CzgException;
import com.czg.market.dto.MemberConfigDTO;
import com.czg.market.dto.MemberOrderDTO;
import com.czg.market.entity.MemberOrder;
import com.czg.market.entity.table.MemberOrderTableDef;
import com.czg.market.service.MemberOrderService;
import com.czg.market.service.TbMemberConfigService;
import com.czg.market.vo.MemberConfigVO;
import com.czg.market.vo.MmberOrderVO;
import com.czg.sa.StpKit;
import com.czg.service.market.enums.OrderStatusEnums;
import com.czg.service.market.mapper.MemberOrderMapper;
import com.czg.utils.AssertUtil;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 会员充值订单 服务层实现。
 *
 * @author zs
 * @since 2025-09-11
 */
@DubboService
public class MemberOrderServiceImpl extends ServiceImpl<MemberOrderMapper, MemberOrder> implements MemberOrderService {
    @DubboReference
    private ShopInfoService shopInfoService;
    @DubboReference
    private UserInfoService userInfoService;
    @DubboReference
    private ShopUserService shopUserService;
    @DubboReference
    private TbMemberConfigService memberConfigService;

    @Override
    public Map<String, Object> pageInfo(String startTime, String endTime, String key) {
        LocalDateTime start = StrUtil.isBlank(startTime) ? null : DateUtil.parseLocalDateTime(startTime);
        LocalDateTime end   = StrUtil.isBlank(endTime) ? null : DateUtil.parseLocalDateTime(endTime);

        Map<String, Object> map = BeanUtil.beanToMap(pageAs(PageUtil.buildPage(), QueryWrapper.create()
                .leftJoin(UserInfoTableDef.USER_INFO).on(UserInfoTableDef.USER_INFO.ID.eq(MemberOrderTableDef.MEMBER_ORDER.USER_ID))
                .leftJoin(ShopUserTableDef.SHOP_USER).on(ShopUserTableDef.SHOP_USER.MAIN_SHOP_ID.eq(MemberOrderTableDef.MEMBER_ORDER.SHOP_ID)
                        .and(ShopUserTableDef.SHOP_USER.USER_ID.eq(MemberOrderTableDef.MEMBER_ORDER.USER_ID)))
                .le(MemberOrder::getCreateTime, end)
                .ge(MemberOrder::getCreateTime, start)
                .and(a -> {
                    a.or(r -> {
                        r.like(ShopUser::getId, key);
                    });

                    a.or(r -> {
                        r.like(UserInfo::getNickName, key);
                    });
                })
                .eq(MemberOrder::getShopId, StpKit.USER.getMainShopId())
                .select(MemberOrderTableDef.MEMBER_ORDER.ALL_COLUMNS)
                .select(ShopUserTableDef.SHOP_USER.NICK_NAME,
                        ShopUserTableDef.SHOP_USER.PHONE)
                .orderBy(MemberOrder::getCreateTime, true), MmberOrderVO.class
        ));
        map.put("totalAmount", getOneAsOpt(QueryWrapper.create()
                .leftJoin(UserInfoTableDef.USER_INFO).on(UserInfoTableDef.USER_INFO.ID.eq(MemberOrderTableDef.MEMBER_ORDER.USER_ID))
                .leftJoin(ShopUserTableDef.SHOP_USER).on(ShopUserTableDef.SHOP_USER.MAIN_SHOP_ID.eq(MemberOrderTableDef.MEMBER_ORDER.SHOP_ID)
                        .and(ShopUserTableDef.SHOP_USER.USER_ID.eq(MemberOrderTableDef.MEMBER_ORDER.USER_ID)))
                .le(MemberOrder::getCreateTime, end)
                .ge(MemberOrder::getCreateTime, start)
                .and(a -> {
                    a.or(r -> {
                        r.like(ShopUser::getId, key);
                    });

                    a.or(r -> {
                        r.like(UserInfo::getNickName, key);
                    });
                })
                .select("sum(tb_member_order.amount)")
                .eq(MemberOrder::getShopId, StpKit.USER.getMainShopId()), BigDecimal.class).orElse(BigDecimal.ZERO));
        return map;
    }

    @Override
    public MemberOrder createMemberOrder(MemberOrderDTO orderDTO) {
        ShopInfo shopInfo = shopInfoService.getById(orderDTO.getShopId());
        AssertUtil.isNull(shopInfo, "生成订单失败，店铺信息不存在");

        UserInfo userInfo = userInfoService.getById(orderDTO.getUserId());
        AssertUtil.isNull(userInfo, "生成订单失败，用户信息不存在");


        MemberConfigVO memberConfigVO = memberConfigService.detail(shopInfo.getId());

        if (memberConfigVO.getIsSubmitInfo() == 1) {
            AssertUtil.isBlank(orderDTO.getBirthDay(), "生日不能为空");
            AssertUtil.isBlank(orderDTO.getNickName(), "名称不能为空");
            AssertUtil.isNull(orderDTO.getSex(), "性别不能为空");

            userInfo.setSex(orderDTO.getSex());
            userInfo.setNickName(orderDTO.getNickName());
            userInfo.setBirthDay(orderDTO.getBirthDay());
        }

        shopUserService.join(orderDTO.getShopId(), orderDTO.getUserId(), new ShopUserAddDTO()
                .setPhone(userInfo.getPhone())
                .setSex(userInfo.getSex())
                .setHeadImg(userInfo.getHeadImg())
                .setAmount(BigDecimal.ZERO)
                .setBirthDay(userInfo.getBirthDay())
                .setIsVip(0)
                .setNickName(userInfo.getNickName())
        );


        if ("PAY".equals(memberConfigVO.getOpenType())){
            if(memberConfigVO.getConfigList() == null || memberConfigVO.getConfigList().isEmpty()) {
                throw new CzgException("会员开通方案未配置，请联系店铺");
            }
            AssertUtil.isBlank(orderDTO.getName(), "方案名称不能为空");
            AssertUtil.isNull(orderDTO.getNum(), "开通周期数不为空");

            MemberConfigDTO.ConfigList configItem = memberConfigVO.getConfigList().stream()
                    .filter(item -> item.getName().equals(orderDTO.getName()))
                    .findFirst()
                    .orElseThrow(() -> new CzgException("会员开通方案未配置，请联系店铺"));

            //生成订单
            MemberOrder orderInfo = new MemberOrder();

            orderInfo.setOrderNo(orderDTO.getPlatformType() + "ME" + IdUtil.getSnowflakeNextId());
            orderInfo.setShopId(orderDTO.getShopId());
            orderInfo.setPayAmount(BigDecimal.ZERO);
            orderInfo.setStatus(OrderStatusEnums.UNPAID.getCode());
            orderInfo.setAmount(configItem.getPrice().multiply(BigDecimal.valueOf(orderDTO.getNum())));
            orderInfo.setPrice(configItem.getPrice());
            orderInfo.setName(configItem.getName());
            orderInfo.setUserId(orderDTO.getUserId());
            orderInfo.setReward(configItem.getReward());
            orderInfo.setCircleTime(configItem.getCircleTime());
            orderInfo.setCircleUnit(configItem.getCircleUnit());
            if (configItem.getCouponList() != null && !configItem.getCouponList().isEmpty()) {
                orderInfo.setCouponList(JSONObject.toJSONString(configItem.getCouponList()));
            }
            orderInfo.setNum(orderDTO.getNum());
            save(orderInfo);
            return orderInfo;
        }else {
            memberConfigService.joinMember(shopInfo.getId(), orderDTO.getUserId(), null);
            return null;
        }
    }
}
