package org.dromara.web.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
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.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.config.RedisUtil;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.SysDiseaseLabel;
import org.dromara.system.domain.SysFoodCategory;
import org.dromara.system.domain.SysFoodIngredient;
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.mapper.SysDeptMapper;
import org.dromara.system.mapper.SysDiseaseLabelMapper;
import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysDictDataService;
import org.dromara.system.service.ISysDiseaseLabelService;
import org.dromara.web.domain.ProductManufacturer;
import org.dromara.web.domain.ProductNutrition;
import org.dromara.web.domain.ProductSupplier;
import org.dromara.web.domain.SuppliesCategory;
import org.dromara.web.domain.SuppliesManage;
import org.dromara.web.domain.bo.BatchSuppliesManageBo;
import org.dromara.web.domain.bo.SuppliesManageBo;
import org.dromara.web.domain.vo.ProductNutritionVo;
import org.dromara.web.domain.vo.SuppliesCategoryVo;
import org.dromara.web.domain.vo.SuppliesManageVo;
import org.dromara.web.mapper.ProductManufacturerMapper;
import org.dromara.web.mapper.ProductSupplierMapper;
import org.dromara.web.mapper.SuppliesCategoryMapper;
import org.dromara.web.mapper.SuppliesManageMapper;
import org.dromara.web.service.ISuppliesCategoryService;
import org.dromara.web.service.ISuppliesManageService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 耗材管理Service业务层处理
 *
 * @author Lion Li
 * @date 2025-07-02
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SuppliesManageServiceImpl implements ISuppliesManageService {

    private final SuppliesManageMapper baseMapper;

    private final SysDeptMapper deptMapper;

    private final ISysDeptService deptService;

    private final SysDiseaseLabelMapper labelMapper;

    private final SuppliesCategoryMapper categoryMapper;

    private final ProductSupplierMapper supplierMapper;

    private final ProductManufacturerMapper manufacturerMapper;

    private final ISysDictDataService dictDataService;

    private final ISuppliesCategoryService categoryService;

    private final ISysDiseaseLabelService diseaseLabelService;


    /**
     * 查询耗材管理
     *
     * @param id 主键
     * @return 耗材管理
     */
    @Override
    public SuppliesManageVo queryById(Long id) {
        SuppliesManageVo suppliesManageVo = baseMapper.selectVoById(id);
        String labelIdsStr = null;
        String categoryIdsStr = null;
        String departmentIdsStr = null;
        if (null != suppliesManageVo) {
            labelIdsStr = suppliesManageVo.getProductLabel();
            categoryIdsStr = suppliesManageVo.getSuppliesCategoryId();
            departmentIdsStr = suppliesManageVo.getApplicableDepartment();
        }
        // 处理产品标签
        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()) {
                suppliesManageVo.setProductLabel(String.join(",", labelNames));
            }
        }
        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(SuppliesCategoryVo::getCategoryName).filter(StringUtils::isNotBlank).collect(Collectors.toList());
            if (!categoryNames.isEmpty()) {
                suppliesManageVo.setSuppliesCategoryId(String.join(",", categoryNames));
            }
        }

        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()) {
                suppliesManageVo.setApplicableDepartment(String.join(",", departmentGroups));
            } else {
                suppliesManageVo.setApplicableDepartment("");
            }
        }
        return suppliesManageVo;
    }

    /**
     * 分页查询耗材管理列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 耗材管理分页列表
     */
    @Override
    public TableDataInfo<SuppliesManageVo> queryPageList(SuppliesManageBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SuppliesManage> lqw = buildQueryWrapper(bo);
        Page<SuppliesManageVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    public TableDataInfo<SuppliesManageVo> listAll() {
        List<SuppliesManageVo> dataList = baseMapper.selectVoList(Wrappers.lambdaQuery(SuppliesManage.class)
            .select(SuppliesManage::getId, SuppliesManage::getSuppliesName,
                SuppliesManage::getSuppliesSpec, SuppliesManage::getSuppliesUnit, SuppliesManage::getSuppliesSpecUnit,
                SuppliesManage::getSellPrice)
            .orderByDesc(SuppliesManage::getId));

        if (CollUtil.isNotEmpty(dataList)) {
            Map<String, List<SysDictDataVo>> dictMap = dictDataService.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.getSuppliesUnit()), StrUtil.EMPTY);
                String productSpecUnit = StrUtil.emptyToDefault(specUnitMap.get(v.getSuppliesSpecUnit()), StrUtil.EMPTY);

                v.setSuppliesSpec(v.getSuppliesSpec() + productSpecUnit + "/" + packageUnit);
                v.setSuppliesSpecUnit(productSpecUnit);
                v.setSuppliesUnit(packageUnit);
            });
        }

        return TableDataInfo.build(dataList);
    }

    /**
     * 查询符合条件的耗材管理列表
     *
     * @param bo 查询条件
     * @return 耗材管理列表
     */
    @Override
    public List<SuppliesManageVo> queryList(SuppliesManageBo bo) {
        LambdaQueryWrapper<SuppliesManage> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<SuppliesManage> buildQueryWrapper(SuppliesManageBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SuppliesManage> lqw = Wrappers.lambdaQuery();
        String categoryIds = null;
        if (bo.getSuppliesCategoryList() != null && !bo.getSuppliesCategoryList().isEmpty()) {
            categoryIds = String.join(",", bo.getSuppliesCategoryList());
        }
        lqw.orderByDesc(SuppliesManage::getCreateTime);
        if (StringUtils.isNotBlank(bo.getSuppliesName())) {
            lqw.and(wrapper -> wrapper.like(SuppliesManage::getSuppliesName, bo.getSuppliesName()).or().like(SuppliesManage::getSuppliesCode, bo.getSuppliesName()).or());
        }
        if (StringUtils.isNotBlank(categoryIds)) {
            lqw.eq(SuppliesManage::getSuppliesCategoryId, categoryIds);
        }
        return lqw;
    }

    /**
     * 新增耗材管理
     *
     * @param bo 耗材管理
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(SuppliesManageBo bo) {
        String categoryIds = null;
        String productLabel = null;
        if (bo.getSuppliesCategoryList() != null && !bo.getSuppliesCategoryList().isEmpty()) {
            categoryIds = String.join(",", bo.getSuppliesCategoryList());
        }
        bo.setSuppliesCategoryId(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);
        SuppliesManage add = MapstructUtils.convert(bo, SuppliesManage.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改耗材管理
     *
     * @param bo 耗材管理
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(SuppliesManageBo bo) {
        SuppliesManage update = MapstructUtils.convert(bo, SuppliesManage.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 批量修改
     *
     * @param manageBo 耗材管理
     * @return 是否修改成功
     */
    @Override
    public Boolean batchUpdateSuppliesManage(BatchSuppliesManageBo manageBo) {
        Integer result = 0;
        SuppliesManageVo suppliesManageVo = null;
        if (null != manageBo && !manageBo.getIds().isEmpty()) {
            for (Long id : manageBo.getIds()) {
                suppliesManageVo = this.queryById(id);
                if (null != suppliesManageVo) {
                    suppliesManageVo.setShelfLifeReminder(manageBo.getShelfLifeReminder());
                    suppliesManageVo.setLicenseExpiryReminder(manageBo.getLicenseExpiryReminder());
                    SuppliesManage suppliesManage = MapstructUtils.convert(suppliesManageVo, SuppliesManage.class);
                    result = baseMapper.updateById(suppliesManage);
                }
            }
        }
        return result > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(SuppliesManage 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());

        List<SuppliesCategory> categoryList = categoryMapper.selectList(Wrappers.lambdaQuery(SuppliesCategory.class).select(SuppliesCategory::getCategoryId, SuppliesCategory::getCategoryName));
        Map<String, String> categoryMap = categoryList.stream().collect(Collectors.toMap(k1 -> k1.getCategoryName(), k2 -> String.valueOf(k2.getCategoryId()), (k1, k2) -> k1));

        List<ProductSupplier> productSupplierList = supplierMapper.selectList(Wrappers.lambdaQuery(ProductSupplier.class).select(ProductSupplier::getId, ProductSupplier::getName));
        Map<String, String> productSupplierMap = productSupplierList.stream().collect(Collectors.toMap(k1 -> k1.getName(), k2 -> String.valueOf(k2.getId()), (k1, k2) -> k1));

        List<ProductManufacturer> productManufacturerList = manufacturerMapper.selectList(Wrappers.lambdaQuery(ProductManufacturer.class).select(ProductManufacturer::getId, ProductManufacturer::getName));
        Map<String, String> productManufacturerMap = productManufacturerList.stream().collect(Collectors.toMap(k1 -> k1.getName(), k2 -> String.valueOf(k2.getId()), (k1, k2) -> k1));

        List<SysDiseaseLabel> disLabelList = labelMapper.selectList(Wrappers.lambdaQuery(SysDiseaseLabel.class).select(SysDiseaseLabel::getLabelId, SysDiseaseLabel::getLabelName));
        Map<String, String> labelMap = disLabelList.stream().collect(Collectors.toMap(k1 -> k1.getLabelName(), k2 -> String.valueOf(k2.getLabelId()), (k1, k2) -> k1));

        List<SysDept> deptlList = deptMapper.selectList(Wrappers.lambdaQuery(SysDept.class).select(SysDept::getDeptId, SysDept::getDeptName));
        Map<String, String> deptMap = deptlList.stream().collect(Collectors.toMap(k1 -> k1.getDeptName(), k2 -> String.valueOf(k2.getDeptId()), (k1, k2) -> k1));

        List<SuppliesManage> suppliesManages = new ArrayList<>();
        StringBuilder builder = new StringBuilder();
        //根据excel中的值获取字典label
        Map<String, String> productQualificationMap = MapUtil.newHashMap(excelList.size());
        dictDataService.selectMapByType("product_qualification").getData().forEach((k, y) -> {
            productQualificationMap.put(y.getDictLabel(), k);
        });

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

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

        Map<String, String> putFlagMap = MapUtil.newHashMap(excelList.size());
        dictDataService.selectMapByType("put_flag").getData().forEach((k, y) -> {
            putFlagMap.put(y.getDictLabel(), k);
        });
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        excelList.forEach(v -> {
            if (MapUtil.isEmpty(v) || v.size() < 4) {
                builder.append(suppliesManages.size() + 4).append("、");
                return;
            }
            SuppliesManage suppliesManage = new SuppliesManage();
            suppliesManage.setSuppliesName(v.get(0));
            suppliesManage.setHospitalSystemCode(v.get(1));
            suppliesManage.setSuppliesCode(v.get(2));
            suppliesManage.setShelfLife(v.get(3));
            suppliesManage.setProductQualification(productQualificationMap.get(v.get(4)));
            StringBuilder categoryIds = new StringBuilder();
            StringBuilder labelIds = new StringBuilder();
            StringBuilder deptIds = new StringBuilder();

            List<String> suppliesNames = Arrays.stream(v.get(5).split("/")).map(String::trim).filter(StringUtils::isNotBlank).collect(Collectors.toList());
            List<String> categories = new ArrayList<>();
            for (String name : suppliesNames) {
                categories.add(categoryMap.get(name));
            }
            String result = String.join(",", categories); // 自动处理逗号
            categoryIds.append(result);
            suppliesManage.setSuppliesCategoryId(categoryIds.toString());

            suppliesManage.setShelfLifeReminder(v.get(6));
            suppliesManage.setPurchasePrice(new BigDecimal(v.get(7)));
            suppliesManage.setSuppliesUnit(productPackageUnitMap.get(v.get(8)));
            suppliesManage.setSellPrice(new BigDecimal(v.get(9)));
            suppliesManage.setSuppliesSpec(v.get(10));
            suppliesManage.setSuppliesSpecUnit(productSpecUnitMap.get(v.get(11)));

            String colVal = v.get(12);
            if (StrUtil.isNotBlank(colVal)) {
                suppliesManage.setBrand(colVal);

            }
            colVal = v.get(13);
            if (StrUtil.isNotBlank(colVal)) {
                List<String> labelNames = Arrays.stream(colVal.split(",")).map(String::trim).filter(StringUtils::isNotBlank).collect(Collectors.toList());
                List<String> dLabelNameList = new ArrayList<>();
                for (String name : labelNames) {
                    dLabelNameList.add(labelMap.get(name));
                }
                String label = String.join(",", dLabelNameList); // 自动处理逗号
                labelIds.append(label);
                suppliesManage.setProductLabel(labelIds.toString());
            }
            colVal = v.get(14);
            if (StrUtil.isNotBlank(colVal)) {
                List<String> deptNames = Arrays.stream(colVal.split(",")).map(String::trim).filter(StringUtils::isNotBlank).collect(Collectors.toList());
                List<String> deptNameList = new ArrayList<>();
                for (String name : deptNames) {
                    SysDeptVo deptVo = deptMapper.selectVoById(deptMap.get(name));
                    if (null != deptVo) {
                        if (deptVo.getParentId() > 0) {
                            deptNameList.add(deptVo.getParentId() + "," + deptVo.getDeptId());
                        } else {
                            deptNameList.add(deptVo.getDeptId().toString());
                        }
                    }
                }
                String deptId = String.join(";", deptNameList); // 自动处理逗号
                deptIds.append(deptId);
                suppliesManage.setApplicableDepartment(deptIds.toString());
            }

            colVal = v.get(15);
            if (StrUtil.isNotBlank(colVal)) {
                suppliesManage.setSupplier(productSupplierMap.get(colVal));
            }

            colVal = v.get(16);
            if (StrUtil.isNotBlank(colVal)) {
                try {
                    suppliesManage.setProductLicenseExpiry(sdf.parse(colVal));
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }
            colVal = v.get(17);
            if (StrUtil.isNotBlank(colVal)) {
                suppliesManage.setApprovalNumber(colVal);
            }
            colVal = v.get(18);
            if (StrUtil.isNotBlank(colVal)) {
                suppliesManage.setLicenseExpiryReminder(colVal);
            }
            colVal = v.get(19);
            if (StrUtil.isNotBlank(colVal)) {
                suppliesManage.setManufacturer(productManufacturerMap.get(colVal));
            }
            colVal = v.get(20);
            if (StrUtil.isNotBlank(colVal)) {
                suppliesManage.setPutFlag(putFlagMap.get("已" + colVal));
            }

            suppliesManages.add(suppliesManage);
        });

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

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