package com.ylx.web.controller.massage;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ylx.common.annotation.Log;
import com.ylx.common.core.controller.BaseController;
import com.ylx.common.core.domain.R;
import com.ylx.common.enums.BusinessType;
import com.ylx.common.exception.ServiceException;
import com.ylx.common.utils.StringUtils;
import com.ylx.massage.domain.Product;
import com.ylx.massage.domain.ProductCategory;
import com.ylx.massage.domain.dto.ProductCreateDTO;
import com.ylx.massage.domain.dto.ProductSpecSetupDTO;
import com.ylx.massage.domain.dto.ProductUpdateDTO;
import com.ylx.massage.domain.vo.CategoryTreeVO;
import com.ylx.massage.domain.vo.H5ProductVo;
import com.ylx.massage.domain.vo.ProductDetailsVo;
import com.ylx.massage.domain.vo.SpecComboVO;
import com.ylx.massage.service.ProductCategoryService;
import com.ylx.massage.service.ProductService;
import com.ylx.massage.service.ProductSkuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

/**
 * 商品管理(Product)表控制层
 *
 * @author ylx
 * @since 2026-03-26
 */
@Slf4j
@Api(tags = {"商品管理"})
@RestController
@RequestMapping("product")
public class ProductController extends BaseController {

    @Resource
    private ProductService productService;

    @Resource
    private ProductCategoryService productCategoryService;

    @Resource
    private ProductSkuService productSkuService;

    /**
     * 分页查询商品列表(PC端)
     *
     * @param page    分页对象
     * @param product 商品实体
     * @return R<Page < Product>> 所有数据
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ApiOperation("PC查询商品管理列表")
    public R<Page<Product>> selectAll(Page<Product> page, Product product) {
        try {
            LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(product.getCategoryId() != null, Product::getCategoryId, product.getCategoryId())
                    .like(StringUtils.isNotBlank(product.getName()), Product::getName, product.getName())
                    .like(StringUtils.isNotBlank(product.getProductNo()), Product::getProductNo, product.getProductNo())
                    .eq(product.getStatus() != null, Product::getStatus, product.getStatus())
                    .orderByDesc(Product::getCreateTime);
            Page<Product> page1 = this.productService.page(page, queryWrapper);
            //根据分类ID查询分类的名称
            List<Product> records = page1.getRecords();
            for (Product record : records) {
                ProductCategory productCategory = this.productCategoryService.getById(record.getCategoryId());
                record.setCategoryName(productCategory.getName());
            }
            return R.ok(page1);
        } catch (Exception e) {
            log.error("商品查询失败", e);
            throw new RuntimeException(e);
        }
    }


    /**
     * 分页查询商品列表(H5端)
     *
     * @param page      分页对象
     * @param product   商品实体
     * @param name      商品名称
     * @param sortField 排序字段（price:价格, sales:销量, comprehensive:综合排序）
     *                   综合排序规则：
     *                   1. 销量热度（50%）：近30天销量/平台总销量，min(1, ratio)
     *                   2. 新品系数（30%）：上架前7天=1.0，之后递减max(0, 1-(days-7)/23)
     *                   3. 积分性价比（20%）：积分值/商品价值
     * @param sortOrder 排序方式（asc:升序, desc:降序）
     * @return R<Page < H5ProductVo>> 所有数据
     */
    @RequestMapping(value = "/h5List", method = RequestMethod.GET)
    @ApiOperation("H5查询商品管理列表")
    public R<Page<H5ProductVo>> selectH5All(Page<H5ProductVo> page, Product product, @RequestParam(required = false) String name, @RequestParam(required = false) String sortField, @RequestParam(required = false) String sortOrder) {
        try {
            Page<H5ProductVo> pageResult = productService.selectH5Page(page, product, name, sortField, sortOrder);
            //根据分类ID查询分类的名称
            for (H5ProductVo record : pageResult.getRecords()) {
                ProductCategory productCategory = this.productCategoryService.getById(record.getCategoryId());
                if (productCategory != null) {
                    // 设置分类名称
                    record.setCategoryName(productCategory.getName());
                }
                //根据商品ID查询库存的最低价格
                record.setOriginalPrice(productSkuService.findMinPriceByProductId(record.getId()));
            }
            return R.ok(pageResult);
        } catch (Exception e) {
            log.error("商品查询失败", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过主键查询商品详情
     *
     * @param id 主键
     * @return R
     */
    @GetMapping("getById")
    @ApiOperation("通过主键查询商品详情")
    public R selectOne(@RequestParam Long id) {
        try {
            Product productServiceById = this.productService.getById(id);
            if(productServiceById == null){
                throw new ServiceException("商品不存在");
            }
            // 根据分类ID查询分类的名称
            ProductCategory productCategory = this.productCategoryService.getById(productServiceById.getCategoryId());
            productServiceById.setCategoryName(productCategory.getName());
            //根据商品编号查询商品的规格
            List<SpecComboVO> specComboVOList = this.productService.getSpecCombinations(productServiceById.getProductNo());
            ProductDetailsVo productDetailsVo = new ProductDetailsVo();
            BeanUtil.copyProperties(productServiceById, productDetailsVo);
            productDetailsVo.setSpecComboVOList(specComboVOList);
            return R.ok(productDetailsVo);
        } catch (Exception e) {
            log.error("商品查询失败", e);
            return R.fail("商品查询失败：" + e.getMessage());
        }
    }

    /**
     * 新增商品
     *
     * @param dto 新增商品请求DTO
     * @return R 新增结果
     */
    @PostMapping("create")
    @ApiOperation("新增商品")
    public R create(@Valid @RequestBody ProductCreateDTO dto) {
        try {
            Long productId = productService.createProduct(dto);
            return R.ok("商品ID：" + productId, "商品创建成功");
        } catch (Exception e) {
            log.error("商品创建失败", e);
            return R.fail("商品创建失败：" + e.getMessage());
        }
    }

    /**
     * 修改商品
     *
     * @param dto 商品实体对象
     * @return R 修改结果
     */
    @PostMapping("update")
    @ApiOperation("修改商品")
    public R update(@Valid @RequestBody ProductUpdateDTO dto) {
        try {
            productService.updateProduct(dto);
            return R.ok("商品修改成功");
        } catch (Exception e) {
            log.error("商品修改失败", e);
            return R.fail("商品修改失败：" + e.getMessage());
        }
    }

    /**
     * 删除商品
     *
     * @param idList 主键结合
     * @return R 删除结果
     */
    @PostMapping("delete")
    @ApiOperation("删除商品")
    public R delete(@RequestBody List<Long> idList) {
        return R.ok(this.productService.removeByIds(idList));
    }

    /**
     * 上下架商品
     *
     * @param id     商品ID
     * @param status 状态：1上架 0下架
     * @return R 操作结果
     */
    @PostMapping("updateStatus")
    @ApiOperation("上下架商品")
    public R updateStatus(@RequestBody Product productDto) {
        try {
            log.info("商品上下架请求：{}", JSON.toJSONString(productDto));
            Product product = new Product();
            product.setId(productDto.getId());
            product.setStatus(productDto.getStatus());
            return R.ok(this.productService.updateById(product));
        } catch (Exception e) {
            log.error("商品上下架失败", e);
            return R.fail("商品上下架失败：" + e.getMessage());
        }
    }


    /**
     * 生成商品编号
     * 规则：分类编码 + 当前日期(yyyyMMdd) + 序列号(3位)
     * 示例：AD20260327001
     *
     * @param categoryId 分类ID
     * @return R<String> 生成的商品编号
     */
    @GetMapping("generateProductNo")
    @ApiOperation("生成商品编号")
    public R<String> generateProductNo(@RequestParam("categoryId") Long categoryId) {
        try {
            String productNo = productService.generateProductNo(categoryId);
            return R.ok(productNo, "商品编号生成成功");
        } catch (Exception e) {
            log.error("商品编号生成失败", e);
            return R.fail("商品编号生成失败：" + e.getMessage());
        }
    }
}
