package com.hotwj.platform.operationManagement.hourPackage.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hotwj.platform.operationManagement.hourPackage.domain.HotHourPackage;
import com.hotwj.platform.operationManagement.hourPackage.domain.bo.HotHourPackageBo;
import com.hotwj.platform.operationManagement.hourPackage.domain.vo.HotHourPackageVo;
import com.hotwj.platform.operationManagement.hourPackage.enums.HotHourPackageTypeEnum;
import com.hotwj.platform.operationManagement.hourPackage.mapper.HotHourPackageMapper;
import com.hotwj.platform.operationManagement.hourPackage.service.IHotHourPackageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 学时套餐Service业务层处理
 *
 * @author shihongwei
 * @date 2026-05-08
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class HotHourPackageServiceImpl implements IHotHourPackageService {

    private final HotHourPackageMapper baseMapper;

    /**
     * 查询学时套餐
     *
     * @param id 主键
     * @return 学时套餐
     */
    @Override
    public HotHourPackageVo queryById(Long id) {
        HotHourPackageVo vo = baseMapper.selectVoById(id);
        if (vo != null) {
            fillDerivedFields(vo);
        }
        return vo;
    }

    /**
     * 分页查询学时套餐列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 学时套餐分页列表
     */
    @Override
    public TableDataInfo<HotHourPackageVo> queryPageList(HotHourPackageBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<HotHourPackage> lqw = buildQueryWrapper(bo);
        Page<HotHourPackageVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        if (result.getRecords() != null) {
            result.getRecords().forEach(this::fillDerivedFields);
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的学时套餐列表
     *
     * @param bo 查询条件
     * @return 学时套餐列表
     */
    @Override
    public List<HotHourPackageVo> queryList(HotHourPackageBo bo) {
        LambdaQueryWrapper<HotHourPackage> lqw = buildQueryWrapper(bo);
        List<HotHourPackageVo> list = baseMapper.selectVoList(lqw);
        list.forEach(this::fillDerivedFields);
        return list;
    }

    private LambdaQueryWrapper<HotHourPackage> buildQueryWrapper(HotHourPackageBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HotHourPackage> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(HotHourPackage::getId);
        lqw.eq(bo.getCompanyId() != null, HotHourPackage::getCompanyId, bo.getCompanyId());
        lqw.eq(StringUtils.isNotBlank(bo.getPackageCode()), HotHourPackage::getPackageCode, bo.getPackageCode());
        lqw.like(StringUtils.isNotBlank(bo.getPackageName()), HotHourPackage::getPackageName, bo.getPackageName());
        lqw.eq(HotHourPackage::getHourType, bo.getHourType() != null ? bo.getHourType() : HotHourPackageTypeEnum.GENERAL.getCode());
        lqw.eq(bo.getHourCount() != null, HotHourPackage::getHourCount, bo.getHourCount());
        lqw.eq(bo.getOriginPrice() != null, HotHourPackage::getOriginPrice, bo.getOriginPrice());
        lqw.eq(bo.getStatus() != null, HotHourPackage::getStatus, bo.getStatus());
        lqw.eq(bo.getSortNo() != null, HotHourPackage::getSortNo, bo.getSortNo());
        lqw.like(StringUtils.isNotBlank(bo.getCreateByName()), HotHourPackage::getCreateByName, bo.getCreateByName());
        lqw.like(StringUtils.isNotBlank(bo.getUpdateByName()), HotHourPackage::getUpdateByName, bo.getUpdateByName());
        lqw.eq(bo.getIsDeleted() != null, HotHourPackage::getIsDeleted, bo.getIsDeleted());
        lqw.eq(bo.getPackagePrice() != null, HotHourPackage::getPackagePrice, bo.getPackagePrice());
        lqw.like(StringUtils.isNotBlank(bo.getPackageDesc()), HotHourPackage::getPackageDesc, bo.getPackageDesc());
        return lqw;
    }

    /**
     * 新增学时套餐
     *
     * @param bo 学时套餐
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(HotHourPackageBo bo) {
        HotHourPackage add = MapstructUtils.convert(bo, HotHourPackage.class);
        prepareEntityForSave(add, true);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改学时套餐
     *
     * @param bo 学时套餐
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(HotHourPackageBo bo) {
        HotHourPackage update = MapstructUtils.convert(bo, HotHourPackage.class);
        HotHourPackage current = baseMapper.selectById(update.getId());
        if (current == null) {
            throw new ServiceException("学时套餐不存在");
        }
        if (update.getPackageCode() == null) {
            update.setPackageCode(current.getPackageCode());
        }
        if (update.getCompanyId() == null) {
            update.setCompanyId(current.getCompanyId());
        }
        if (update.getPackagePrice() == null) {
            update.setPackagePrice(current.getPackagePrice());
        }
        if (update.getPackageDesc() == null) {
            update.setPackageDesc(current.getPackageDesc());
        }
        if (update.getSortNo() == null) {
            update.setSortNo(current.getSortNo());
        }
        if (update.getRemark() == null) {
            update.setRemark(current.getRemark());
        }
        prepareEntityForSave(update, false);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(HotHourPackage entity) {
        if (StringUtils.isBlank(entity.getPackageName())) {
            throw new ServiceException("套餐名称不能为空");
        }
        if (entity.getHourCount() == null || entity.getHourCount() <= 0) {
            throw new ServiceException("学时必须大于0");
        }
        if (entity.getOriginPrice() == null || entity.getOriginPrice().compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("套餐原价格必须大于0");
        }
        if (entity.getPackagePrice() != null && entity.getPackagePrice().compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("套餐活动价必须大于0");
        }
        if (entity.getPackagePrice() != null && entity.getPackagePrice().compareTo(entity.getOriginPrice()) > 0) {
            throw new ServiceException("套餐活动价不能大于原价格");
        }
        if (entity.getStatus() == null || (entity.getStatus() != 0L && entity.getStatus() != 1L)) {
            throw new ServiceException("是否启用取值不正确");
        }
        LambdaQueryWrapper<HotHourPackage> lqw = Wrappers.lambdaQuery();
        lqw.eq(HotHourPackage::getPackageName, entity.getPackageName());
        lqw.eq(HotHourPackage::getHourType, HotHourPackageTypeEnum.GENERAL.getCode());
        lqw.ne(entity.getId() != null, HotHourPackage::getId, entity.getId());
        if (baseMapper.selectCount(lqw) > 0) {
            throw new ServiceException("套餐名称已存在，请勿重复添加");
        }
    }

    private void prepareEntityForSave(HotHourPackage entity, boolean create) {
        entity.setHourType(HotHourPackageTypeEnum.GENERAL.getCode());
        entity.setApplicableTypes(String.valueOf(HotHourPackageTypeEnum.GENERAL.getCode()));
        entity.setOriginPrice(normalizeMoney(entity.getOriginPrice()));
        entity.setPackagePrice(normalizeOptionalMoney(entity.getPackagePrice()));
        entity.setUnitPrice(calculateUnitPrice(entity.getOriginPrice(), entity.getPackagePrice(), entity.getHourCount()));
        if (entity.getStatus() == null) {
            entity.setStatus(1L);
        }
        if (create && StringUtils.isBlank(entity.getPackageCode())) {
            entity.setPackageCode("HP" + IdUtil.getSnowflakeNextIdStr());
        }
    }

    private void fillDerivedFields(HotHourPackageVo vo) {
        vo.setHourType(HotHourPackageTypeEnum.GENERAL.getCode());
        vo.setApplicableTypes(String.valueOf(HotHourPackageTypeEnum.GENERAL.getCode()));
        vo.setUnitPrice(calculateUnitPrice(vo.getOriginPrice(), vo.getPackagePrice(), vo.getHourCount()));
    }

    private BigDecimal calculateUnitPrice(BigDecimal originPrice, BigDecimal packagePrice, Long hourCount) {
        if (hourCount == null || hourCount <= 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal effectivePrice = packagePrice != null ? packagePrice : originPrice;
        if (effectivePrice == null) {
            return BigDecimal.ZERO;
        }
        return effectivePrice.divide(BigDecimal.valueOf(hourCount), 2, RoundingMode.HALF_UP);
    }

    private BigDecimal normalizeMoney(BigDecimal amount) {
        return amount == null ? null : amount.setScale(2, RoundingMode.HALF_UP);
    }

    private BigDecimal normalizeOptionalMoney(BigDecimal amount) {
        return amount == null ? null : amount.setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 校验并批量删除学时套餐信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
