package com.yami.shop.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.dto.ShopCategoryExcelDTO;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.CategoryProductDTO;
import com.yami.shop.bean.vo.ListCategoryForUserVO;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.util.R;
import com.yami.shop.dao.*;
import com.yami.shop.service.CategoryProdService;
import com.yami.shop.service.IShopCategoryService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 门店前台类目服务实现类
 *
 * @author YourName
 * @since 2025-09-XX
 */
@Slf4j
@Service
@AllArgsConstructor
public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, ShopCategory> implements IShopCategoryService {

    private final ShopCategoryMapper shopCategoryMapper;
    private final ShopCategoryLogMapper shopCategoryLogMapper;

    private final FrontCategoryMapper frontCategoryMapper;
    private final CategoryProdMapper categoryProdMapper;

    private final ShopDetailMapper shopDetailMapper;
    private final LabelMapper labelMapper;


    @Override
    public List<ShopCategory> treeShopCategory(Long shopId, String name) {
        // 获取所有未删除的前台类目
        List<ShopCategory> shopCategories = shopCategoryMapper.selectListAll(shopId, name);
//        // 构建树形结构
//        return shopCategories; // 假设根节点的parentCode为"0"
////        return buildCategoryTree(shopCategories, "0"); // 假设根节点的parentCode为"0"
//    }
//
//
//
//    @Override
//    public List<ShopCategory> listCategoryForUser(Long shopId) {
//        List<ShopCategory> shopCategories = shopCategoryMapper.selectList(new LambdaQueryWrapper<ShopCategory>()
//                .eq(ShopCategory::getShopId, shopId)
//                .eq(ShopCategory::getIsDelete, Boolean.FALSE)
//                .orderByAsc(ShopCategory::getNum));
//        if (CollectionUtil.isEmpty(shopCategories)) {
//            return Collections.emptyList();
//        }

        Map<Long, List<ShopCategory>> parentMap = shopCategories.stream()
                .collect(Collectors.groupingBy(ShopCategory::getPid));

        // 初始层级为一级分类（grade = 1）
        return buildCategoryTree(parentMap.getOrDefault(0L, Collections.emptyList()), parentMap, 1);
    }
    private List<ShopCategory> buildCategoryTree(List<ShopCategory> categories, Map<Long, List<ShopCategory>> parentMap, int currentLevel) {
        if (CollectionUtil.isEmpty(categories)) return Collections.emptyList();
        return categories.stream()
                .map(category -> {
                    // 直接使用ShopCategory而不是ListCategoryForUserVO
                    ShopCategory shopCategory = new ShopCategory();
                    shopCategory.setId(category.getId());
                    shopCategory.setName(category.getName());
                    shopCategory.setNum(category.getNum());
                    shopCategory.setPid(category.getPid());
                    shopCategory.setIcon(category.getIcon());
                    shopCategory.setLevel(currentLevel);

                    // 判断是否为二级或三级分类，并设置level字段（原productBeBound）
                    int level = 1;
                    if (currentLevel == 2 || currentLevel == 3) {
                        // 三级分类直接绑定商品
                        if (currentLevel == 3) {
                            level = 2;
                        }
                        // 二级分类若无子分类（三级分类），则允许绑定商品
                        else if (currentLevel == 2) {
                            List<ShopCategory> children = parentMap.getOrDefault(category.getId(), Collections.emptyList());
                            level = children.isEmpty() ? 2 : 1;
                        }
                    }
                    shopCategory.setLevel(level);

                    // 递归构建子分类树，层级 +1
                    List<ShopCategory> children = parentMap.getOrDefault(category.getId(), Collections.emptyList());

                    children.sort(Comparator.comparingInt(ShopCategory::getNum));

                    shopCategory.setChildren(buildCategoryTree(children, parentMap, currentLevel + 1));

                    return shopCategory;
                })
                .collect(Collectors.toList());
    }

    /**
     * 构建类目树形结构
     *
     * @param categories 所有类目列表
     * @param parentCode 父级编码
     * @return 树形结构的类目列表
     */
    private List<ShopCategory> buildCategoryTree(List<ShopCategory> categories, String parentCode) {
        List<ShopCategory> tree = new ArrayList<>();
        for (ShopCategory category : categories) {
            // 查找指定parentCode的子类目
            if (parentCode.equals(category.getParentCode())) {
                // 递归设置子类目
                List<ShopCategory> children = buildCategoryTree(categories, category.getCode());
                category.setChildren(children);
                tree.add(category);
            }
        }

        return tree;
    }


    @Override
    public void exportTemplate(HttpServletResponse response) throws Exception {
        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("门店前台类目导入模板", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        // 创建示例数据
        List<ShopCategoryExcelDTO> templateData = new ArrayList<>();
        // 使用EasyExcel导出模板
        EasyExcel.write(response.getOutputStream(), ShopCategoryExcelDTO.class)
                .sheet("店内分类导入模板")
                .doWrite(templateData);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importCategory(MultipartFile file, Long userId) {
        try {
            // 检查文件是否为空
            if (file == null || file.isEmpty()) {
                throw new GlobalException("上传文件不能为空");
            }
            // 检查文件格式
            String fileName = file.getOriginalFilename();
            if (fileName == null || (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx"))) {
                throw new GlobalException("文件格式不正确，请上传Excel文件(.xls或.xlsx)");
            }
            // 解析Excel文件
            List<ShopCategoryExcelDTO> shopCategories = parseExcelFile(file);

            // 批量保存数据
            if (!shopCategories.isEmpty()) {
                Date date = new Date();
                String code = generateUniqueCode();
                for (int i = 0; i < shopCategories.size(); i++) {
                    ShopCategoryExcelDTO category = shopCategories.get(i);


                    ShopCategoryLog shopCategoryLog = new ShopCategoryLog();
                    ShopDetail shopDetail = shopDetailMapper.selectByHbStationId(category.getHbShopId());
                    shopCategoryLog.setShopId(shopDetail.getShopId());
                    shopCategoryLog.setHbShopId(category.getHbShopId());
                    shopCategoryLog.setName(category.getName());
                    shopCategoryLog.setSubName(category.getSubName());
                    shopCategoryLog.setSubSubName(category.getSubSubName());
                    shopCategoryLog.setIsFail(true);
                    shopCategoryLog.setTaskCode(code);
                    shopCategoryLog.setTaskName("导入前台类目");
                    // 设置操作人 获取当前操作人信息
                    shopCategoryLog.setCreateBy(userId);
                    shopCategoryLog.setCreateTime(date);
                    shopCategoryLog.setUpdateTime(date);

                    try {
                        // 检查数据有效性 及 添加
                        validateShopCategories(category, i, code);
                    } catch (Exception e) {
                        shopCategoryLog.setReason(e.getMessage());
                        shopCategoryLog.setIsFail(false);
                    }
                    shopCategoryLogMapper.insert(shopCategoryLog);
                }
            }
        } catch (Exception e) {
            log.error("导入门店前台类目失败：", e);
            throw new GlobalException("导入失败：" + e.getMessage());
        }
    }

    @Override
    public IPage<Category> listByParentIdAndShopId(Long parentId, Long shopId, Integer current, Integer size) {
        IPage<ShopCategory> page = page(new Page<>(current, size), new LambdaQueryWrapper<ShopCategory>()
                .eq(ShopCategory::getShopId, shopId)
                .eq(ShopCategory::getPid, parentId)
                .eq(ShopCategory::getIsDelete, 0)
                .orderByAsc(ShopCategory::getNum));
        Page res = new Page();
        BeanUtils.copyProperties(page, res);
        List<Category> categories = page.getRecords().stream().map((sc) -> {
            Category category = new Category();

            Integer count = shopCategoryMapper.selectAppCount(sc.getShopId(), sc.getCode());
            if (count == 0){
                category.setHasSecond(false);
            }else {
                category.setHasSecond(true);
            }

            category.setCategoryId(sc.getId());
            category.setShopId(sc.getShopId());
            category.setParentId(sc.getPid());
            category.setCategoryName(sc.getName());
            category.setIcon(sc.getIcon());
            category.setPic(sc.getPic());
            category.setSeq(sc.getNum());
            category.setGrade(sc.getLevel());
            if (ObjectUtils.isNotEmpty(sc.getLabel())) {
                Label label = labelMapper.selectOne(new LambdaQueryWrapper<Label>()
                        .eq(Label::getId, sc.getLabel())
                        .eq(Label::getIsDelete, 0)
                        .eq(Label::getType, 0));
                if (null != label && null != label.getName()) {
                    category.setLabel(label.getName());
                }
            }
            return category;
        }).collect(Collectors.toList());
        res.setRecords(categories);
        return res;
    }

    @Override
    public void delete(Long id) {
        // 检查是否存在
        ShopCategory dbShopCategory = shopCategoryMapper.selectById(id);
        if (dbShopCategory == null) {
           new GlobalException("门店前台类目不存在");
        }

        // 逻辑删除
        Integer integer = categoryProdMapper.selectCount(new LambdaQueryWrapper<CategoryProd>()
                .eq(CategoryProd::getCategoryId, id)
                .eq(CategoryProd::getIsDelete, 0));
        if (integer > 0) {
            new GlobalException("门店前台类目下有商品，请先删除商品");
        }

        ShopCategory shopCategory = new ShopCategory();
        shopCategory.setId(id);
        shopCategory.setIsDelete(1);
        shopCategoryMapper.updateById(shopCategory);
    }


    /**
     * 添加对应的二级和三级类目
     *
     * @param frontCategory 前台类目模板
     * @param hbShopId      海报
     * @param shopId        门店ID
     */
    private ShopCategory addShopCategory(FrontCategory frontCategory, String hbShopId, Long shopId, Long id) {
        ShopCategory shopCategory = new ShopCategory();
        shopCategory.setPid(id);
        shopCategory.setName(frontCategory.getName());
        shopCategory.setCode(frontCategory.getCode());
        shopCategory.setParentCode(frontCategory.getParentCode());
        shopCategory.setParentName(frontCategory.getName());
        shopCategory.setLevel(frontCategory.getLevel());
        shopCategory.setNum(frontCategory.getNum());
        shopCategory.setIsDelete(0);
        shopCategory.setOperateUser("admin");
        shopCategory.setIsLeaves(1);
        shopCategory.setIcon("https://zswl-shop.oss-cn-chengdu.aliyuncs.com/2025/09/eae85a85269045f6ba484bd1edf5f975.jpg");

        shopCategory.setHbShopId(hbShopId);
        shopCategory.setShopId(shopId);
        log.info("添加门店前台类目：{}", shopCategory);
        this.save(shopCategory);
        List<FrontCategory> frontCategoryList = frontCategoryMapper.selectList(new LambdaQueryWrapper<FrontCategory>()
                .eq(FrontCategory::getParentCode, frontCategory.getCode()));
        for (FrontCategory frontCategory1 : frontCategoryList) {
            addShopCategory(frontCategory1, hbShopId, shopId, shopCategory.getId());
        }
        return shopCategory;
    }

    /**
     * 解析Excel文件
     *
     * @param file Excel文件
     * @return 门店前台类目列表
     */
    private List<ShopCategoryExcelDTO> parseExcelFile(MultipartFile file) throws Exception {

        List<ShopCategoryExcelDTO> excelDataList = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream()) {
            // 使用EasyExcel读取Excel文件
            EasyExcel.read(inputStream, ShopCategoryExcelDTO.class, new AnalysisEventListener<ShopCategoryExcelDTO>() {
                @Override
                public void invoke(ShopCategoryExcelDTO data, AnalysisContext context) {
                    // 处理每一行数据
                    excelDataList.add(data);
                }
                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    // 所有数据解析完成后的操作
                }
            }).sheet().doRead();
        }

        return excelDataList;
    }


    /**
     * 生成唯一编码
     *
     * @return 唯一编码
     */
    private synchronized String generateUniqueCode() {
        // 使用时间年月日+四位随机数生成唯一编码
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String date = sdf.format(new Date());
        String random = String.valueOf((int) (Math.random() * 10000));
        return "F" + date + random;
    }

    /**
     * 验证门店前台类目数据有效性
     *
     * @param category 门店前台类目
     */
    private void validateShopCategories(ShopCategoryExcelDTO category, int i, String code) {

            // 检查必填字段
            if (ObjectUtils.isEmpty(category.getHbShopId())) {
                throw new GlobalException("第" + (i + 1) + "行：门店ID不能为空");
            }
            ShopDetail shopDetail = shopDetailMapper.selectByHbStationId(category.getHbShopId());
            if (ObjectUtils.isEmpty(shopDetail)) {
                throw new GlobalException("第" + (i + 1) + "行：门店不存在");
            }
            if (ObjectUtils.isEmpty(category.getSubSubName())) {
                throw new GlobalException("第" + (i + 1) + "行：类目名称不能为空");
            }
            // 检查类目名称长度
            if (category.getSubSubName().length() > 255) {
                throw new GlobalException("第" + (i + 1) + "行：类目名称长度不能超过255个字符");
            }

            //查看前台类目模板里面是否存在二级类目
            FrontCategory frontCategory = frontCategoryMapper.selectOne(new LambdaQueryWrapper<FrontCategory>()
                    .eq(FrontCategory::getParentName, category.getName())
                    .eq(FrontCategory::getName, category.getSubName())
                    .eq(FrontCategory::getIsDelete, 0));


            if (frontCategory == null) {
                throw new GlobalException("第" + (i + 1) + "行：一二级对应类目不存在");
            }


            ShopCategory shopCategoryByCode1 = shopCategoryMapper.selectOne(new LambdaQueryWrapper<ShopCategory>()
                    .eq(ShopCategory::getCode, frontCategory.getCode())
                    .eq(ShopCategory::getIsDelete, 0)
                    .eq(ShopCategory::getShopId, shopDetail.getShopId()));
            if (shopCategoryByCode1 == null) {
                shopCategoryByCode1 = addShopCategory(frontCategory, shopDetail.getHbStationId(), shopDetail.getShopId(), shopCategoryByCode1.getId());
            }

        ShopCategory shopCategory1 = shopCategoryMapper.selectOne(new LambdaQueryWrapper<ShopCategory>()
                .eq(ShopCategory::getParentCode, frontCategory.getCode())
                .eq(ShopCategory::getIsDelete, 0)
                .eq(ShopCategory::getShopId, shopDetail.getShopId())
                .eq(ShopCategory::getName, category.getSubSubName()));
            if (shopCategory1 != null){
                throw new GlobalException("第" + (i + 1) + "行：三级类目已经存在");
            }

        ShopCategory shopCategory = new ShopCategory();
            shopCategory.setPid(shopCategoryByCode1.getId());
            shopCategory.setName(category.getSubSubName());
            shopCategory.setCode(code);
            shopCategory.setParentCode(shopCategoryByCode1.getCode());
            shopCategory.setParentName(shopCategoryByCode1.getName());
            shopCategory.setLevel(3);
            shopCategory.setNum(0);
            shopCategory.setIsDelete(0);
            shopCategory.setOperateUser("admin");
            shopCategory.setIsLeaves(1);
            shopCategory.setIcon("https://zswl-shop.oss-cn-chengdu.aliyuncs.com/2025/09/eae85a85269045f6ba484bd1edf5f975.jpg");

            shopCategory.setHbShopId(shopDetail.getHbStationId());
            shopCategory.setShopId(shopDetail.getShopId());
            log.info("添加门店前台类目：{}", shopCategory);
            this.save(shopCategory);

    }

}
