package com.ylx.massage.service.impl;

import cn.hutool.core.util.StrUtil;
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.ylx.massage.domain.Product;
import com.ylx.massage.domain.dto.OptionDTO;
import com.ylx.massage.domain.dto.ServiceOptionDTO;
import com.ylx.massage.domain.vo.ProductOptionVO;
import com.ylx.massage.domain.vo.ProductServiceOptionVO;
import com.ylx.massage.enums.ProductTypeEnum;
import com.ylx.massage.service.ProductSelectionService;
import com.ylx.massage.service.ProductService;
import com.ylx.project.domain.Project;
import com.ylx.project.service.ProjectService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProductSelectionServiceImpl implements ProductSelectionService {

    @Resource
    private ProjectService projectService;

    @Resource
    private ProductService productService; // 积分商品服务

    @Override
    public Page<ProductOptionVO> optionsPage(OptionDTO dto) {
        Page page = new Page(dto.getCurrent(), dto.getSize());
        Integer productType = dto.getProductType();

        // 1. 只查积分商品 (Type = 1)
        if (productType != null && productType.equals(ProductTypeEnum.INTEGRAL_GOODS.getCode())) {
            return queryIntegralProducts(page, dto);
        }

        // 2. 只查项目/服务商品 (Type = 0)
        if (productType != null && productType.equals(ProductTypeEnum.MASSAGE_SERVICE.getCode())) {
            return queryProjectProducts(page, dto);
        }

        // 3. 查询全部 (Type = null)
        return queryAllProductsUnion(page, dto);
    }

    @Override
    public Page<ProductServiceOptionVO> serviceOptionsPage(ServiceOptionDTO dto) {
        Page<ProductServiceOptionVO> resultPage = projectService.selectServiceOptionsPage(new Page(dto.getCurrent(), dto.getSize()), dto);
        return resultPage;
    }

    /**
     * 查询积分商品
     */
    private Page<ProductOptionVO> queryIntegralProducts(Page page, OptionDTO dto) {
        // 构建查询条件
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getStatus, 1) // 假设 1 是上架
                .eq(Product::getDeleted, 0); // 假设 0 是未删除
        if (StrUtil.isNotEmpty(dto.getTitle())) {
            wrapper.like(Product::getName, dto.getTitle());
        }

        // 执行分页查询
        Page<Product> productPage = productService.page(page, wrapper);

        // 转换 VO
        return convertToVOPage(productPage, p -> {
            ProductOptionVO vo = new ProductOptionVO();
            vo.setId(String.valueOf(p.getId())); // Long 转 String
            vo.setTitle(p.getName());
            vo.setProductType(1); // 设置商品类型
            return vo;
        });
    }

    /**
     * 查询项目商品
     */
    private Page<ProductOptionVO> queryProjectProducts(Page page, OptionDTO dto) {
        // 构建查询条件
        LambdaQueryWrapper<Project> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Project::getIsDelete, 0);
        if (StrUtil.isNotEmpty(dto.getTitle())) {
            wrapper.like(Project::getTitle, dto.getTitle());
        }
        // 执行分页查询
        Page<Project> xiangmuPage = this.projectService.page(page, wrapper);

        // 转换 VO
        return convertToVOPage(xiangmuPage, x -> {
            ProductOptionVO vo = new ProductOptionVO();
            vo.setId(x.getId().toString()); // String 直接赋值
            vo.setTitle(x.getTitle());
            vo.setProductType(0); // 设置商品类型
            return vo;
        });
    }

    /**
     * 查询全部 (合并分页逻辑)
     * 核心逻辑：
     * 1. 分别查询两张表的所有符合条件的数据（全量）。
     * 2. 在内存中合并为一个总列表。
     * 3. 获取总列表的大小作为 total。
     * 4. 根据分页参数截取当前页的数据。
     */
    private Page<ProductOptionVO> queryAllProductsUnion(Page page, OptionDTO dto) {
        // 调用自定义 SQL
        IPage<ProductOptionVO> resultPage = this.projectService.selectOptionUnionPage(page, dto);

        // 将 IPage 转为具体的 Page 实现类返回（如果需要）
        Page<ProductOptionVO> returnPage = new Page<>(page.getCurrent(), page.getSize());
        returnPage.setRecords(resultPage.getRecords());
        returnPage.setTotal(resultPage.getTotal());
        returnPage.setPages(resultPage.getPages());
        return returnPage;
    }

    /**
     * 通用的 MyBatis-Plus Page 转 VO Page 方法
     */
    private <T, R> Page<R> convertToVOPage(Page<T> sourcePage, java.util.function.Function<T, R> converter) {
        Page<R> voPage = new Page<>(sourcePage.getCurrent(), sourcePage.getSize());
        voPage.setTotal(sourcePage.getTotal());
        voPage.setPages(sourcePage.getPages());

        List<R> records = sourcePage.getRecords().stream()
                .map(converter)
                .collect(Collectors.toList());
        voPage.setRecords(records);

        return voPage;
    }
}