package com.ruoyi.web.sales.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.web.base.domain.BaseEmployee;
import com.ruoyi.web.base.domain.BaseMaterial;
import com.ruoyi.web.base.service.IBaseEmployeeService;
import com.ruoyi.web.base.service.IBaseMaterialService;
import com.ruoyi.web.sales.domain.*;
import com.ruoyi.web.sales.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.ruoyi.common.core.domain.AjaxResult.success;
import static com.ruoyi.common.utils.SecurityUtils.getUsername;

@RestController
@Api(tags = "销售退回单")
@RequestMapping("/sales-return")
public class SalesReturnController {

    @Autowired
    private ISalesReturnService salesReturnService;
    @Autowired
    private ISalesReturnGoodsService salesReturnGoodsService;
    @Autowired
    private ISalesDeliveryService salesDeliveryService;
    @Autowired
    private ISalesDeliveryGoodsService salesDeliveryGoodsService;
    @Autowired
    private IBaseCustomerService customerService;
    @Autowired
    private IBaseEmployeeService baseEmployeeService;
    @Autowired
    private IBaseMaterialService baseMaterialService;
    @Autowired
    private TokenService tokenService;

    @ApiOperation("销售退回单新增")
    @PostMapping("/add")
    @Transactional
    public AjaxResult add(@RequestBody SalesReturn salesReturn, HttpServletRequest request) throws Exception {
        String orgId = tokenService.getLoginOrgId(request);
        fillByDeliveryNumIfNeeded(salesReturn, orgId, true);
        validateBeforeSave(salesReturn, orgId, true);
        fillCustomerInfo(salesReturn, orgId);
        recalcGoodsAmountAndTotal(salesReturn);
        salesReturn.setOrgId(orgId);
        salesReturn.setDelFlag("0");
        salesReturn.setAuditStatus(1);
        if (salesReturn.getOffsetStatus() == null) {
            salesReturn.setOffsetStatus(0);
        }
        String username = getUsername();
        salesReturn.setId(null);
        salesReturn.setCreateBy(username);
        salesReturn.setCreateTime(new Date());
        salesReturn.setUpdateBy(null);
        salesReturn.setUpdateTime(null);
        salesReturnService.save(salesReturn);
        saveGoods(salesReturn, orgId, username);
        return success();
    }

    @ApiOperation("销售退回单修改")
    @PostMapping("/edit")
    @Transactional
    public AjaxResult edit(@RequestBody SalesReturn salesReturn, HttpServletRequest request) throws Exception {
        if (salesReturn.getId() == null) {
            throw new Exception("id不能为空");
        }
        SalesReturn old = salesReturnService.getById(salesReturn.getId());
        if (old == null || !"0".equals(old.getDelFlag())) {
            throw new Exception("销售退回单不存在");
        }
        if (old.getAuditStatus() != null && old.getAuditStatus() == 1) {
            throw new Exception("已审核的销售退回单不能修改，请先反审核");
        }
        if (old.getOffsetStatus() != null && old.getOffsetStatus() == 1) {
            throw new Exception("已冲销的销售退回单不能修改");
        }
        String orgId = tokenService.getLoginOrgId(request);
        fillByDeliveryNumIfNeeded(salesReturn, orgId, false);
        validateBeforeSave(salesReturn, orgId, false);
        fillCustomerInfo(salesReturn, orgId);
        recalcGoodsAmountAndTotal(salesReturn);
        salesReturn.setOrgId(orgId);
        salesReturn.setAuditStatus(1);
        salesReturn.setOffsetStatus(old.getOffsetStatus());
        String username = getUsername();
        salesReturn.setCreateBy(old.getCreateBy());
        salesReturn.setCreateTime(old.getCreateTime());
        salesReturn.setUpdateBy(username);
        salesReturn.setUpdateTime(new Date());
        salesReturnService.updateById(salesReturn);
        String oldNum = StringUtils.isNotBlank(old.getReturnNum()) ? old.getReturnNum().trim() : null;
        deleteGoodsByReturnNum(orgId, oldNum);
        saveGoods(salesReturn, orgId, username);
        return success();
    }

    @ApiOperation("销售退回单删除")
    @PostMapping("/delete")
    public AjaxResult delete(@RequestBody Map<String, String> params) throws Exception {
        String ids = params.get("ids");
        for (String id : ids.split(",")) {
            SalesReturn salesReturn = salesReturnService.getById(id);
            if (salesReturn == null || !"0".equals(salesReturn.getDelFlag())) {
                continue;
            }
            if (salesReturn.getAuditStatus() != null && salesReturn.getAuditStatus() == 1) {
                throw new Exception("已审核的销售退回单不能删除，请先反审核");
            }
            if (salesReturn.getOffsetStatus() != null && salesReturn.getOffsetStatus() == 1) {
                throw new Exception("已冲销的销售退回单不能删除");
            }
            deleteGoodsByReturnNum(salesReturn.getOrgId(), salesReturn.getReturnNum());
            SalesReturn up = new SalesReturn();
            up.setId(Integer.valueOf(id));
            up.setDelFlag("2");
            up.setUpdateBy(getUsername());
            up.setUpdateTime(new Date());
            salesReturnService.updateById(up);
        }
        return success();
    }

    @ApiOperation("销售退回单详情")
    @PostMapping("/listById")
    public AjaxResult listById(@ApiParam("详情参数: id") @RequestBody Map<String, String> params, HttpServletRequest request) {
        SalesReturn salesReturn = salesReturnService.getById(params.get("id"));
        if (salesReturn == null) {
            return success(null);
        }
        String orgId = tokenService.getLoginOrgId(request);
        List<SalesReturnGoods> goods = salesReturnGoodsService.list(new QueryWrapper<SalesReturnGoods>()
                .eq("org_id", orgId)
                .eq("return_num", salesReturn.getReturnNum())
                .eq("del_flag", "0"));
        enrichGoodsDisplay(goods, orgId);
        enrichSalesReturnDisplay(salesReturn, orgId);
        salesReturn.setGoods(goods);
        return success(salesReturn);
    }

    @ApiOperation("销售退回单分页")
    @GetMapping("/page")
    public AjaxResult page(@RequestParam("pageNum") Integer pageNum,
                           @RequestParam("pageSize") Integer pageSize,
                           SalesReturn query,
                           HttpServletRequest request) {
        String orgId = tokenService.getLoginOrgId(request);
        QueryWrapper<SalesReturn> wrapper = buildWrapper(query, orgId);
        Page<SalesReturn> page = salesReturnService.page(new Page<SalesReturn>(pageNum, pageSize), wrapper);
        for (SalesReturn row : page.getRecords()) {
            enrichSalesReturnDisplay(row, orgId);
        }
        return success(page);
    }

    @ApiOperation("销售退回单列表")
    @PostMapping("/list")
    public AjaxResult list(@RequestBody SalesReturn query, HttpServletRequest request) {
        String orgId = tokenService.getLoginOrgId(request);
        List<SalesReturn> list = salesReturnService.list(buildWrapper(query, orgId));
        for (SalesReturn row : list) {
            enrichSalesReturnDisplay(row, orgId);
        }
        attachGoodsForListRows(list, orgId);
        return success(list);
    }

    @ApiOperation("销售退回单导出")
    @PostMapping("/export")
    public void export(HttpServletResponse response, SalesReturn query, HttpServletRequest request) {
        String orgId = tokenService.getLoginOrgId(request);
        List<SalesReturn> list = salesReturnService.list(buildWrapper(query, orgId));
        for (SalesReturn row : list) {
            enrichSalesReturnDisplay(row, orgId);
        }
        ExcelUtil<SalesReturn> util = new ExcelUtil<SalesReturn>(SalesReturn.class);
        util.exportExcel(response, list, "销售退回单");
    }

    @ApiOperation("销售退回单审核")
    @PostMapping("/audit")
    public AjaxResult audit(@RequestBody Map<String, String> params) throws Exception {
        SalesReturn salesReturn = getActiveById(params.get("id"));
        salesReturn.setAuditStatus(1);
        salesReturn.setUpdateBy(getUsername());
        salesReturn.setUpdateTime(new Date());
        return success(salesReturnService.updateById(salesReturn));
    }

    @ApiOperation("销售退回单反审核")
    @PostMapping("/unaudit")
    public AjaxResult unaudit(@RequestBody Map<String, String> params) throws Exception {
        SalesReturn salesReturn = getActiveById(params.get("id"));
        if (salesReturn.getOffsetStatus() != null && salesReturn.getOffsetStatus() == 1) {
            throw new Exception("已做冲销的销售退回单不可反审核");
        }
        salesReturn.setAuditStatus(0);
        salesReturn.setUpdateBy(getUsername());
        salesReturn.setUpdateTime(new Date());
        return success(salesReturnService.updateById(salesReturn));
    }

    @ApiOperation("销售退回单打印数据")
    @PostMapping("/print")
    public AjaxResult print(@RequestBody Map<String, String> params, HttpServletRequest request) throws Exception {
        SalesReturn salesReturn = getActiveById(params.get("id"));
        String orgId = tokenService.getLoginOrgId(request);
        List<SalesReturnGoods> goods = salesReturnGoodsService.list(new QueryWrapper<SalesReturnGoods>()
                .eq("org_id", orgId)
                .eq("return_num", salesReturn.getReturnNum())
                .eq("del_flag", "0"));
        enrichGoodsDisplay(goods, orgId);
        enrichSalesReturnDisplay(salesReturn, orgId);
        salesReturn.setGoods(goods);
        return success(salesReturn);
    }

    @ApiOperation("获取新增销售退回单页面数据")
    @PostMapping("/getAddPageData")
    public AjaxResult getAddPageData(HttpServletRequest request) throws Exception {
        String orgId = tokenService.getLoginOrgId(request);
        String tomorrow = LocalDate.now().plusDays(1).format(DateTimeFormatter.ISO_LOCAL_DATE);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("documentDate", tomorrow);
        data.put("returnNum", generateSalesReturnNum(orgId));
        return success(data);
    }

    @ApiOperation("按销售出库单编号回填退回单")
    @PostMapping("/fillByDeliveryNum")
    public AjaxResult fillByDeliveryNum(@RequestBody Map<String, String> params, HttpServletRequest request) throws Exception {
        String deliveryNum = params.get("deliveryNum");
        if (StringUtils.isBlank(deliveryNum)) {
            throw new Exception("销售出库单编号不能为空");
        }
        String orgId = tokenService.getLoginOrgId(request);
        SalesReturn salesReturn = new SalesReturn();
        salesReturn.setDeliveryNum(deliveryNum.trim());
        salesReturn.setGoods(new ArrayList<SalesReturnGoods>());
        fillByDeliveryNumIfNeeded(salesReturn, orgId, true);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("deliveryNum", salesReturn.getDeliveryNum());
        data.put("customerNum", salesReturn.getCustomerNum());
        data.put("customerName", salesReturn.getCustomerName());
        data.put("receivableCustomer", salesReturn.getReceivableCustomer());
        data.put("employeeNum", salesReturn.getEmployeeNum());
        data.put("remark", salesReturn.getRemark());
        data.put("goods", salesReturn.getGoods());
        return success(data);
    }

    private QueryWrapper<SalesReturn> buildWrapper(SalesReturn query, String orgId) {
        QueryWrapper<SalesReturn> wrapper = new QueryWrapper<SalesReturn>()
                .eq("org_id", orgId).eq("del_flag", "0");
        if (query == null) return wrapper.orderByDesc("id");
        if (query.getDocumentDateStart() != null) wrapper.ge("document_date", query.getDocumentDateStart());
        if (query.getDocumentDateEnd() != null) wrapper.le("document_date", query.getDocumentDateEnd());
        if (StringUtils.isNotBlank(query.getReturnNum())) wrapper.like("return_num", query.getReturnNum());
        if (StringUtils.isNotBlank(query.getDeliveryNum())) wrapper.like("delivery_num", query.getDeliveryNum());
        if (StringUtils.isNotBlank(query.getCustomerNum())) wrapper.like("customer_num", query.getCustomerNum());
        if (StringUtils.isNotBlank(query.getCustomerName())) {
            String safe = query.getCustomerName().trim().replace("'", "''");
            wrapper.inSql("customer_num", "SELECT customer_num FROM base_customer WHERE org_id='" + orgId + "' AND del_flag='0' AND customer_name LIKE '%" + safe + "%'");
        }
        if (StringUtils.isNotBlank(query.getRemark())) wrapper.like("remark", query.getRemark());
        if (StringUtils.isNotBlank(query.getEmployeeNum())) wrapper.like("employee_num", query.getEmployeeNum());
        if (query.getAuditStatus() != null) wrapper.eq("audit_status", query.getAuditStatus());
        if (StringUtils.isNotBlank(query.getGoodsNum())) {
            String safe = query.getGoodsNum().trim().replace("'", "''");
            wrapper.inSql("return_num", "SELECT return_num FROM sales_return_goods WHERE org_id='" + orgId + "' AND del_flag='0' AND goods_num LIKE '%" + safe + "%'");
        }
        if (StringUtils.isNotBlank(query.getWarehouseNum())) {
            String safe = query.getWarehouseNum().trim().replace("'", "''");
            wrapper.inSql("return_num", "SELECT return_num FROM sales_return_goods WHERE org_id='" + orgId + "' AND del_flag='0' AND warehouse_num LIKE '%" + safe + "%'");
        }
        if (StringUtils.isNotBlank(query.getGoodsName())) {
            String safe = query.getGoodsName().trim().replace("'", "''");
            wrapper.inSql("return_num", "SELECT g.return_num FROM sales_return_goods g LEFT JOIN base_material m ON m.org_id=g.org_id AND m.goods_num=g.goods_num WHERE g.org_id='" + orgId + "' AND g.del_flag='0' AND m.goods_name LIKE '%" + safe + "%'");
        }
        if (StringUtils.isNotBlank(query.getWarehouseName())) {
            String safe = query.getWarehouseName().trim().replace("'", "''");
            wrapper.inSql("return_num", "SELECT g.return_num FROM sales_return_goods g LEFT JOIN base_material m ON m.org_id=g.org_id AND m.goods_num=g.goods_num WHERE g.org_id='" + orgId + "' AND g.del_flag='0' AND m.warehouse_name LIKE '%" + safe + "%'");
        }
        return wrapper.orderByDesc("id");
    }

    private void validateBeforeSave(SalesReturn salesReturn, String orgId, boolean isAdd) throws Exception {
        if (salesReturn == null) throw new Exception("参数不能为空");
        if (StringUtils.isAnyBlank(salesReturn.getReturnNum(), salesReturn.getCustomerNum())) throw new Exception("单据编号、客户编号不能为空");
        QueryWrapper<SalesReturn> numWrapper = new QueryWrapper<SalesReturn>()
                .eq("org_id", orgId).eq("return_num", salesReturn.getReturnNum()).eq("del_flag", "0");
        if (!isAdd && salesReturn.getId() != null) numWrapper.ne("id", salesReturn.getId());
        if (salesReturnService.count(numWrapper) > 0) throw new Exception("该单据编号已存在");
        if (salesReturn.getGoods() == null || salesReturn.getGoods().isEmpty()) throw new Exception("货品清单不能为空");
        if (StringUtils.isNotBlank(salesReturn.getEmployeeNum())) {
            BaseEmployee emp = baseEmployeeService.getOne(new QueryWrapper<BaseEmployee>()
                    .eq("org_id", orgId).eq("employee_num", salesReturn.getEmployeeNum().trim()).eq("del_flag", "0").last("limit 1"));
            if (emp == null) throw new Exception("业务员编号不存在");
        }
    }

    private void fillCustomerInfo(SalesReturn salesReturn, String orgId) throws Exception {
        BaseCustomer customer = customerService.getOne(new QueryWrapper<BaseCustomer>()
                .eq("org_id", orgId).eq("customer_num", salesReturn.getCustomerNum()).eq("del_flag", "0").last("limit 1"));
        if (customer == null) throw new Exception("客户编号不存在");
        salesReturn.setCustomerName(customer.getCustomerName());
        salesReturn.setReceivableCustomer(customer.getReceivableCustomer());
    }

    private void fillByDeliveryNumIfNeeded(SalesReturn salesReturn, String orgId, boolean fillGoods) throws Exception {
        if (salesReturn == null || StringUtils.isBlank(salesReturn.getDeliveryNum())) return;
        SalesDelivery delivery = salesDeliveryService.getOne(new QueryWrapper<SalesDelivery>()
                .eq("org_id", orgId).eq("delivery_num", salesReturn.getDeliveryNum().trim()).eq("del_flag", "0").last("limit 1"));
        if (delivery == null) throw new Exception("销货转入单据不存在");
        if (StringUtils.isBlank(salesReturn.getCustomerNum())) salesReturn.setCustomerNum(delivery.getCustomerNum());
        if (StringUtils.isBlank(salesReturn.getEmployeeNum())) salesReturn.setEmployeeNum(delivery.getEmployeeNum());
        if (StringUtils.isBlank(salesReturn.getRemark())) salesReturn.setRemark(delivery.getRemark());
        if (fillGoods && (salesReturn.getGoods() == null || salesReturn.getGoods().isEmpty())) {
            List<SalesDeliveryGoods> deliveryGoods = salesDeliveryGoodsService.list(new QueryWrapper<SalesDeliveryGoods>()
                    .eq("org_id", orgId).eq("delivery_num", delivery.getDeliveryNum()).eq("del_flag", "0"));
            List<SalesReturnGoods> goods = new ArrayList<SalesReturnGoods>();
            for (SalesDeliveryGoods g : deliveryGoods) {
                SalesReturnGoods item = new SalesReturnGoods();
                item.setGoodsNum(g.getGoodsNum());
                item.setWarehouseNum(g.getWarehouseNum());
                item.setGoodsSpec(g.getGoodsSpec());
                item.setBatchNum(g.getBatchNum());
                item.setBaseNum(g.getBaseNum());
                item.setBaseUnit(g.getBaseUnit());
                item.setAssNum(g.getAssNum());
                item.setAssUnit(g.getAssUnit());
                item.setGoodsName(g.getGoodsName());
                item.setWarehouseName(g.getWarehouseName());
                item.setUnitPrice(g.getUnitPrice());
                item.setAmount(g.getAmount());
                item.setGoodsRemark(g.getGoodsRemark());
                goods.add(item);
            }
            salesReturn.setGoods(goods);
        }
    }

    private void recalcGoodsAmountAndTotal(SalesReturn salesReturn) {
        List<SalesReturnGoods> goods = salesReturn.getGoods();
        if (goods == null || goods.isEmpty()) {
            salesReturn.setTotalAmount(null);
            return;
        }
        BigDecimal sum = BigDecimal.ZERO;
        boolean any = false;
        for (SalesReturnGoods g : goods) {
            BigDecimal p = parseMoney(g.getUnitPrice());
            BigDecimal q = parseMoney(g.getBaseNum());
            BigDecimal line = (p != null && q != null) ? p.multiply(q) : parseMoney(g.getAmount());
            if (line != null) {
                g.setAmount(formatMoney(line));
                sum = sum.add(line);
                any = true;
            } else {
                g.setAmount(null);
            }
        }
        salesReturn.setTotalAmount(any ? formatMoney(sum) : null);
    }

    private void saveGoods(SalesReturn salesReturn, String orgId, String username) {
        List<SalesReturnGoods> goods = salesReturn.getGoods();
        if (goods == null) goods = Collections.emptyList();
        Date now = new Date();
        for (SalesReturnGoods g : goods) {
            g.setId(null);
            g.setOrgId(orgId);
            g.setReturnNum(salesReturn.getReturnNum());
            g.setDelFlag("0");
            g.setCreateBy(username);
            g.setCreateTime(now);
            g.setUpdateBy(null);
            g.setUpdateTime(null);
            salesReturnGoodsService.save(g);
        }
    }

    /**
     * 列表接口需带出货品清单：按退回单号批量查询子表，避免逐单 N+1。
     */
    private void attachGoodsForListRows(List<SalesReturn> list, String orgId) {
        if (list == null || list.isEmpty()) {
            return;
        }
        List<String> returnNums = list.stream()
                .filter(r -> r != null && StringUtils.isNotBlank(r.getReturnNum()))
                .map(r -> r.getReturnNum().trim())
                .distinct()
                .collect(Collectors.toList());
        if (returnNums.isEmpty()) {
            return;
        }
        List<SalesReturnGoods> allGoods = salesReturnGoodsService.list(new QueryWrapper<SalesReturnGoods>()
                .eq("org_id", orgId)
                .in("return_num", returnNums)
                .eq("del_flag", "0")
                .orderByAsc("id"));
        Map<String, List<SalesReturnGoods>> byReturnNum = new HashMap<String, List<SalesReturnGoods>>();
        for (SalesReturnGoods g : allGoods) {
            if (g == null || StringUtils.isBlank(g.getReturnNum())) {
                continue;
            }
            String key = g.getReturnNum().trim();
            byReturnNum.computeIfAbsent(key, k -> new ArrayList<SalesReturnGoods>()).add(g);
        }
        for (SalesReturn row : list) {
            if (row == null || StringUtils.isBlank(row.getReturnNum())) {
                continue;
            }
            List<SalesReturnGoods> goods = byReturnNum.getOrDefault(row.getReturnNum().trim(), Collections.<SalesReturnGoods>emptyList());
            List<SalesReturnGoods> copy = new ArrayList<SalesReturnGoods>(goods);
            enrichGoodsDisplay(copy, orgId);
            row.setGoods(copy);
        }
    }

    private void enrichSalesReturnDisplay(SalesReturn salesReturn, String orgId) {
        if (salesReturn == null) return;
        salesReturn.setCustomerName(null);
        salesReturn.setEmployeeName(null);
        if (StringUtils.isNotBlank(salesReturn.getCustomerNum())) {
            BaseCustomer c = customerService.getOne(new QueryWrapper<BaseCustomer>()
                    .eq("org_id", orgId).eq("customer_num", salesReturn.getCustomerNum().trim()).eq("del_flag", "0").last("limit 1"));
            if (c != null) {
                salesReturn.setCustomerName(c.getCustomerName());
                if (StringUtils.isBlank(salesReturn.getReceivableCustomer())) {
                    salesReturn.setReceivableCustomer(c.getReceivableCustomer());
                }
            }
        }
        if (StringUtils.isNotBlank(salesReturn.getEmployeeNum())) {
            BaseEmployee e = baseEmployeeService.getOne(new QueryWrapper<BaseEmployee>()
                    .eq("org_id", orgId).eq("employee_num", salesReturn.getEmployeeNum().trim()).eq("del_flag", "0").last("limit 1"));
            if (e != null) salesReturn.setEmployeeName(e.getEmployeeName());
        }
    }

    /**
     * 单据编号规则：
     * XSTH + 当前日期后一天的yyyyMMdd + 3位递增序号（不足补零，从001开始）
     */
    private String generateSalesReturnNum(String orgId) throws Exception {
        if (StringUtils.isBlank(orgId)) {
            throw new Exception("orgId不能为空");
        }
        String tomorrowYmd = LocalDate.now().plusDays(1).format(DateTimeFormatter.BASIC_ISO_DATE);
        String base = "XSTH" + tomorrowYmd;

        SalesReturn last = salesReturnService.getOne(new QueryWrapper<SalesReturn>()
                .eq("org_id", orgId)
                .eq("del_flag", "0")
                .like("return_num", base)
                .orderByDesc("return_num")
                .last("limit 1"));

        int startSeq = 1;
        if (last != null && StringUtils.isNotBlank(last.getReturnNum()) && last.getReturnNum().length() >= 3) {
            String suffix = last.getReturnNum().substring(last.getReturnNum().length() - 3);
            try {
                startSeq = Integer.parseInt(suffix) + 1;
            } catch (Exception ignored) {
                startSeq = 1;
            }
        }

        for (int seq = startSeq; seq <= 999; seq++) {
            String candidate = base + String.format("%03d", seq);
            long occupied = salesReturnService.count(new QueryWrapper<SalesReturn>()
                    .eq("org_id", orgId)
                    .eq("return_num", candidate)
                    .eq("del_flag", "0"));
            if (occupied == 0) {
                return candidate;
            }
        }
        throw new Exception("无法生成唯一销售退回单编号");
    }

    private void enrichGoodsDisplay(List<SalesReturnGoods> goods, String orgId) {
        if (goods == null || goods.isEmpty()) return;
        for (SalesReturnGoods g : goods) {
            if (StringUtils.isBlank(g.getGoodsNum())) continue;
            BaseMaterial m = baseMaterialService.getOne(new QueryWrapper<BaseMaterial>()
                    .eq("org_id", orgId).eq("goods_num", g.getGoodsNum()).eq("del_flag", "0").last("limit 1"));
            if (m == null) continue;
            g.setGoodsName(m.getGoodsName());
            if (StringUtils.isBlank(g.getGoodsSpec())) g.setGoodsSpec(m.getGoodsSpec());
            if (StringUtils.isBlank(g.getBaseUnit())) g.setBaseUnit(m.getUnit());
            if (StringUtils.isBlank(g.getAssUnit())) g.setAssUnit(m.getAssistantUnit());
            if (StringUtils.isBlank(g.getWarehouseName())) g.setWarehouseName(m.getWarehouseName());
            if (StringUtils.isBlank(g.getGoodsName())) g.setGoodsName(m.getGoodsName());
            BigDecimal p = parseMoney(g.getUnitPrice());
            BigDecimal q = parseMoney(g.getBaseNum());
            g.setAmount((p != null && q != null) ? formatMoney(p.multiply(q)) : null);
        }
    }

    private void deleteGoodsByReturnNum(String orgId, String returnNum) {
        if (StringUtils.isBlank(orgId) || StringUtils.isBlank(returnNum)) return;
        SalesReturnGoods up = new SalesReturnGoods();
        up.setDelFlag("2");
        up.setUpdateBy(getUsername());
        up.setUpdateTime(new Date());
        salesReturnGoodsService.update(up, new QueryWrapper<SalesReturnGoods>()
                .eq("org_id", orgId)
                .eq("return_num", returnNum)
                .eq("del_flag", "0"));
    }

    private BigDecimal parseMoney(String s) {
        if (StringUtils.isBlank(s)) return null;
        try {
            return new BigDecimal(s.trim().replace(",", ""));
        } catch (Exception e) {
            return null;
        }
    }

    private String formatMoney(BigDecimal n) {
        if (n == null) return null;
        return n.stripTrailingZeros().toPlainString();
    }

    private SalesReturn getActiveById(String id) throws Exception {
        SalesReturn salesReturn = salesReturnService.getById(id);
        if (salesReturn == null || !"0".equals(salesReturn.getDelFlag())) {
            throw new Exception("销售退回单不存在");
        }
        return salesReturn;
    }
}
