package com.erp.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.erp.product.dto.*;
import com.erp.product.entity.*;
import com.erp.product.exception.GoodsException;
import com.erp.product.repository.*;
import com.erp.product.service.GoodsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商品服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GoodsServiceImpl implements GoodsService {
    
    private final GoodsRepository goodsRepository;
    private final BrandRepository brandRepository;
    private final SupplierRepository supplierRepository;
    private final ComboItemRepository comboItemRepository;
    private final GoodsSupplierRepository goodsSupplierRepository;
    
    private static final String GOODS_CODE_PREFIX = "G";
    private static final DateTimeFormatter CODE_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
    
    @Override
    public GoodsListResponse listGoods(GoodsListRequest request) {
        // 构建查询条件
        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.isNull(Goods::getDeletedAt);
        
        // 关键词搜索（名称、编码、条形码）
        if (StringUtils.hasText(request.getKeyword())) {
            String keyword = "%" + request.getKeyword() + "%";
            queryWrapper.and(w -> w
                    .like(Goods::getName, keyword)
                    .or()
                    .like(Goods::getCode, keyword)
                    .or()
                    .like(Goods::getBarcode, keyword)
            );
        }
        
        // 类型筛选
        if (StringUtils.hasText(request.getType())) {
            queryWrapper.eq(Goods::getType, request.getType());
        }
        
        // 品牌筛选
        if (request.getBrandId() != null) {
            queryWrapper.eq(Goods::getBrandId, request.getBrandId());
        }
        
        // 按创建时间倒序
        queryWrapper.orderByDesc(Goods::getCreatedAt);
        
        // 分页查询
        int page = request.getPage() != null ? request.getPage() : 1;
        int limit = request.getLimit() != null ? request.getLimit() : 15;
        Page<Goods> pageResult = goodsRepository.selectPage(new Page<>(page, limit), queryWrapper);
        
        // 转换结果
        List<GoodsDTO> dtoList = pageResult.getRecords().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        
        // 构建响应
        GoodsListResponse response = new GoodsListResponse();
        response.setList(dtoList);
        response.setTotal(pageResult.getTotal());
        response.setCurrentPage(page);
        response.setLastPage((int) pageResult.getPages());
        
        return response;
    }
    
    @Override
    public List<GoodsDTO> listAllGoods(String type) {
        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.isNull(Goods::getDeletedAt)
                .select(Goods::getId, Goods::getName, Goods::getCode, 
                        Goods::getRetailPrice, Goods::getCostPrice, Goods::getType);
        
        if (StringUtils.hasText(type)) {
            queryWrapper.eq(Goods::getType, type);
        }
        
        List<Goods> goodsList = goodsRepository.selectList(queryWrapper);
        return goodsList.stream().map(this::convertToSimpleDTO).collect(Collectors.toList());
    }
    
    @Override
    public GoodsDTO getGoodsById(Long id) {
        Goods goods = goodsRepository.selectById(id);
        if (goods == null || goods.getDeletedAt() != null) {
            throw new GoodsException(404, "商品不存在");
        }
        return convertToDetailDTO(goods);
    }
    
    @Override
    @Transactional
    public Long createGoods(CreateGoodsRequest request) {
        // 生成或验证商品编码
        String code = request.getCode();
        if (!StringUtils.hasText(code)) {
            code = generateGoodsCode();
        } else {
            // 检查编码唯一性
            Goods existingGoods = goodsRepository.findByCode(code);
            if (existingGoods != null) {
                throw new GoodsException(400, "商品编码已存在");
            }
        }
        
        // 如果是组套商品，验证组合项
        if ("combo".equals(request.getType())) {
            validateComboItems(request.getComboItems());
        }
        
        // 创建商品
        Goods goods = new Goods();
        goods.setName(request.getName());
        goods.setCode(code);
        goods.setBarcode(request.getBarcode());
        goods.setCategory(request.getCategory());
        goods.setUnit(request.getUnit());
        goods.setWeight(request.getWeight() != null ? request.getWeight() : BigDecimal.ZERO);
        goods.setRetailPrice(request.getRetailPrice());
        goods.setCostPrice(request.getCostPrice());
        goods.setStockWarning(request.getStockWarning() != null ? request.getStockWarning() : 0);
        goods.setType(request.getType());
        goods.setCustomId(request.getCustomId());
        goods.setPackagingCost(request.getPackagingCost() != null ? request.getPackagingCost() : BigDecimal.ZERO);
        goods.setShippingPackagingCost(request.getShippingPackagingCost() != null ? request.getShippingPackagingCost() : BigDecimal.ZERO);
        goods.setVolume(request.getVolume() != null ? request.getVolume() : BigDecimal.ZERO);
        goods.setLength(request.getLength() != null ? request.getLength() : BigDecimal.ZERO);
        goods.setWidth(request.getWidth() != null ? request.getWidth() : BigDecimal.ZERO);
        goods.setHeight(request.getHeight() != null ? request.getHeight() : BigDecimal.ZERO);
        goods.setBrandId(request.getBrandId());
        goods.setBatchManagement(request.getBatchManagement() != null ? request.getBatchManagement() : false);
        
        goodsRepository.insert(goods);
        log.info("商品创建成功: id={}, code={}", goods.getId(), goods.getCode());
        
        // 关联供应商
        if (request.getSupplierIds() != null && !request.getSupplierIds().isEmpty()) {
            goodsSupplierRepository.deleteByGoodsId(goods.getId());
            goodsSupplierRepository.insertBatch(goods.getId(), request.getSupplierIds());
        }
        
        // 如果是组套商品，添加组合项
        if ("combo".equals(request.getType()) && request.getComboItems() != null) {
            for (CreateGoodsRequest.ComboItemRequest itemRequest : request.getComboItems()) {
                ComboItem comboItem = new ComboItem();
                comboItem.setComboGoodsId(goods.getId());
                comboItem.setGoodsId(itemRequest.getGoodsId());
                comboItem.setQuantity(itemRequest.getQuantity());
                comboItemRepository.insert(comboItem);
            }
        }
        
        return goods.getId();
    }
    
    @Override
    @Transactional
    public void updateGoods(Long id, UpdateGoodsRequest request) {
        Goods goods = goodsRepository.selectById(id);
        if (goods == null || goods.getDeletedAt() != null) {
            throw new GoodsException(404, "商品不存在");
        }
        
        // 如果更新了编码，检查唯一性
        if (StringUtils.hasText(request.getCode()) && !request.getCode().equals(goods.getCode())) {
            Goods existingGoods = goodsRepository.findByCodeExcludingId(request.getCode(), id);
            if (existingGoods != null) {
                throw new GoodsException(400, "商品编码已存在");
            }
        }
        
        // 如果是组套商品，验证组合项
        if ("combo".equals(request.getType())) {
            validateComboItems(request.getComboItems());
        }
        
        // 更新商品基本信息
        if (StringUtils.hasText(request.getName())) {
            goods.setName(request.getName());
        }
        if (StringUtils.hasText(request.getCode())) {
            goods.setCode(request.getCode());
        }
        if (request.getBarcode() != null) {
            goods.setBarcode(request.getBarcode());
        }
        if (StringUtils.hasText(request.getCategory())) {
            goods.setCategory(request.getCategory());
        }
        if (StringUtils.hasText(request.getUnit())) {
            goods.setUnit(request.getUnit());
        }
        if (request.getWeight() != null) {
            goods.setWeight(request.getWeight());
        }
        if (request.getRetailPrice() != null) {
            goods.setRetailPrice(request.getRetailPrice());
        }
        if (request.getCostPrice() != null) {
            goods.setCostPrice(request.getCostPrice());
        }
        if (request.getStockWarning() != null) {
            goods.setStockWarning(request.getStockWarning());
        }
        if (StringUtils.hasText(request.getType())) {
            goods.setType(request.getType());
        }
        if (request.getCustomId() != null) {
            goods.setCustomId(request.getCustomId());
        }
        if (request.getPackagingCost() != null) {
            goods.setPackagingCost(request.getPackagingCost());
        }
        if (request.getShippingPackagingCost() != null) {
            goods.setShippingPackagingCost(request.getShippingPackagingCost());
        }
        if (request.getVolume() != null) {
            goods.setVolume(request.getVolume());
        }
        if (request.getLength() != null) {
            goods.setLength(request.getLength());
        }
        if (request.getWidth() != null) {
            goods.setWidth(request.getWidth());
        }
        if (request.getHeight() != null) {
            goods.setHeight(request.getHeight());
        }
        if (request.getBrandId() != null) {
            goods.setBrandId(request.getBrandId());
        }
        if (request.getBatchManagement() != null) {
            goods.setBatchManagement(request.getBatchManagement());
        }
        
        goodsRepository.updateById(goods);
        log.info("商品更新成功: id={}", id);
        
        // 更新供应商关联
        if (request.getSupplierIds() != null) {
            goodsSupplierRepository.deleteByGoodsId(id);
            if (!request.getSupplierIds().isEmpty()) {
                goodsSupplierRepository.insertBatch(id, request.getSupplierIds());
            }
        }
        
        // 更新组套商品子项
        if ("combo".equals(request.getType()) && request.getComboItems() != null) {
            // 删除旧的组合项
            comboItemRepository.deleteByComboGoodsId(id);
            // 添加新的组合项
            for (UpdateGoodsRequest.ComboItemRequest itemRequest : request.getComboItems()) {
                ComboItem comboItem = new ComboItem();
                comboItem.setComboGoodsId(id);
                comboItem.setGoodsId(itemRequest.getGoodsId());
                comboItem.setQuantity(itemRequest.getQuantity());
                comboItemRepository.insert(comboItem);
            }
        } else if ("normal".equals(request.getType())) {
            // 如果是普通商品，删除所有组合项
            comboItemRepository.deleteByComboGoodsId(id);
        }
    }
    
    @Override
    @Transactional
    public void deleteGoods(Long id) {
        Goods goods = goodsRepository.selectById(id);
        if (goods == null || goods.getDeletedAt() != null) {
            throw new GoodsException(404, "商品不存在");
        }
        
        // 检查是否被组套商品引用
        if (isReferencedByCombo(id)) {
            throw new GoodsException(400, "该商品已被组合商品引用，无法删除");
        }
        
        // 逻辑删除
        goods.setDeletedAt(LocalDate.now().atStartOfDay());
        goodsRepository.updateById(goods);
        log.info("商品删除成功: id={}", id);
    }
    
    @Override
    public String generateGoodsCode() {
        String prefix = GOODS_CODE_PREFIX + LocalDate.now().format(CODE_DATE_FORMAT);
        String maxCode = goodsRepository.findMaxCodeWithPrefix(prefix + "%");
        
        int num = 1;
        if (maxCode != null && maxCode.length() >= prefix.length() + 4) {
            String numStr = maxCode.substring(prefix.length());
            num = Integer.parseInt(numStr) + 1;
        }
        
        return prefix + String.format("%04d", num);
    }
    
    @Override
    public boolean isReferencedByCombo(Long goodsId) {
        List<Long> comboGoodsIds = comboItemRepository.findComboGoodsIdsByGoodsId(goodsId);
        return comboGoodsIds != null && !comboGoodsIds.isEmpty();
    }
    
    // ==================== 私有方法 ====================
    
    /**
     * 验证组套商品子项
     */
    private void validateComboItems(List<?> comboItems) {
        if (comboItems == null || comboItems.isEmpty()) {
            throw new GoodsException(400, "组套商品至少需要包含一个子商品");
        }
    }
    
    /**
     * 转换商品为简单DTO（用于列表）
     */
    private GoodsDTO convertToSimpleDTO(Goods goods) {
        GoodsDTO dto = new GoodsDTO();
        dto.setId(goods.getId());
        dto.setName(goods.getName());
        dto.setCode(goods.getCode());
        dto.setType(goods.getType());
        dto.setTypeLabel(goods.getTypeLabel());
        dto.setRetailPrice(goods.getRetailPrice());
        dto.setCostPrice(goods.getCostPrice());
        return dto;
    }
    
    /**
     * 转换商品为DTO（用于列表展示）
     */
    private GoodsDTO convertToDTO(Goods goods) {
        GoodsDTO dto = new GoodsDTO();
        dto.setId(goods.getId());
        dto.setName(goods.getName());
        dto.setCode(goods.getCode());
        dto.setBarcode(goods.getBarcode());
        dto.setType(goods.getType());
        dto.setTypeLabel(goods.getTypeLabel());
        dto.setRetailPrice(goods.getRetailPrice());
        dto.setCostPrice(goods.getCostPrice());
        dto.setUnit(goods.getUnit());
        dto.setWeight(goods.getWeight());
        dto.setPackagingCost(goods.getPackagingCost());
        dto.setShippingPackagingCost(goods.getShippingPackagingCost());
        dto.setVolume(goods.getVolume());
        dto.setLength(goods.getLength());
        dto.setWidth(goods.getWidth());
        dto.setHeight(goods.getHeight());
        dto.setBatchManagement(goods.getBatchManagement());
        dto.setCreatedAt(goods.getCreatedAt());
        dto.setUpdatedAt(goods.getUpdatedAt());
        
        // 填充品牌信息
        if (goods.getBrandId() != null) {
            Brand brand = brandRepository.selectById(goods.getBrandId());
            if (brand != null) {
                GoodsDTO.BrandSimpleDTO brandDTO = new GoodsDTO.BrandSimpleDTO();
                brandDTO.setId(brand.getId());
                brandDTO.setName(brand.getName());
                dto.setBrand(brandDTO);
            }
        }
        
        // 填充供应商信息
        List<Long> supplierIds = goodsSupplierRepository.findSupplierIdsByGoodsId(goods.getId());
        if (supplierIds != null && !supplierIds.isEmpty()) {
            List<GoodsDTO.SupplierSimpleDTO> supplierDTOs = new ArrayList<>();
            for (Long supplierId : supplierIds) {
                Supplier supplier = supplierRepository.selectById(supplierId);
                if (supplier != null) {
                    GoodsDTO.SupplierSimpleDTO supplierDTO = new GoodsDTO.SupplierSimpleDTO();
                    supplierDTO.setId(supplier.getId());
                    supplierDTO.setName(supplier.getName());
                    supplierDTOs.add(supplierDTO);
                }
            }
            dto.setSuppliers(supplierDTOs);
        }
        
        return dto;
    }
    
    /**
     * 转换商品为详细DTO（用于详情展示）
     */
    private GoodsDTO convertToDetailDTO(Goods goods) {
        GoodsDTO dto = convertToDTO(goods);
        
        // 填充更多详情字段
        dto.setCategory(goods.getCategory());
        dto.setStockWarning(goods.getStockWarning());
        dto.setCustomId(goods.getCustomId());
        
        // 填充组套子项
        if (goods.isCombo()) {
            List<ComboItem> comboItems = comboItemRepository.findByComboGoodsId(goods.getId());
            if (comboItems != null && !comboItems.isEmpty()) {
                List<GoodsDTO.ComboItemDTO> comboItemDTOs = new ArrayList<>();
                for (ComboItem item : comboItems) {
                    Goods childGoods = goodsRepository.selectById(item.getGoodsId());
                    if (childGoods != null) {
                        GoodsDTO.ComboItemDTO comboItemDTO = new GoodsDTO.ComboItemDTO();
                        comboItemDTO.setGoodsId(item.getGoodsId());
                        comboItemDTO.setGoodsName(childGoods.getName());
                        comboItemDTO.setGoodsCode(childGoods.getCode());
                        comboItemDTO.setQuantity(item.getQuantity());
                        comboItemDTOs.add(comboItemDTO);
                    }
                }
                dto.setComboItems(comboItemDTOs);
            }
        }
        
        return dto;
    }
}
