package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import shop.alien.entity.store.*;
import shop.alien.entity.store.vo.LifeTuanGouParamVo;
import shop.alien.entity.store.vo.StoreGroupPackageVO;
import shop.alien.mapper.StoreGroupPackageMapper;
import shop.alien.mapper.StoreLabelTypeMapper;
import shop.alien.store.service.LifeGroupPackageService;
import shop.alien.store.service.StoreGroupPackageService;
import shop.alien.store.util.GroupConstant;
import shop.alien.util.common.UniqueRandomNumGenerator;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 八大类团购套餐表 服务实现类
 * </p>
 *
 * @author ssk
 * @since 2025-05-06
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class StoreGroupPackageServiceImpl extends ServiceImpl<StoreGroupPackageMapper, StoreGroupPackage> implements StoreGroupPackageService {

    private final StoreLabelTypeMapper storeLabelTypeMapper;

    private final LifeGroupPackageService lifeGroupPackageService;

    @Override
    public StoreGroupPackageVO addGroup(StoreGroupPackageVO storeGroupPackageVO) {
        try {
            log.info("开始创建团购套餐, 请求参数: {}", storeGroupPackageVO);

            // 参数校验
            if (storeGroupPackageVO == null) {
                throw new RuntimeException("请求参数不能为空");
            }

            LifeCoupon lifeCoupon = storeGroupPackageVO.getStoreGroupPackage();
            if (lifeCoupon == null) {
                log.error("创建团购套餐失败: 团购套餐信息为空");
                throw new RuntimeException("团购套餐信息不能为空");
            }
            if ("1".equals(lifeCoupon.getValidityPeriodType())) {
                if (StringUtil.isNotEmpty(lifeCoupon.getValidityPeriod())) {
                    String[] split = lifeCoupon.getValidityPeriod().split(",");
                    long diffSeconds = Math.abs(Long.parseLong(split[1]) - Long.parseLong(split[0]));
                    lifeCoupon.setExpirationDate((int) (diffSeconds / 86400000) + 1);
                }
            }
            LifeTuanGouParamVo lifeTuanGouParamVo = new LifeTuanGouParamVo();
            LifeCoupon tuangou = new LifeCoupon();
            BeanUtils.copyProperties(lifeCoupon, tuangou);
            lifeTuanGouParamVo.setTuangou(tuangou);
            lifeCoupon.setCouponCode(UniqueRandomNumGenerator.generateUniqueCode(12));

            // 处理标签中间表数据
            try {
                processLabelType(lifeCoupon);
            } catch (Exception e) {
                log.error("创建团购套餐失败: 处理标签信息异常", e);
                throw new RuntimeException("处理标签信息失败");
            }
            List<LifeGroupPackage> lifeGroupPackages = new ArrayList<>();
            // 处理套餐子表信息
            List<StoreGroupInfo> storeGroupInfos = storeGroupPackageVO.getStoreGroupInfos();

            if (!CollectionUtils.isEmpty(storeGroupInfos)) {
                for (StoreGroupInfo storeGroupInfo : storeGroupInfos) {
                    LifeGroupPackage lifeGroupPackage = new LifeGroupPackage();
                    BeanUtils.copyProperties(storeGroupInfo, lifeGroupPackage);
                    lifeGroupPackage.setGroupName(storeGroupInfo.getCategory());
                    lifeGroupPackage.setDishName(storeGroupInfo.getServiceName());
                    lifeGroupPackage.setQty(storeGroupInfo.getNum());
                    lifeGroupPackage.setPrice(storeGroupInfo.getPrice().toString());
                    lifeGroupPackages.add(lifeGroupPackage);
                }
            }
            lifeTuanGouParamVo.setTuangouPackageList(lifeGroupPackages);
            lifeGroupPackageService.addOrUpdateGroupPackage(lifeTuanGouParamVo);
        } catch (Exception e) {
            log.error("创建团购套餐发生异常", e);
            throw new RuntimeException(e.getMessage());
        }
        log.info("创建团购套餐成功, 返回结果: {}", storeGroupPackageVO);
        return storeGroupPackageVO;
    }

    @Transactional
    @Override
    public StoreGroupPackageVO addHotelGroup(StoreGroupPackageVO storeGroupPackageVO) {
        try {
            log.info("开始创建酒店团购套餐,: {}", storeGroupPackageVO);

            // 参数校验
            validateStoreGroupPackageVO(storeGroupPackageVO);
            LifeCoupon lifeCoupon = storeGroupPackageVO.getStoreGroupPackage();

            // 有效期类型为天时，计算天数
            calculateExpirationDateIfNecessary(lifeCoupon);

            LifeTuanGouParamVo lifeTuanGouParamVo = new LifeTuanGouParamVo();
            LifeCoupon tuangou = new LifeCoupon();
            BeanUtils.copyProperties(lifeCoupon, tuangou);
            lifeTuanGouParamVo.setTuangou(tuangou);
            lifeCoupon.setCouponCode(UniqueRandomNumGenerator.generateUniqueCode(12));

            // 处理标签中间表数据
            try {
                processLabelType(lifeCoupon);
            } catch (Exception e) {
                log.error("创建酒店团购套餐失败: 处理标签信息异常", e);
                throw new RuntimeException("处理标签信息失败");
            }
            //创建子表集合
            List<StoreHotelGroupRoomInfo> storeHotelGroupRoomInfos = new ArrayList<>();

            // 将前端传入的子表信息，转换成酒店子表信息
            List<StoreHotelGroupRoomInfo> hotelGroupRoomInfos = storeGroupPackageVO.getStoreHotelGroupRoomInfos();
            hotelGroupRoomInfos.forEach(storeHotelGroupInfo -> {
                StoreHotelGroupRoomInfo storeHotelGroupRoomInfo = new StoreHotelGroupRoomInfo();
                BeanUtils.copyProperties(storeHotelGroupInfo, storeHotelGroupRoomInfo);
                storeHotelGroupRoomInfos.add(storeHotelGroupRoomInfo);
            });

            //将主表信息子表信息存入库中
            lifeTuanGouParamVo.setTuangouHotelRoomList(storeHotelGroupRoomInfos);
            lifeGroupPackageService.addOrUpdateHotelGroupPackage(lifeTuanGouParamVo);
        } catch (
                Exception e) {
            log.error("创建酒店团购套餐发生异常", e);
            throw new RuntimeException(e.getMessage());
        }
        log.info("创建酒店团购套餐成功, 返回结果: {}", storeGroupPackageVO);
        return storeGroupPackageVO;
    }

    private static void validateStoreGroupPackageVO(StoreGroupPackageVO storeGroupPackageVO) {
        if (storeGroupPackageVO == null || storeGroupPackageVO.getStoreGroupPackage() == null ||
                CollectionUtils.isEmpty(storeGroupPackageVO.getStoreHotelGroupRoomInfos())) {
            throw new RuntimeException("请求参数不能为空");
        }
    }

    private static void calculateExpirationDateIfNecessary(LifeCoupon lifeCoupon) {
        if (StringUtil.isNotEmpty(lifeCoupon.getValidityPeriod()) &&
                GroupConstant.VALIDITY_PERIOD_TYPE_DAY.equals(lifeCoupon.getValidityPeriodType())) {
            String[] split = lifeCoupon.getValidityPeriod().split(",");
            long diffSeconds = Math.abs(Long.parseLong(split[1]) - Long.parseLong(split[0]));
            lifeCoupon.setExpirationDate((int) (diffSeconds / 86400000) + 1);
        }
    }

    /**
     * 处理标签整合
     *
     * @param lifeCoupon 团购套餐信息
     */
    private void processLabelType(LifeCoupon lifeCoupon) throws Exception {
        StoreLabelType storeLabelType = new StoreLabelType();
        storeLabelType.setStoreId(Integer.parseInt(lifeCoupon.getStoreId()));
        storeLabelType.setLabelType("1");
        storeLabelType.setStoreType(lifeCoupon.getStoreType());

        StringBuilder label = getStringBuilder(lifeCoupon);
        storeLabelType.setLabel(label.toString());
        List<StoreLabelType> storeLabelTypes = storeLabelTypeMapper.selectList(new LambdaQueryWrapper<StoreLabelType>().eq(StoreLabelType::getLabelType, 1)
                .eq(StoreLabelType::getStoreId, Integer.parseInt(lifeCoupon.getStoreId())));
        int insertResult = 0;
        if (!storeLabelTypes.isEmpty()) {
            for (StoreLabelType labelType : storeLabelTypes) {
                // 将字符串按逗号分割并转换为整数列表
                List<Integer> list1 = new ArrayList<>();
                if (StringUtil.isNotEmpty(labelType.getLabel())) {
                    list1 = Arrays.stream(labelType.getLabel().split(","))
                            .map(String::trim)
                            .map(Integer::parseInt)
                            .collect(Collectors.toList());
                }
                List<Integer> list2 = new ArrayList<>();
                if (StringUtil.isNotEmpty(label.toString())) {
                    list2 = Arrays.stream(label.toString().split(","))
                            .map(String::trim)
                            .map(Integer::parseInt)
                            .collect(Collectors.toList());
                }

                // 合并两个列表并去重，保留顺序
                Set<Integer> uniqueSet = new LinkedHashSet<>(list1);
                uniqueSet.addAll(list2);

                // 转换为字符串
                String result = String.join(",", uniqueSet.stream()
                        .map(String::valueOf)
                        .collect(Collectors.toList()));
                labelType.setLabel(result);
                insertResult = storeLabelTypeMapper.updateById(labelType);
            }
        } else {
            insertResult = storeLabelTypeMapper.insert(storeLabelType);
        }

        if (insertResult <= 0) {
            throw new RuntimeException("保存标签信息失败");
        }
    }

    /**
     * 处理标签整合
     *
     * @param lifeCoupon 团购套餐信息
     * @return 标签字符串
     */
    private static StringBuilder getStringBuilder(LifeCoupon lifeCoupon) throws Exception {
        StringBuilder label = new StringBuilder();
        String separator = ",";

        // 定义需要处理的字段列表
        List<String> fieldsToProcess = Arrays.asList(
                "entertainmentFacilitiesCode", "convenienceFacilitiesCode", "bathroomFacilitiesCode",
                "bathProductsCode", "serviceCode", "safetyCode", "childrenFlag", "petFlag", "hygieneCode",
                "foundationCode", "bathroomCode", "kitchenCode", "roomTypeCode", "businessTypes", "cancellationPolicyType",
                "boxTypeCode", "snacksCode", "tangchiCode", "sweatSaunaCode", "massageTechniqueCode", "massageAreaCode", "massageToolsCode",
                "compressToolsCode"
        );

        // 处理普通字段
        for (String fieldName : fieldsToProcess) {
            Field field = LifeCoupon.class.getDeclaredField(fieldName);
            field.setAccessible(true);
            String value = (String) field.get(lifeCoupon);
            if (StringUtil.isNotEmpty(value)) {
                if (label.length() > 0) {
                    label.append(separator);
                }
                label.append(value);
            }
        }
        return label;
    }
}
