package org.dromara.web.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.idev.excel.FastExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.dromara.common.core.constant.BizConst;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.system.domain.SysDiseaseLabel;
import org.dromara.system.domain.bo.SysDiseaseLabelBo;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.domain.vo.SysDictDataVo;
import org.dromara.system.domain.vo.SysDiseaseLabelVo;
import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysDictDataService;
import org.dromara.system.service.ISysDiseaseLabelService;
import org.dromara.web.domain.ProductCategory;
import org.dromara.web.domain.ProductNutrition;
import org.dromara.web.domain.TreatmentUser;
import org.dromara.web.domain.bo.BatchProductNuyritionBo;
import org.dromara.web.domain.bo.ProductNutritionBo;
import org.dromara.web.domain.vo.ProductCategoryVo;
import org.dromara.web.domain.vo.ProductNutritionVo;
import org.dromara.web.mapper.ProductNutritionMapper;
import org.dromara.web.service.IProductCategoryService;
import org.dromara.web.service.IProductNutritionService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import java.util.*;
import java.util.stream.Collectors;

/**
 * 营养产品信息Service业务层处理
 *
 * @author h
 * @date 2025-06-26
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class ProductNutritionServiceImpl implements IProductNutritionService {

    private final ProductNutritionMapper baseMapper;

    private final ISysDeptService deptService;

    private final ISysDictDataService dictDataService;

    private final IProductCategoryService categoryService;

    private final ISysDiseaseLabelService diseaseLabelService;

    private final ISysDictDataService dataService;


    /**
     * 查询营养产品信息
     *
     * @param id 主键
     * @return 营养产品信息
     */
    @Override
    public ProductNutritionVo queryById(Long id) {
        ProductNutritionVo nutritionVo = baseMapper.selectVoById(id);
        if (null != nutritionVo) {
            String categoryIdsStr = nutritionVo.getProductCategory();
            if (StringUtils.isNotBlank(categoryIdsStr)) {//处理产品分类
                List<String> categoryNames = Arrays.stream(categoryIdsStr.split(",")).map(String::trim).filter(StringUtils::isNotBlank).map(cateId -> {
                    try {
                        return categoryService.queryById(Long.parseLong(cateId));
                    } catch (NumberFormatException e) {
                        return null;
                    }
                }).filter(Objects::nonNull).map(ProductCategoryVo::getCategoryName).filter(StringUtils::isNotBlank).collect(Collectors.toList());
                if (!categoryNames.isEmpty()) {
                    nutritionVo.setProductCategory(String.join(",", categoryNames));
                }
            }
            String labelIdsStr = nutritionVo.getProductLabel();
            String contraindicationLabelIdsStr = nutritionVo.getContraindicationLabel();

            // 处理产品标签
            if (StringUtils.isNotBlank(labelIdsStr)) {
                List<String> labelNames = Arrays.stream(labelIdsStr.split(",")).map(String::trim).filter(StringUtils::isNotBlank).map(labelid -> {
                    try {
                        return diseaseLabelService.queryById(Long.parseLong(labelid));
                    } catch (NumberFormatException e) {
                        return null;
                    }
                }).filter(Objects::nonNull).map(SysDiseaseLabelVo::getLabelName).filter(StringUtils::isNotBlank).collect(Collectors.toList());

                if (!labelNames.isEmpty()) {
                    nutritionVo.setProductLabel(String.join(",", labelNames));
                }
            }

            // 处理禁忌标签
            if (StringUtils.isNotBlank(contraindicationLabelIdsStr)) {
                List<String> contraindicationLabelNames = Arrays.stream(contraindicationLabelIdsStr.split(",")).map(String::trim).filter(StringUtils::isNotBlank).map(labelId -> {
                    try {
                        return diseaseLabelService.queryById(Long.parseLong(labelId));
                    } catch (NumberFormatException e) {
                        return null;
                    }
                }).filter(Objects::nonNull).map(SysDiseaseLabelVo::getLabelName).filter(StringUtils::isNotBlank).collect(Collectors.toList());

                if (!contraindicationLabelNames.isEmpty()) {
                    nutritionVo.setContraindicationLabel(String.join(",", contraindicationLabelNames));
                }
            }
            String departmentIdsStr = nutritionVo.getApplicableDepartment();
            if (StringUtils.isNotBlank(departmentIdsStr)) {
                List<String> departmentGroups = new ArrayList<>();
                // 按分号分组
                String[] groups = departmentIdsStr.split(";");
                Long deptId = null;
                SysDeptVo deptVo = null;
                for (String group : groups) {
                    List<String> groupNames = new ArrayList<>();
                    String[] deptIds = group.split(",");

                    for (String deptIdStr : deptIds) {
                        try {
                            deptId = Long.parseLong(deptIdStr.trim());
                            deptVo = deptService.selectDeptById(deptId);
                            if (deptVo != null && StringUtils.isNotBlank(deptVo.getDeptName())) {
                                groupNames.add(deptVo.getDeptName());
                            }
                        } catch (NumberFormatException e) {
                            // 记录日志或处理异常
                        }
                    }
                    if (!groupNames.isEmpty()) {
                        departmentGroups.add(String.join("/", groupNames));
                    }
                }

                if (!departmentGroups.isEmpty()) {
                    nutritionVo.setApplicableDepartment(String.join(",", departmentGroups));
                } else {
                    nutritionVo.setApplicableDepartment("");
                }
            }
        }
        return nutritionVo;
    }

    /**
     * 分页查询营养产品信息列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 营养产品信息分页列表
     */
    @Override
    public TableDataInfo<ProductNutritionVo> queryPageList(ProductNutritionBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ProductNutrition> lqw = buildQueryWrapper(bo);
        Page<ProductNutritionVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    public TableDataInfo<ProductNutritionVo> listAll() {
        List<ProductNutritionVo> dataList = baseMapper.selectVoList(Wrappers.lambdaQuery(ProductNutrition.class)
            .select(ProductNutrition::getId, ProductNutrition::getProductName, ProductNutrition::getProductCategory,
                ProductNutrition::getProductSpec, ProductNutrition::getProductSpecUnit, ProductNutrition::getPackageUnit,
                ProductNutrition::getConfigSalePrice, ProductNutrition::getPackagePrice, ProductNutrition::getCalorie,
                ProductNutrition::getDefaultUsage)
            .orderByDesc(ProductNutrition::getId));

        if (CollUtil.isNotEmpty(dataList)) {
            Map<String, List<SysDictDataVo>> dictMap = dataService.selectGroupByType(
                List.of(BizConst.PRODUCT_SPEC_UNIT, BizConst.PRODUCT_PACKAGE_UNIT)).getData();
            Map<String, String> specUnitMap = dictMap.get(BizConst.PRODUCT_SPEC_UNIT).stream().collect(Collectors.toMap(k1 -> k1.getDictValue(), k2 -> k2.getDictLabel(), (k1, k2) -> k1));
            Map<String, String> packageUnitMap = dictMap.get(BizConst.PRODUCT_PACKAGE_UNIT).stream().collect(Collectors.toMap(k1 -> k1.getDictValue(), k2 -> k2.getDictLabel(), (k1, k2) -> k1));

            dataList.forEach(v -> {
                String packageUnit = StrUtil.emptyToDefault(packageUnitMap.get(v.getPackageUnit()), StrUtil.EMPTY);
                String productSpecUnit = StrUtil.emptyToDefault(specUnitMap.get(v.getProductSpecUnit()), StrUtil.EMPTY);
                v.setProductSpec(v.getProductSpec() + productSpecUnit + "/" + packageUnit);
                v.setProductSpecUnit(productSpecUnit);
                v.setPackageUnit(packageUnit);
            });
        }

        return TableDataInfo.build(dataList);
    }

    /**
     * 查询符合条件的营养产品信息列表
     *
     * @param bo 查询条件
     * @return 营养产品信息列表
     */
    @Override
    public List<ProductNutritionVo> queryList(ProductNutritionBo bo) {
        LambdaQueryWrapper<ProductNutrition> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ProductNutrition> buildQueryWrapper(ProductNutritionBo bo) {
        Map<String, Object> params = bo.getParams();
        String categoryIds = null;
        if (bo.getProductCategoryList() != null && !bo.getProductCategoryList().isEmpty()) {
            categoryIds = String.join(",", bo.getProductCategoryList());
        }
        LambdaQueryWrapper<ProductNutrition> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(ProductNutrition::getCreateTime);
        if (StringUtils.isNotBlank(bo.getProductName())) {
            lqw.and(wrapper -> wrapper.like(ProductNutrition::getProductName, bo.getProductName()).or().like(ProductNutrition::getProductCode, bo.getProductName()).or());
        }
        if (StringUtils.isNotBlank(categoryIds)) {
            lqw.eq(ProductNutrition::getProductCategory, categoryIds);
        }

        return lqw;
    }

    /**
     * 新增营养产品信息
     *
     * @param bo 营养产品信息
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(ProductNutritionBo bo) {
        String categoryIds = null;
        String productLabel = null;
        String contraindicationLabel = null;
        if (bo.getProductCategoryList() != null && !bo.getProductCategoryList().isEmpty()) {
            categoryIds = String.join(",", bo.getProductCategoryList());
        }
        bo.setProductCategory(categoryIds);
        String applicableDepartment = null;
        if (bo.getApplicableDepartmentList() != null && !bo.getApplicableDepartmentList().isEmpty()) {
            applicableDepartment = bo.getApplicableDepartmentList().stream().map(array -> String.join(",", array)).collect(Collectors.joining(";"));
        }
        bo.setApplicableDepartment(applicableDepartment);
        if (bo.getProductLabelList() != null && !bo.getProductLabelList().isEmpty()) {
            List<String> labelIds = bo.getProductLabelList().stream().map(labelBo -> labelBo.getLabelId().toString()).collect(Collectors.toList());
            productLabel = String.join(",", labelIds);
        }
        bo.setProductLabel(productLabel);
        if (bo.getContraindicationLabelList() != null && !bo.getContraindicationLabelList().isEmpty()) {
            List<String> labelIds = bo.getContraindicationLabelList().stream().map(labelBo -> labelBo.getLabelId().toString()).collect(Collectors.toList());
            contraindicationLabel = String.join(",", labelIds);
        }
        bo.setContraindicationLabel(contraindicationLabel);

        ProductNutrition add = MapstructUtils.convert(bo, ProductNutrition.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改营养产品信息
     *
     * @param bo 营养产品信息
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(ProductNutritionBo bo) {
        ProductNutrition update = MapstructUtils.convert(bo, ProductNutrition.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 批量修改
     *
     * @param nutritionBo 营养产品信息
     * @return 是否修改成功
     */
    @Override
    public Boolean batchUpdateNutrition(BatchProductNuyritionBo nutritionBo) {
        Integer result = 0;
        ProductNutritionVo nutritionVo = null;
        if (null != nutritionBo && !nutritionBo.getIds().isEmpty()) {
            for (Long id : nutritionBo.getIds()) {
                nutritionVo = this.queryById(id);
                if (null != nutritionVo) {
                    nutritionVo.setShelfLifeReminder(nutritionBo.getShelfLifeReminder());
                    nutritionVo.setLicenseExpiryReminder(nutritionBo.getLicenseExpiryReminder());
                    ProductNutrition nutrition = MapstructUtils.convert(nutritionVo, ProductNutrition.class);
                    result = baseMapper.updateById(nutrition);
                }
            }
        }
        return result > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ProductNutrition entity) {
        //TODO 做一些数据校验,如唯一约束
    }

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

    @Override
    public R<?> importExcel(MultipartFile file) throws Exception {
        if (ObjUtil.isNull(file)) {
            return R.fail("请选择文件!");
        }

        List<Map<Integer, String>> excelList = FastExcel.read(file.getInputStream()).headRowNumber(3).sheet().doReadSync();

        log.info("开始导入数据");
        if (CollUtil.isEmpty(excelList)) {
            return R.fail("读取数据为空!");
        }
        log.info("size:" + excelList.size());

        Map<String, String> labelMap = MapUtil.newHashMap(excelList.size());
        dictDataService.selectMapByType("product_manufacturer").getData().forEach((k, v) -> {
            labelMap.put(v.getDictLabel(), k);
        });

        List<ProductNutrition> nutritionList = new ArrayList<>();
        StringBuilder builder = new StringBuilder();
        excelList.forEach(v -> {
            if (MapUtil.isEmpty(v) || v.size() != 3) {
                builder.append(nutritionList.size() + 4).append("、");
                return;
            }
            ProductNutrition nutrition = new ProductNutrition();
          /*  nutrition.setLabelCode(v.get(0));
            nutrition.setLabelName(v.get(1));
            nutrition.setProductCategory(labelMap.get(v.get(2)));
            if (StrUtil.isBlank(nutrition.getCategory()) || StrUtil.isBlank(nutrition.getLabelCode())
                || StrUtil.isBlank(nutrition.getLabelName())) {
                builder.append(nutritionList.size() + 4).append("、");
                return;
            }*/
            nutritionList.add(nutrition);
        });

        if (builder.length() == 0) {
            baseMapper.insertBatch(nutritionList);
        } else {
            return R.fail("以下行数据不完整：" + builder);
        }

        return R.ok("导入成功！");
    }
}
