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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.czg.account.entity.ShopConfig;
import com.czg.account.entity.ShopInfo;
import com.czg.account.service.ShopConfigService;
import com.czg.account.service.ShopInfoService;
import com.czg.constants.PpPackageConstants;
import com.czg.constants.SystemConstants;
import com.czg.exception.CzgException;
import com.czg.market.entity.PpPackage;
import com.czg.market.entity.PpPackageOrder;
import com.czg.market.service.PpHelpRecordService;
import com.czg.market.service.PpPackageService;
import com.czg.market.vo.PpPackagePageReqVo;
import com.czg.market.vo.PpPackageVO;
import com.czg.sa.StpKit;
import com.czg.service.market.mapper.PpPackageMapper;
import com.czg.service.market.mapper.PpPackageOrderMapper;
import com.czg.utils.AssertUtil;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 套餐推广套餐 服务层实现。
 *
 * @author gyj
 * @since 2025-12-18
 */
@Slf4j
@Service
public class PpPackageServiceImpl extends ServiceImpl<PpPackageMapper, PpPackage> implements PpPackageService {

    @DubboReference
    private ShopInfoService shopInfoService;

    @DubboReference
    private ShopConfigService shopConfigService;

    @Resource
    private PpHelpRecordService ppHelpRecordService;

    @Resource
    private PpPackageOrderMapper ppPackageOrderMapper;

    @Override
    public Integer getPackagePromotionSwitch(Long shopId) {
        Integer isPackagePromotion = shopConfigService.getById(shopId).getIsPackagePromotion();
        return isPackagePromotion == null ? SystemConstants.OneZero.ZERO : isPackagePromotion;
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = "shopInfo", key = "#shopId")
    public boolean updatePackagePromotionSwitch(Integer status, Long shopId) {
        ShopConfig shopConfig = new ShopConfig();
        shopConfig.setIsPackagePromotion(status);
        boolean update = shopConfigService.update(shopConfig, QueryWrapper.create().eq(ShopConfig::getId, shopId));
        if (update && status == 0) {
            // 下架所有进行中的套餐订单
            UpdateChain.of(PpPackage.class)
                    .set(PpPackage::getOnlineStatus, SystemConstants.OneZero.ZERO)
                    .eq(PpPackage::getShopId, shopId)
                    .update();

            cancelProgressingPackageOrder(StpKit.USER.getShopId(), 0L);
        }
        return update;
    }

    @Override
    public void insertPackage(PpPackageVO packageVO) {
        if (SystemConstants.SubShopType.CUSTOM.equals(packageVO.getUseShopType())) {
            AssertUtil.isBlank(packageVO.getUseShops(), "请配置可用门店");
        }

        Long shopId = StpKit.USER.getShopId();
        // 查询名称是否存在
        PpPackage ppPackage = getOne(QueryWrapper.create().eq(PpPackage::getPackageName, packageVO.getPackageName())
                .eq(PpPackage::getShopId, shopId).eq(PpPackage::getIsDel, SystemConstants.OneZero.ZERO));
        if (ppPackage != null) {
            throw new CzgException("名称已存在");
        }

        ppPackage = getEntityFromDto(packageVO);
        ppPackage.setShopId(shopId);

        save(ppPackage);
    }

    @Override
    public void updatePackage(PpPackageVO packageVO) {
        if (SystemConstants.SubShopType.CUSTOM.equals(packageVO.getUseShopType())) {
            AssertUtil.isBlank(packageVO.getUseShops(), "请配置可用门店");
        }

        Long shopId = StpKit.USER.getShopId();

        PpPackage ppPackage = getPackageById(packageVO.getId());

        if (!ppPackage.getShopId().equals(shopId)) {
            throw new CzgException("无权限");
        }

        ppPackage = getEntityFromDto(packageVO);
        updateById(ppPackage);
    }

    @Override
    @Transactional
    public boolean deletePackage(Long id) {
        Long shopId = StpKit.USER.getShopId();

        PpPackage ppPackage = getPackageById(id);

        if (!ppPackage.getShopId().equals(shopId)) {
            throw new RuntimeException("无权限");
        }

        cancelProgressingPackageOrder(StpKit.USER.getShopId(), id);

        ppPackage.setIsDel(SystemConstants.OneZero.ONE);
        return updateById(ppPackage);
    }

    @Override
    @Transactional
    public boolean updateOnlineStatus(Long id, Integer onlineStatus) {
        if (SystemConstants.OneZero.ZERO != onlineStatus && SystemConstants.OneZero.ONE != onlineStatus) {
            throw new CzgException("参数错误");
        }
        Long shopId = StpKit.USER.getShopId();

        PpPackage ppPackage = getPackageById(id);

        if (!ppPackage.getShopId().equals(shopId)) {
            throw new RuntimeException("无权限");
        }

        if (SystemConstants.OneZero.ZERO == onlineStatus) {
            cancelProgressingPackageOrder(StpKit.USER.getShopId(), id);
        }

        ppPackage.setOnlineStatus(onlineStatus);
        return updateById(ppPackage);
    }

    @Override
    public Page<PpPackageVO> getPackagePage(PpPackagePageReqVo reqVo, boolean isAdmin) {
        Long shopId = StpKit.USER.getShopId();

        // 如果没有开启操作，直接返回空数据
        Integer promotionSwitch = getPackagePromotionSwitch(shopId);
        if (!isAdmin && SystemConstants.OneZero.ZERO == promotionSwitch) {
            log.info("没有开启套餐推广");
            return PageUtil.emptyPage();
        }

        Long mainShopId = shopInfoService.getMainIdByShopId(shopId);

        QueryWrapper queryWrapper = new QueryWrapper();
        if (!isAdmin) {
            queryWrapper.eq(PpPackage::getOnlineStatus, SystemConstants.OneZero.ONE);
        }
        queryWrapper.eq(PpPackage::getIsDel, SystemConstants.OneZero.ZERO)
                .eq(PpPackage::getOnlineStatus, reqVo.getOnlineStatus());

        if (StrUtil.isNotBlank(reqVo.getPackageName())) {
            queryWrapper.like(PpPackage::getPackageName, reqVo.getPackageName());
        }
        queryWrapper.orderBy(PpPackage::getCreateTime).desc();

        queryWrapper.and(q -> {
            q.eq(PpPackage::getShopId, shopId).or(q1 -> {
                q1.eq(PpPackage::getUseShopType, SystemConstants.SubShopType.ALL).eq(PpPackage::getShopId, mainShopId);
            }).or(q2 -> {
                q2.eq(PpPackage::getUseShopType, SystemConstants.SubShopType.CUSTOM).and("FIND_IN_SET( " + shopId + ", use_shops ) > 0");
            });
        });

        Page<PpPackage> page = page(Page.of(reqVo.getPage(), reqVo.getSize()), queryWrapper);

        List<PpPackageVO> voList = new ArrayList<>();
        page.getRecords().forEach(item -> {
            if (!isAdmin) {
                item.setShopId(shopId);
            }
            voList.add(convertPackageToVo(item));
        });

        Page<PpPackageVO> voPage = new Page<>();
        BeanUtil.copyProperties(page, voPage, "records");
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public PpPackage getPackageById(Long id) {
        PpPackage ppPackage = getOne(QueryWrapper.create().eq(PpPackage::getId, id)
                .eq(PpPackage::getIsDel, SystemConstants.OneZero.ZERO));
        if (ppPackage == null) {
            throw new RuntimeException("套餐不存在");
        }
        return ppPackage;
    }

    @Override
    public PpPackageVO getPackageDetail(Long id, Long shopId) {
        PpPackage ppPackage = getPackageById(id);

        PpPackageVO packageVO = convertPackageToVo(ppPackage);

        ShopInfo shopInfo = shopInfoService.getById(shopId);
        if (shopInfo != null) {
            packageVO.setShopName(shopInfo.getShopName());
            packageVO.setShopAddress(shopInfo.getAddress());
            packageVO.setShopLogo(shopInfo.getLogo());
        }
        packageVO.setShopId(shopId);
        return packageVO;
    }

    @Override
    public PpPackageVO convertPackageToVo(PpPackage ppPackage) {
        PpPackageVO packageVO = new PpPackageVO();
        packageVO.setId(ppPackage.getId());
        packageVO.setShopId(ppPackage.getShopId());
        packageVO.setUseShopType(ppPackage.getUseShopType());
        packageVO.setUseShops(ppPackage.getUseShops());
        packageVO.setPackageName(ppPackage.getPackageName());
        packageVO.setDescription(ppPackage.getDescription());
        packageVO.setOriginPrice(ppPackage.getOriginPrice());
        packageVO.setPrice(ppPackage.getPrice());
        packageVO.setUseTimes(ppPackage.getUseTimes());
        packageVO.setOtherDesc(ppPackage.getOtherDesc());
        packageVO.setExpireHours(ppPackage.getExpireHours());
        packageVO.setOnlineStatus(ppPackage.getOnlineStatus());
        packageVO.setCreateTime(ppPackage.getCreateTime());
        packageVO.setUpdateTime(ppPackage.getUpdateTime());
        packageVO.setSaleNum(ppPackage.getSaleNum());

        packageVO.setUseWeeks(JSONArray.parseArray(ppPackage.getUseWeeks(), String.class));
        packageVO.setPackageContent(JSONArray.parseArray(ppPackage.getPackageContent(), PpPackageVO.PackageContent.class));
        packageVO.setTieredDiscount(JSONArray.parseArray(ppPackage.getTieredDiscount(), PpPackageVO.TieredDiscount.class));
        packageVO.setImages(JSONArray.parseArray(ppPackage.getImages(), String.class));
        packageVO.setDetailImages(JSONArray.parseArray(ppPackage.getDetailImages(), String.class));

        return packageVO;
    }

    public void cancelProgressingPackageOrder(Long shopId, Long packageId) {
        // 查询订单 id 集合，删除助力记录
        QueryWrapper wrapper = QueryWrapper.create();
        if (packageId != null && packageId > 0L) {
            wrapper.eq(PpPackageOrder::getPackageId, packageId);
        }
        wrapper.eq(PpPackageOrder::getShopId, shopId)
                .in(PpPackageOrder::getStatus, PpPackageConstants.OrderStatus.PROCESSING, PpPackageConstants.OrderStatus.TIMEOUT);
        List<PpPackageOrder> orderList = ppPackageOrderMapper.selectListByQuery(wrapper);
        if (orderList != null && !orderList.isEmpty()) {
            ppHelpRecordService.deleteByOrderIds(orderList.stream().map(PpPackageOrder::getId).collect(Collectors.toList()));
        }

        UpdateChain<PpPackageOrder> update = UpdateChain.of(PpPackageOrder.class)
                .set(PpPackageOrder::getStatus, PpPackageConstants.OrderStatus.CANCEL)
                .set(PpPackageOrder::getCancelTime, LocalDateTime.now())
                .set(PpPackageOrder::getCancelReason, "商家下架套餐");
        if (packageId != null && packageId > 0L) {
            update.eq(PpPackageOrder::getPackageId, packageId);
        }
        update.eq(PpPackageOrder::getShopId, shopId)
                .in(PpPackageOrder::getStatus, PpPackageConstants.OrderStatus.PROCESSING, PpPackageConstants.OrderStatus.TIMEOUT)
                .update();
    }

    public PpPackage getEntityFromDto(PpPackageVO packageVO) {
        PpPackage ppPackage = BeanUtil.copyProperties(packageVO, PpPackage.class);
        ppPackage.setPackageContent(JSONArray.toJSONString(packageVO.getPackageContent()));
        ppPackage.setUseWeeks(JSONArray.toJSONString(packageVO.getUseWeeks()));
        ppPackage.setTieredDiscount(JSONArray.toJSONString(packageVO.getTieredDiscount()));
        ppPackage.setImages(JSONArray.toJSONString(packageVO.getImages()));
        ppPackage.setDetailImages(JSONArray.toJSONString(packageVO.getDetailImages()));
        return ppPackage;
    }
}
