package shop.alien.lawyer.service.impl;

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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import shop.alien.entity.result.R;
import shop.alien.entity.store.LawFirm;
import shop.alien.entity.store.LawFirmPayment;
import shop.alien.entity.store.excelVo.LawFirmExcelVo;
import shop.alien.entity.store.excelVo.util.ExcelHeader;
import shop.alien.entity.store.vo.LawFirmPaymentVO;
import shop.alien.lawyer.service.LawFirmPaymentService;
import shop.alien.lawyer.service.LawFirmService;
import shop.alien.mapper.LawFirmMapper;
import shop.alien.mapper.LawFirmPaymentMapper;
import shop.alien.util.excel.EasyExcelUtil;

import org.apache.poi.ss.usermodel.DateUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 律所表 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Transactional
@Service
@RequiredArgsConstructor
public class LawFirmServiceImpl extends ServiceImpl<LawFirmMapper, LawFirm> implements LawFirmService {

    private final LawFirmMapper lawFirmMapper;
    private final LawFirmPaymentService lawFirmPaymentService;
    private final LawFirmPaymentMapper lawFirmPaymentMapper;

    @Override
    public R<IPage<LawFirm>> getLawFirmList(int pageNum, int pageSize, String firmName, Integer status) {
        log.info("LawFirmServiceImpl.getLawFirmList?pageNum={},pageSize={},firmName={},status={}", pageNum, pageSize, firmName, status);
        Page<LawFirm> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<LawFirm> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LawFirm::getDeleteFlag, 0);
        if (StringUtils.hasText(firmName)) {
            queryWrapper.like(LawFirm::getFirmName, firmName);
        }
        if (status != null) {
            queryWrapper.eq(LawFirm::getStatus, status);
        }
        queryWrapper.orderByDesc(LawFirm::getCreatedTime);
        IPage<LawFirm> pageResult = this.page(page, queryWrapper);
        return R.data(pageResult);
    }

    @Override
    public R<LawFirm> addLawFirm(LawFirm lawFirm) {
        log.info("LawFirmServiceImpl.addLawFirm?lawFirm={}, platformCommissionRatio={}", lawFirm, lawFirm.getPlatformCommissionRatio());
        
        // 第一步：先校验收款账号，如果 paymentAccount 在数据库中存在，不让新增
        if (lawFirm.getPaymentList() != null && !lawFirm.getPaymentList().isEmpty()) {
            for (LawFirmPayment payment : lawFirm.getPaymentList()) {
                if (StringUtils.hasText(payment.getPaymentAccount())) {
                    String paymentAccount = payment.getPaymentAccount().trim();
                    
                    // 检查收款账号是否在数据库中存在
                    LambdaQueryWrapper<LawFirmPayment> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
                    queryWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
                    long count = lawFirmPaymentService.count(queryWrapper);
                    if (count > 0) {
                        return R.fail("收款账号[" + paymentAccount + "]在数据库中已存在，不能添加");
                    }
                }
            }
        }
        
        // 第二步：paymentAccount 校验通过后，检查统一社会信用代码是否已存在
        LawFirm existingLawFirm = null;
        if (StringUtils.hasText(lawFirm.getCreditCode())) {
            LambdaQueryWrapper<LawFirm> creditCodeWrapper = new LambdaQueryWrapper<>();
            creditCodeWrapper.eq(LawFirm::getCreditCode, lawFirm.getCreditCode());
            creditCodeWrapper.eq(LawFirm::getDeleteFlag, 0);
            existingLawFirm = this.getOne(creditCodeWrapper);
        }
        
        // existingLawFirm 不为空执行更新主表和子表，否则执行新增主子表操作
        if (existingLawFirm != null) {
            // 更新主表和子表操作
            Integer firmId = existingLawFirm.getId();
            log.info("统一社会信用代码[{}]已存在，更新主表和子表数据，律所ID={}", lawFirm.getCreditCode(), firmId);
            
            // 更新主表数据：将新传入的字段更新到现有记录中
            lawFirm.setId(firmId);
            // 保留原有的一些字段（如果新数据没有提供）
            if (!StringUtils.hasText(lawFirm.getFirmName())) {
                lawFirm.setFirmName(existingLawFirm.getFirmName());
            }
            if (lawFirm.getStatus() == null) {
                lawFirm.setStatus(existingLawFirm.getStatus());
            }
            if (lawFirm.getDeleteFlag() == null) {
                lawFirm.setDeleteFlag(existingLawFirm.getDeleteFlag());
            }
            
            // 更新主表
            boolean updateResult = this.updateById(lawFirm);
            if (!updateResult) {
                log.error("更新律所主表失败，firmId={}", firmId);
                return R.fail("更新律所信息失败");
            }
            log.info("更新律所主表成功，firmId={}", firmId);
            
            // 保存子表数据
            if (lawFirm.getPaymentList() != null && !lawFirm.getPaymentList().isEmpty()) {
                for (LawFirmPayment payment : lawFirm.getPaymentList()) {
                    if (!StringUtils.hasText(payment.getPaymentAccount())) {
                        continue;
                    }
                    
                    String paymentAccount = payment.getPaymentAccount().trim();
                    
                    // 再次检查账号是否已存在（防止并发问题）
                    LambdaQueryWrapper<LawFirmPayment> checkWrapper = new LambdaQueryWrapper<>();
                    checkWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
                    checkWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
                    long checkCount = lawFirmPaymentService.count(checkWrapper);
                    if (checkCount > 0) {
                        return R.fail("收款账号[" + paymentAccount + "]在数据库中已存在，不能添加");
                    }
                    
                    // 新增收款账号
                    LawFirmPayment newPayment = new LawFirmPayment();
                    newPayment.setFirmId(firmId);
                    newPayment.setPaymentAccount(paymentAccount);
                    if (StringUtils.hasText(payment.getAddress())) {
                        newPayment.setAddress(payment.getAddress().trim());
                    }
                    newPayment.setDeleteFlag(0);
                    
                    boolean saveResult = lawFirmPaymentService.save(newPayment);
                    if (!saveResult) {
                        log.error("保存收款账号失败，firmId={}, paymentAccount={}", firmId, paymentAccount);
                        return R.fail("保存收款账号失败：" + paymentAccount);
                    }
                    log.info("保存收款账号成功，firmId={}, paymentAccount={}, id={}", 
                            firmId, paymentAccount, newPayment.getId());
                }
            }
            
            // 重新查询更新后的数据返回
            LawFirm updatedLawFirm = this.getById(firmId);
            return R.data(updatedLawFirm, "统一社会信用代码已存在，已更新律所信息和收款账号列表");
        } else {
            // 新增主子表操作
            // 保存主表
            log.info("新增律所，platformCommissionRatio={}", lawFirm.getPlatformCommissionRatio());
            boolean result = this.save(lawFirm);
            if (!result) {
                return R.fail("新增失败");
            }
            Integer firmId = lawFirm.getId();
            
            // 验证 platformCommissionRatio 是否保存成功
            LawFirm savedLawFirm = this.getById(firmId);
            if (savedLawFirm != null) {
                log.info("保存后的律所，platformCommissionRatio={}", savedLawFirm.getPlatformCommissionRatio());
            }
            
            // 保存子表数据
            if (lawFirm.getPaymentList() != null && !lawFirm.getPaymentList().isEmpty()) {
                for (LawFirmPayment payment : lawFirm.getPaymentList()) {
                    if (!StringUtils.hasText(payment.getPaymentAccount())) {
                        continue;
                    }
                    
                    String paymentAccount = payment.getPaymentAccount().trim();
                    
                    // 再次检查账号是否已存在（防止并发问题）
                    LambdaQueryWrapper<LawFirmPayment> checkWrapper = new LambdaQueryWrapper<>();
                    checkWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
                    checkWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
                    long checkCount = lawFirmPaymentService.count(checkWrapper);
                    if (checkCount > 0) {
                        return R.fail("收款账号[" + paymentAccount + "]在数据库中已存在，不能添加");
                    }
                    
                    // 创建新的对象，避免污染原对象
                    LawFirmPayment newPayment = new LawFirmPayment();
                    newPayment.setFirmId(firmId);
                    newPayment.setPaymentAccount(paymentAccount);
                    if (StringUtils.hasText(payment.getAddress())) {
                        newPayment.setAddress(payment.getAddress().trim());
                    }
                    newPayment.setDeleteFlag(0);

                    boolean saveResult = lawFirmPaymentService.save(newPayment);
                    if (!saveResult) {
                        log.error("保存收款账号失败，firmId={}, paymentAccount={}", firmId, paymentAccount);
                        return R.fail("保存收款账号失败：" + paymentAccount);
                    }
                    log.info("保存收款账号成功，firmId={}, paymentAccount={}, id={}", 
                            firmId, paymentAccount, newPayment.getId());
                }
            }
            
            return R.data(lawFirm);
        }
    }

    @Override
    public R<LawFirm> editLawFirm(LawFirm lawFirm) {
        log.info("LawFirmServiceImpl.editLawFirm?lawFirm={}", lawFirm);
        
        // 校验律所ID
        if (lawFirm.getId() == null) {
            return R.fail("律所ID不能为空");
        }
        
        // 检查律所是否存在
        LawFirm existingLawFirm = this.getById(lawFirm.getId());
        if (existingLawFirm == null || existingLawFirm.getDeleteFlag() == 1) {
            return R.fail("律所不存在");
        }
        
        // 第一步：先校验收款账号，如果 paymentAccount 在数据库中存在，不让新增或修改
        if (lawFirm.getPaymentList() != null && !lawFirm.getPaymentList().isEmpty()) {
            // 查询当前律所下现有的收款账号记录（用于判断是新增还是更新）
            LambdaQueryWrapper<LawFirmPayment> existingWrapper = new LambdaQueryWrapper<>();
            existingWrapper.eq(LawFirmPayment::getFirmId, lawFirm.getId());
            existingWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
            List<LawFirmPayment> existingPayments = lawFirmPaymentService.list(existingWrapper);
            Map<Integer, String> existingPaymentMap = existingPayments.stream()
                    .collect(Collectors.toMap(LawFirmPayment::getId, LawFirmPayment::getPaymentAccount));
            
            for (LawFirmPayment payment : lawFirm.getPaymentList()) {
                if (StringUtils.hasText(payment.getPaymentAccount())) {
                    String paymentAccount = payment.getPaymentAccount().trim();
                    
                    // 如果是更新操作，检查账号是否被修改
                    if (payment.getId() != null) {
                        String originalAccount = existingPaymentMap.get(payment.getId());
                        // 如果账号被修改了，需要检查新账号是否已存在
                        if (originalAccount != null && !originalAccount.equals(paymentAccount)) {
                            // 检查新账号是否在数据库中存在（排除当前记录）
                            LambdaQueryWrapper<LawFirmPayment> queryWrapper = new LambdaQueryWrapper<>();
                            queryWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
                            queryWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
                            queryWrapper.ne(LawFirmPayment::getId, payment.getId());
                            long count = lawFirmPaymentService.count(queryWrapper);
                            if (count > 0) {
                                return R.fail("新收款账号数据库已存在");
                            }
                        }
                    } else {
                        // 新增操作：检查账号是否在数据库中存在
                        LambdaQueryWrapper<LawFirmPayment> queryWrapper = new LambdaQueryWrapper<>();
                        queryWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
                        queryWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
                        long count = lawFirmPaymentService.count(queryWrapper);
                        if (count > 0) {
                            return R.fail("收款账号[" + paymentAccount + "]在数据库中已存在，不能添加");
                        }
                    }
                }
            }
        }
        
        // 第二步：更新主表
        boolean result = this.updateById(lawFirm);
        if (!result) {
        return R.fail("修改失败");
        }
        
        // 第三步：处理子表数据
        if (lawFirm.getPaymentList() != null) {
            // 查询现有的收款账号记录
            LambdaQueryWrapper<LawFirmPayment> existingWrapper = new LambdaQueryWrapper<>();
            existingWrapper.eq(LawFirmPayment::getFirmId, lawFirm.getId());
            existingWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
            List<LawFirmPayment> existingPayments = lawFirmPaymentService.list(existingWrapper);
            
            // 收集前端传来的收款账号ID
            Set<Integer> incomingIds = lawFirm.getPaymentList().stream()
                    .filter(p -> p.getId() != null)
                    .map(LawFirmPayment::getId)
                    .collect(Collectors.toSet());
            
            // 删除不在前端列表中的记录（逻辑删除）
            for (LawFirmPayment existing : existingPayments) {
                if (!incomingIds.contains(existing.getId())) {
                    existing.setDeleteFlag(1);
                    lawFirmPaymentService.updateById(existing);
                }
            }
            
            // 新增或更新收款账号记录
            for (LawFirmPayment payment : lawFirm.getPaymentList()) {
                if (!StringUtils.hasText(payment.getPaymentAccount())) {
                    continue;
                }
                
                String paymentAccount = payment.getPaymentAccount().trim();
                
                try {
                    if (payment.getId() != null) {
                        // 更新：获取原始记录
                        LawFirmPayment existingPayment = existingPayments.stream()
                                .filter(p -> p.getId().equals(payment.getId()))
                                .findFirst()
                                .orElse(null);
                        
                        if (existingPayment != null) {
                            String originalAccount = existingPayment.getPaymentAccount();
                            
                            // 如果 paymentAccount 被修改了，不更新 paymentAccount 字段，保持原值
                            LawFirmPayment updatePayment = new LawFirmPayment();
                            updatePayment.setId(payment.getId());
                            updatePayment.setFirmId(lawFirm.getId());
                            
                            // 如果账号被修改了，保持原值；否则使用新值
                            if (!originalAccount.equals(paymentAccount)) {
                                updatePayment.setPaymentAccount(originalAccount); // 保持原值
                            } else {
                                updatePayment.setPaymentAccount(paymentAccount);
                            }
                            
                            // 更新其他字段
                            if (StringUtils.hasText(payment.getAddress())) {
                                updatePayment.setAddress(payment.getAddress().trim());
                            } else {
                                updatePayment.setAddress(existingPayment.getAddress());
                            }
                            
                            boolean updateResult = lawFirmPaymentService.updateById(updatePayment);
                            if (!updateResult) {
                                log.error("更新收款账号失败，firmId={}, paymentAccount={}, id={}", 
                                        lawFirm.getId(), paymentAccount, payment.getId());
                                return R.fail("更新收款账号失败：" + paymentAccount);
                            }
                            log.info("更新收款账号成功，firmId={}, paymentAccount={}, id={}", 
                                    lawFirm.getId(), existingPayment.getPaymentAccount(), updatePayment.getId());
                        }
                    } else {
                        // 新增：再次检查账号是否已存在（防止并发问题）
                        LambdaQueryWrapper<LawFirmPayment> checkWrapper = new LambdaQueryWrapper<>();
                        checkWrapper.eq(LawFirmPayment::getPaymentAccount, paymentAccount);
                        checkWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
                        long checkCount = lawFirmPaymentService.count(checkWrapper);
                        if (checkCount > 0) {
                            return R.fail("收款账号[" + paymentAccount + "]在数据库中已存在，不能添加");
                        }
                        
                        // 新增收款账号
                        LawFirmPayment newPayment = new LawFirmPayment();
                        newPayment.setFirmId(lawFirm.getId());
                        newPayment.setPaymentAccount(paymentAccount);
                        if (StringUtils.hasText(payment.getAddress())) {
                            newPayment.setAddress(payment.getAddress().trim());
                        }
                        newPayment.setDeleteFlag(0);
                        
                        boolean saveResult = lawFirmPaymentService.save(newPayment);
                        if (!saveResult) {
                            log.error("保存收款账号失败，firmId={}, paymentAccount={}", lawFirm.getId(), paymentAccount);
                            return R.fail("保存收款账号失败：" + paymentAccount);
                        }
                        log.info("保存收款账号成功，firmId={}, paymentAccount={}, id={}", 
                                lawFirm.getId(), paymentAccount, newPayment.getId());
                    }
                } catch (Exception e) {
                    log.error("处理收款账号异常，firmId={}, paymentAccount={}", lawFirm.getId(), paymentAccount, e);
                    return R.fail("处理收款账号异常：" + e.getMessage());
                }
            }
        }
        
        return R.data(lawFirm);
    }

    @Override
    public R<Boolean> deleteLawFirm(Integer id) {
        log.info("LawFirmServiceImpl.deleteLawFirm?paymentId={}", id);
        
        // 1. 根据律所子表id查询子表记录
        LawFirmPayment payment = lawFirmPaymentService.getById(id);
        if (payment == null || payment.getDeleteFlag() == 1) {
            return R.fail("收款账号记录不存在或已被删除");
        }
        
        Integer firmId = payment.getFirmId();
        if (firmId == null) {
            return R.fail("律所ID为空，无法删除");
        }
        
        // 2. 删除子表记录（逻辑删除）
        boolean deletePaymentResult = lawFirmPaymentService.removeById(id);
        if (!deletePaymentResult) {
            return R.fail("删除收款账号失败");
        }
        log.info("删除收款账号成功，paymentId={}, firmId={}", id, firmId);
        
        // 3. 查询该律所是否还有关联的子表（未删除的）
        LambdaQueryWrapper<LawFirmPayment> paymentWrapper = new LambdaQueryWrapper<>();
        paymentWrapper.eq(LawFirmPayment::getFirmId, firmId);
        paymentWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
        long remainingPaymentCount = lawFirmPaymentService.count(paymentWrapper);
        
        // 4. 如果没有子表了，继续删除主表（逻辑删除）
        if (remainingPaymentCount == 0) {
            log.info("律所[{}]没有关联的收款账号了，删除主表", firmId);
            boolean deleteFirmResult = this.removeById(firmId);
            if (!deleteFirmResult) {
                log.warn("删除律所主表失败，firmId={}", firmId);
                return R.success("收款账号删除成功，但删除律所主表失败");
            }
            log.info("删除律所主表成功，firmId={}", firmId);
            return R.success("删除成功，已同时删除律所主表");
        } else {
            log.info("律所[{}]还有{}个收款账号，保留主表", firmId, remainingPaymentCount);
            return R.success("删除成功");
        }
    }

    @Override
    public R<LawFirm> register(LawFirm lawFirm) {
        log.info("LawFirmServiceImpl.register?lawFirm={}", lawFirm);
        
        // 校验必填字段
        if (!StringUtils.hasText(lawFirm.getFirmName())) {
            return R.fail("律所名称不能为空");
        }
        if (!StringUtils.hasText(lawFirm.getCreditCode())) {
            return R.fail("统一社会信用代码不能为空");
        }
        if (!StringUtils.hasText(lawFirm.getPhone())) {
            return R.fail("联系电话不能为空");
        }
        if (!StringUtils.hasText(lawFirm.getDirectorName())) {
            return R.fail("负责人姓名不能为空");
        }
        if (!StringUtils.hasText(lawFirm.getDirectorPhone())) {
            return R.fail("负责人电话不能为空");
        }
        
        // 校验统一社会信用代码是否已存在
        LambdaQueryWrapper<LawFirm> creditCodeWrapper = new LambdaQueryWrapper<>();
        creditCodeWrapper.eq(LawFirm::getCreditCode, lawFirm.getCreditCode());
        creditCodeWrapper.eq(LawFirm::getDeleteFlag, 0);
        long creditCodeCount = this.count(creditCodeWrapper);
        if (creditCodeCount > 0) {
            return R.fail("该统一社会信用代码已注册，请勿重复注册");
        }
        
        // 校验联系电话是否已存在
        if (StringUtils.hasText(lawFirm.getPhone())) {
            LambdaQueryWrapper<LawFirm> phoneWrapper = new LambdaQueryWrapper<>();
            phoneWrapper.eq(LawFirm::getPhone, lawFirm.getPhone());
            phoneWrapper.eq(LawFirm::getDeleteFlag, 0);
            long phoneCount = this.count(phoneWrapper);
            if (phoneCount > 0) {
                return R.fail("该联系电话已被使用，请更换其他号码");
            }
        }
        
        // 校验负责人电话是否已存在
        if (StringUtils.hasText(lawFirm.getDirectorPhone())) {
            LambdaQueryWrapper<LawFirm> directorPhoneWrapper = new LambdaQueryWrapper<>();
            directorPhoneWrapper.eq(LawFirm::getDirectorPhone, lawFirm.getDirectorPhone());
            directorPhoneWrapper.eq(LawFirm::getDeleteFlag, 0);
            long directorPhoneCount = this.count(directorPhoneWrapper);
            if (directorPhoneCount > 0) {
                return R.fail("该负责人电话已被使用，请更换其他号码");
            }
        }
        
        // 校验邮箱是否已存在
        if (StringUtils.hasText(lawFirm.getEmail())) {
            LambdaQueryWrapper<LawFirm> emailWrapper = new LambdaQueryWrapper<>();
            emailWrapper.eq(LawFirm::getEmail, lawFirm.getEmail());
            emailWrapper.eq(LawFirm::getDeleteFlag, 0);
            long emailCount = this.count(emailWrapper);
            if (emailCount > 0) {
                return R.fail("该邮箱已被使用，请更换其他邮箱");
            }
        }
        
        // 设置注册时的初始状态
        lawFirm.setStatus(1); // 启用状态
        lawFirm.setCertificationStatus(0); // 未认证状态
        lawFirm.setDeleteFlag(0); // 未删除
        lawFirm.setIsRecommended(0); // 默认不推荐
        if (lawFirm.getLawyerCount() == null) {
            lawFirm.setLawyerCount(0);
        }
        if (lawFirm.getPartnerCount() == null) {
            lawFirm.setPartnerCount(0);
        }
        
        // 保存律所信息
        boolean result = this.save(lawFirm);
        if (result) {
            return R.data(lawFirm, "注册成功，请等待审核");
        }
        return R.fail("注册失败，请稍后重试");
    }

    @Override
    public void exportLawFirm(HttpServletResponse response, Integer firmId, Integer pageNum, Integer pageSize) throws IOException {
        log.info("LawFirmServiceImpl.exportLawFirm?firmId={},pageNum={},pageSize={}", firmId, pageNum, pageSize);
        try {
            // 如果 pageSize 为 null，则导出全部数据；否则使用分页
            int currentPage = (pageNum != null && pageNum > 0) ? pageNum : 1;
            int size = (pageSize != null && pageSize > 0) ? pageSize : Integer.MAX_VALUE;
            
            Page<LawFirmPaymentVO> page = new Page<>(currentPage, size);
            IPage<LawFirmPaymentVO> pageResult = lawFirmPaymentMapper.selectPaymentPageWithFirm(
                    page, firmId, null, null, null, null, null, null, null, null
            );

            List<LawFirmPaymentVO> paymentList = pageResult.getRecords();

            if (paymentList == null || paymentList.isEmpty()) {
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                response.getWriter().write("暂无数据可导出");
                return;
            }

            // 使用 EasyExcelUtil 导出
            EasyExcelUtil.exportExcel(response, paymentList, LawFirmPaymentVO.class, "律所列表", "律所列表");
        } catch (Exception e) {
            log.error("导出律所数据失败", e);
            if (!response.isCommitted()) {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.getWriter().write("导出失败：" + e.getMessage());
            }
            throw new IOException("导出失败：" + e.getMessage(), e);
        }
    }

    @Override
    public R<String> importLawFirm(MultipartFile file) {
        log.info("LawFirmServiceImpl.importLawFirm fileName={}", file.getOriginalFilename());
        try {
            if (file == null || file.isEmpty()) {
                return R.fail("文件不能为空");
            }

            String fileName = file.getOriginalFilename();
            if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
                return R.fail("文件格式不正确，请上传Excel文件");
            }

            List<LawFirmExcelVo> excelVoList = new ArrayList<>();
            List<String> errorMessages = new ArrayList<>();

            // 使用POI读取Excel
            try (InputStream inputStream = file.getInputStream();
                 Workbook workbook = new XSSFWorkbook(inputStream)) {
                Sheet sheet = workbook.getSheetAt(0);

                // 获取表头
                Row headerRow = sheet.getRow(0);
                if (headerRow == null) {
                    return R.fail("Excel文件格式不正确，缺少表头");
                }

                // 构建字段映射（表头名称 -> 列索引）
                Map<String, Integer> headerMap = new HashMap<>();
                Field[] fields = LawFirmExcelVo.class.getDeclaredFields();
                for (int i = 0; i < headerRow.getLastCellNum(); i++) {
                    Cell cell = headerRow.getCell(i);
                    if (cell != null) {
                        String headerName = cell.getStringCellValue().trim();
                        headerMap.put(headerName, i);
                    }
                }

                // 读取数据行
                for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                    Row row = sheet.getRow(rowIndex);
                    if (row == null) {
                        continue;
                    }

                    // 检查是否为空行
                    boolean isEmptyRow = true;
                    for (int i = 0; i < row.getLastCellNum(); i++) {
                        Cell cell = row.getCell(i);
                        if (cell != null && cell.getCellType() != CellType.BLANK) {
                            isEmptyRow = false;
                            break;
                        }
                    }
                    if (isEmptyRow) {
                        continue;
                    }

                    LawFirmExcelVo excelVo = new LawFirmExcelVo();

                    // 读取每个字段
                    for (Field field : fields) {
                        if (!field.isAnnotationPresent(ExcelHeader.class)) {
                            continue;
                        }
                        ExcelHeader excelHeader = field.getAnnotation(ExcelHeader.class);
                        String headerName = excelHeader.value();
                        Integer colIndex = headerMap.get(headerName);
                        if (colIndex == null) {
                            continue;
                        }

                        Cell cell = row.getCell(colIndex);
                        if (cell == null) {
                            continue;
                        }

                        field.setAccessible(true);
                        try {
                            String cellValue = getCellValueAsString(cell);
                            if (cellValue != null && !cellValue.trim().isEmpty()) {
                                // 根据字段类型设置值
                                Class<?> fieldType = field.getType();
                                if (fieldType == String.class) {
                                    field.set(excelVo, cellValue.trim());
                                } else if (fieldType == Integer.class) {
                                    try {
                                        field.set(excelVo, Integer.parseInt(cellValue.trim()));
                                    } catch (NumberFormatException e) {
                                        // 忽略
                                    }
                                }
                            }
                        } catch (Exception e) {
                            log.warn("读取字段{}失败：{}", headerName, e.getMessage());
                        }
                    }

                    // 校验数据
                    String errorMsg = validateExcelData(excelVo, rowIndex + 1);
                    if (errorMsg != null) {
                        errorMessages.add(errorMsg);
                    } else {
                        excelVoList.add(excelVo);
                    }
                }
            }

            if (!errorMessages.isEmpty()) {
                return R.fail("数据校验失败：\n" + String.join("\n", errorMessages));
            }

            if (excelVoList.isEmpty()) {
                return R.fail("Excel文件中没有有效数据");
            }

            // 收集所有导入数据中的收款账号（用于检查重复）
            Set<String> allImportAccounts = new HashSet<>();
            Map<String, String> accountToFirmNameMap = new HashMap<>(); // 账号 -> 律所名称，用于错误提示

            // 先收集所有账号，检查导入数据中的重复（不允许逗号分隔）
            for (LawFirmExcelVo excelVo : excelVoList) {
                String paymentAccount = excelVo.getPaymentAccount();
                if (StringUtils.hasText(paymentAccount)) {
                    String trimmedAccount = paymentAccount.trim();
                    if (!trimmedAccount.isEmpty()) {
                        if (allImportAccounts.contains(trimmedAccount)) {
                            // 发现重复账号
                            String existingFirmName = accountToFirmNameMap.get(trimmedAccount);
                            return R.fail(String.format("导入数据中存在重复的收款账号[%s]，律所[%s]和律所[%s]使用了相同的账号，无法导入",
                                    trimmedAccount, existingFirmName, excelVo.getFirmName()));
                        }
                        allImportAccounts.add(trimmedAccount);
                        accountToFirmNameMap.put(trimmedAccount, excelVo.getFirmName());
                    }
                }
            }

            // 检查数据库中是否已存在这些账号
            if (!allImportAccounts.isEmpty()) {
                // 查询数据库中所有已存在的收款账号（从子表查询）
                LambdaQueryWrapper<LawFirmPayment> paymentWrapper = new LambdaQueryWrapper<>();
                paymentWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
                paymentWrapper.isNotNull(LawFirmPayment::getPaymentAccount);
                paymentWrapper.ne(LawFirmPayment::getPaymentAccount, "");
                List<LawFirmPayment> existingPayments = lawFirmPaymentService.list(paymentWrapper);

                // 收集数据库中所有已存在的账号
                Set<String> existingAccounts = new HashSet<>();
                for (LawFirmPayment payment : existingPayments) {
                    String paymentAccount = payment.getPaymentAccount();
                    if (StringUtils.hasText(paymentAccount)) {
                        existingAccounts.add(paymentAccount.trim());
                    }
                }

                // 检查导入的账号是否已存在
                Set<String> duplicateAccounts = new HashSet<>();
                for (String importAccount : allImportAccounts) {
                    if (existingAccounts.contains(importAccount)) {
                        duplicateAccounts.add(importAccount);
                    }
                }

                if (!duplicateAccounts.isEmpty()) {
                    String duplicateAccountList = String.join("、", duplicateAccounts);
                    return R.fail(String.format("收款账号[%s]在数据库中已存在，无法导入。请检查并修改账号后重新导入", duplicateAccountList));
                }
            }

            // 按统一社会信用代码分组，合并数据
            // 先检查是否有空的信用代码
            for (LawFirmExcelVo excelVo : excelVoList) {
                if (!StringUtils.hasText(excelVo.getCreditCode())) {
                    return R.fail("导入数据中存在空的统一社会信用代码，请检查第" + (excelVoList.indexOf(excelVo) + 2) + "行数据");
                }
            }

            // 按统一社会信用代码分组
            Map<String, List<LawFirmExcelVo>> creditCodeMap = excelVoList.stream()
                    .filter(vo -> StringUtils.hasText(vo.getCreditCode()))
                    .collect(Collectors.groupingBy(LawFirmExcelVo::getCreditCode));

            int successCount = 0;
            int failCount = 0;
            int updateCount = 0;
            List<String> importErrors = new ArrayList<>();

            for (Map.Entry<String, List<LawFirmExcelVo>> entry : creditCodeMap.entrySet()) {
                String creditCode = entry.getKey();
                List<LawFirmExcelVo> voList = entry.getValue();

                // 合并收款账号，并维护账号和地址的对应关系（不允许逗号分隔）
                // 使用LinkedHashMap保持顺序，后出现的账号地址会覆盖先出现的（如果地址不为空）
                Map<String, String> accountAddressMap = new LinkedHashMap<>();
                for (LawFirmExcelVo vo : voList) {
                    String paymentAccount = vo.getPaymentAccount();
                    String address = vo.getAddress();
                    if (StringUtils.hasText(paymentAccount)) {
                        String trimmedAccount = paymentAccount.trim();
                        if (!trimmedAccount.isEmpty()) {
                            // 如果账号已存在但地址为空，且当前地址不为空，则更新地址
                            // 如果账号不存在，直接添加
                            if (!accountAddressMap.containsKey(trimmedAccount) || 
                                (StringUtils.hasText(address) && !StringUtils.hasText(accountAddressMap.get(trimmedAccount)))) {
                                accountAddressMap.put(trimmedAccount, address != null ? address.trim() : "");
                            }
                        }
                    }
                }

                // 使用第一个数据作为主数据，其他数据补充缺失字段
                LawFirmExcelVo firstVo = voList.get(0);
                LawFirm lawFirm = convertToLawFirm(firstVo);
                
                // 如果第一个数据缺少某些字段，尝试从其他数据中获取
                for (int i = 1; i < voList.size(); i++) {
                    LawFirmExcelVo otherVo = voList.get(i);
                    // 补充缺失的字段（这里可以根据需要补充其他字段）
                    if (!StringUtils.hasText(lawFirm.getFirmName()) && StringUtils.hasText(otherVo.getFirmName())) {
                        lawFirm.setFirmName(otherVo.getFirmName());
                    }
                    if (!StringUtils.hasText(lawFirm.getPhone()) && StringUtils.hasText(otherVo.getPhone())) {
                        lawFirm.setPhone(otherVo.getPhone());
                    }
                    if (!StringUtils.hasText(lawFirm.getDirectorName()) && StringUtils.hasText(otherVo.getDirectorName())) {
                        lawFirm.setDirectorName(otherVo.getDirectorName());
                    }
                    if (!StringUtils.hasText(lawFirm.getDirectorPhone()) && StringUtils.hasText(otherVo.getDirectorPhone())) {
                        lawFirm.setDirectorPhone(otherVo.getDirectorPhone());
                    }
                }

                // 检查统一社会信用代码是否已存在
                LambdaQueryWrapper<LawFirm> creditCodeWrapper = new LambdaQueryWrapper<>();
                creditCodeWrapper.eq(LawFirm::getCreditCode, creditCode);
                creditCodeWrapper.eq(LawFirm::getDeleteFlag, 0);
                LawFirm existingLawFirm = this.getOne(creditCodeWrapper);
                
                boolean isUpdate = false;
                if (existingLawFirm != null) {
                    // 如果已存在，更新现有记录
                    isUpdate = true;
                    lawFirm.setId(existingLawFirm.getId());
                    // 保留原有的一些字段（如果新数据没有提供）
                    if (!StringUtils.hasText(lawFirm.getFirmName())) {
                        lawFirm.setFirmName(existingLawFirm.getFirmName());
                    }
                    if (!StringUtils.hasText(lawFirm.getPhone())) {
                        lawFirm.setPhone(existingLawFirm.getPhone());
                    }
                    if (lawFirm.getStatus() == null) {
                        lawFirm.setStatus(existingLawFirm.getStatus());
                    }
                } else {
                    // 设置默认值（新增时）
                if (lawFirm.getStatus() == null) {
                    lawFirm.setStatus(1);
                }
                }
                
                if (lawFirm.getDeleteFlag() == null) {
                    lawFirm.setDeleteFlag(0);
                }
                
                // 保存或更新主表
                boolean saveResult;
                if (isUpdate) {
                    saveResult = this.updateById(lawFirm);
                } else {
                    saveResult = this.save(lawFirm);
                }
                
                if (!saveResult) {
                    importErrors.add("统一社会信用代码[" + creditCode + "]" + (isUpdate ? "更新" : "保存") + "失败");
                    failCount++;
                    continue;
                }
                
                // 处理子表收款账号
                if (!accountAddressMap.isEmpty()) {
                    // 查询现有的收款账号
                    LambdaQueryWrapper<LawFirmPayment> existingPaymentWrapper = new LambdaQueryWrapper<>();
                    existingPaymentWrapper.eq(LawFirmPayment::getFirmId, lawFirm.getId());
                    existingPaymentWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
                    List<LawFirmPayment> existingPayments = lawFirmPaymentService.list(existingPaymentWrapper);
                    
                    // 收集现有的收款账号
                    Set<String> existingAccountSet = existingPayments.stream()
                            .map(LawFirmPayment::getPaymentAccount)
                            .filter(Objects::nonNull)
                            .filter(acc -> !acc.trim().isEmpty())
                            .collect(Collectors.toSet());
                    
                    // 添加新的收款账号（排除已存在的），每个账号使用其对应的地址
                    for (Map.Entry<String, String> accountEntry : accountAddressMap.entrySet()) {
                        String trimmedAccount = accountEntry.getKey();
                        String address = accountEntry.getValue();
                        
                        if (!trimmedAccount.isEmpty() && !existingAccountSet.contains(trimmedAccount)) {
                            // 检查账号是否已存在（全局唯一性校验）
                            LambdaQueryWrapper<LawFirmPayment> accountWrapper = new LambdaQueryWrapper<>();
                            accountWrapper.eq(LawFirmPayment::getPaymentAccount, trimmedAccount);
                            accountWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
                            long accountCount = lawFirmPaymentService.count(accountWrapper);
                            if (accountCount == 0) {
                                // 账号不存在，可以添加
                                LawFirmPayment payment = new LawFirmPayment();
                                payment.setFirmId(lawFirm.getId());
                                payment.setPaymentAccount(trimmedAccount);
                                // 设置详细地址（使用该账号对应的地址）
                                if (StringUtils.hasText(address)) {
                                    payment.setAddress(address.trim());
                                }
                                payment.setDeleteFlag(0);
                                lawFirmPaymentService.save(payment);
                            } else {
                                // 账号已存在，记录警告但不阻止导入
                                log.warn("收款账号[{}]已存在，跳过添加", trimmedAccount);
                            }
                        }
                    }
                }

                if (isUpdate) {
                    updateCount++;
                } else {
                    successCount++;
                }
            }

            String resultMsg = String.format("导入完成：新增%d条，更新%d条，失败%d条", successCount, updateCount, failCount);
            if (!importErrors.isEmpty()) {
                resultMsg += "\n失败详情：\n" + String.join("\n", importErrors);
            }

            return R.success(resultMsg);
        } catch (Exception e) {
            log.error("导入律所数据失败", e);
            return R.fail("导入失败：" + e.getMessage());
        }
    }

    /**
     * 生成带合并单元格的Excel
     */
    private void generateExcelWithMerge(HttpServletResponse response, List<LawFirmExcelVo> excelVoList,
                                        Map<String, List<LawFirm>> firmNameMap) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("律所列表");

        // 获取字段
        Field[] fields = LawFirmExcelVo.class.getDeclaredFields();
        List<Field> excelFields = Arrays.stream(fields)
                .filter(f -> f.isAnnotationPresent(ExcelHeader.class))
                .collect(Collectors.toList());

        // 创建表头样式
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        CellStyle headerCellStyle = workbook.createCellStyle();
        headerCellStyle.setFont(headerFont);
        headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
        headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        // 创建数据样式
        CellStyle dataCellStyle = workbook.createCellStyle();
        dataCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        dataCellStyle.setWrapText(true);

        // 创建表头
        Row headerRow = sheet.createRow(0);
        for (int i = 0; i < excelFields.size(); i++) {
            Field field = excelFields.get(i);
            ExcelHeader excelHeader = field.getAnnotation(ExcelHeader.class);
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(excelHeader.value());
            cell.setCellStyle(headerCellStyle);
        }

        // 填充数据
        int rowNum = 1;
        Map<String, Integer> firmNameRowMap = new HashMap<>(); // 记录每个律所名称的第一行
        Map<String, Integer> firmNameCountMap = new HashMap<>(); // 记录每个律所名称的行数

        for (LawFirmExcelVo excelVo : excelVoList) {
            Row row = sheet.createRow(rowNum);
            String firmName = excelVo.getFirmName();

            if (!firmNameRowMap.containsKey(firmName)) {
                firmNameRowMap.put(firmName, rowNum);
                // 计算该律所名称有多少行
                long count = excelVoList.stream()
                        .filter(vo -> firmName.equals(vo.getFirmName()))
                        .count();
                firmNameCountMap.put(firmName, (int) count);
            }

            for (int i = 0; i < excelFields.size(); i++) {
                Field field = excelFields.get(i);
                field.setAccessible(true);
                Cell cell = row.createCell(i);
                cell.setCellStyle(dataCellStyle);
                try {
                    Object value = field.get(excelVo);
                    if (value != null) {
                        cell.setCellValue(value.toString());
                    }
                } catch (IllegalAccessException e) {
                    log.error("获取字段值失败", e);
                }
            }
            rowNum++;
        }

        // 合并相同律所名称的单元格（除了账号列）
        int firmNameColIndex = -1;
        int paymentAccountColIndex = -1;
        for (int i = 0; i < excelFields.size(); i++) {
            Field field = excelFields.get(i);
            ExcelHeader excelHeader = field.getAnnotation(ExcelHeader.class);
            if ("律所名称".equals(excelHeader.value())) {
                firmNameColIndex = i;
            } else if ("律师事务所收款账号".equals(excelHeader.value())) {
                paymentAccountColIndex = i;
            }
        }

        // 合并律所名称列
        if (firmNameColIndex >= 0) {
            for (Map.Entry<String, Integer> entry : firmNameRowMap.entrySet()) {
                String firmName = entry.getKey();
                int firstRow = entry.getValue();
                int rowCount = firmNameCountMap.get(firmName);
                if (rowCount > 1) {
                    sheet.addMergedRegion(new CellRangeAddress(firstRow, firstRow + rowCount - 1, firmNameColIndex, firmNameColIndex));
                }
            }
        }

        // 合并其他列（除了账号列）
        for (int i = 0; i < excelFields.size(); i++) {
            if (i == firmNameColIndex || i == paymentAccountColIndex) {
                continue;
            }
            for (Map.Entry<String, Integer> entry : firmNameRowMap.entrySet()) {
                String firmName = entry.getKey();
                int firstRow = entry.getValue();
                int rowCount = firmNameCountMap.get(firmName);
                if (rowCount > 1) {
                    sheet.addMergedRegion(new CellRangeAddress(firstRow, firstRow + rowCount - 1, i, i));
                }
            }
        }

        // 设置列宽
        for (int i = 0; i < excelFields.size(); i++) {
            sheet.setColumnWidth(i, 20 * 256);
        }

        // 设置响应头
        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");

        // 输出（不要关闭 response 的输出流，由容器管理）
        OutputStream outputStream = response.getOutputStream();
        workbook.write(outputStream);
        outputStream.flush();
        workbook.close();
    }

    /**
     * 转换为ExcelVo
     */
    private LawFirmExcelVo convertToExcelVo(LawFirm lawFirm, int serialNumber,
                                           SimpleDateFormat dateFormat, SimpleDateFormat dateTimeFormat) {
        LawFirmExcelVo excelVo = new LawFirmExcelVo();
        BeanUtils.copyProperties(lawFirm, excelVo);
        excelVo.setSerialNumber(serialNumber);

        // 格式化日期
        if (lawFirm.getEstablishmentDate() != null) {
            excelVo.setEstablishmentDate(dateFormat.format(lawFirm.getEstablishmentDate()));
        }

        // 格式化类型
        if (lawFirm.getFirmType() != null) {
            switch (lawFirm.getFirmType()) {
                case 1:
                    excelVo.setFirmType("合伙制");
                    break;
                case 2:
                    excelVo.setFirmType("个人制");
                    break;
                case 3:
                    excelVo.setFirmType("国资制");
                    break;
            }
        }

        // 格式化规模
        if (lawFirm.getFirmScale() != null) {
            switch (lawFirm.getFirmScale()) {
                case 1:
                    excelVo.setFirmScale("小型(1-10人)");
                    break;
                case 2:
                    excelVo.setFirmScale("中型(11-50人)");
                    break;
                case 3:
                    excelVo.setFirmScale("大型(51-200人)");
                    break;
                case 4:
                    excelVo.setFirmScale("超大型(200人以上)");
                    break;
            }
        }

        // 格式化状态
        if (lawFirm.getStatus() != null) {
            excelVo.setStatus(lawFirm.getStatus() == 1 ? "启用" : "禁用");
        }

        // 格式化认证状态
        if (lawFirm.getCertificationStatus() != null) {
            switch (lawFirm.getCertificationStatus()) {
                case 0:
                    excelVo.setCertificationStatus("未认证");
                    break;
                case 1:
                    excelVo.setCertificationStatus("认证中");
                    break;
                case 2:
                    excelVo.setCertificationStatus("已认证");
                    break;
                case 3:
                    excelVo.setCertificationStatus("认证失败");
                    break;
            }
        }

        // 格式化佣金比例
        if (lawFirm.getPlatformCommissionRatio() != null) {
            excelVo.setPlatformCommissionRatio(lawFirm.getPlatformCommissionRatio().toString() + "%");
        }

        return excelVo;
    }

    /**
     * 校验Excel数据
     */
    private String validateExcelData(LawFirmExcelVo excelVo, int rowIndex) {
        if (!StringUtils.hasText(excelVo.getFirmName())) {
            return "第" + rowIndex + "行：律所名称不能为空";
        }
        if (!StringUtils.hasText(excelVo.getCreditCode())) {
            return "第" + rowIndex + "行：统一社会信用代码不能为空";
        }
//        if (!StringUtils.hasText(excelVo.getPhone())) {
//            return "第" + rowIndex + "行：联系电话不能为空";
//        }
        if (!StringUtils.hasText(excelVo.getDirectorName())) {
            return "第" + rowIndex + "行：负责人姓名不能为空";
        }
//        if (!StringUtils.hasText(excelVo.getDirectorPhone())) {
//            return "第" + rowIndex + "行：负责人电话不能为空";
//        }

        // 校验收款账号（不允许逗号分隔，必须是单个16位或19位账号）
        if (StringUtils.hasText(excelVo.getPaymentAccount())) {
            String paymentAccount = excelVo.getPaymentAccount().trim();
            // 不允许包含逗号
            if (paymentAccount.contains(",")) {
                return "第" + rowIndex + "行：收款账号不允许包含逗号，每行只能填写一个账号";
            }
            // 校验长度（必须是16位或19位）
            int length = paymentAccount.length();
            if (length != 16 && length != 19) {
                return "第" + rowIndex + "行：收款账号[" + paymentAccount + "]长度不正确，必须是16位或19位，当前为" + length + "位";
            }
        }

        // 校验邮箱格式
//        if (StringUtils.hasText(excelVo.getEmail())) {
//            if (!excelVo.getEmail().matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")) {
//                return "第" + rowIndex + "行：邮箱格式不正确";
//            }
//        }
//        if (StringUtils.hasText(excelVo.getDirectorEmail())) {
//            if (!excelVo.getDirectorEmail().matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")) {
//                return "第" + rowIndex + "行：负责人邮箱格式不正确";
//            }
//        }

        return null;
    }

    /**
     * 转换为LawFirm实体
     */
    private LawFirm convertToLawFirm(LawFirmExcelVo excelVo) {
        LawFirm lawFirm = new LawFirm();
        BeanUtils.copyProperties(excelVo, lawFirm);

        // 解析类型
        if (StringUtils.hasText(excelVo.getFirmType())) {
            switch (excelVo.getFirmType()) {
                case "合伙制":
                    lawFirm.setFirmType(1);
                    break;
                case "个人制":
                    lawFirm.setFirmType(2);
                    break;
                case "国资制":
                    lawFirm.setFirmType(3);
                    break;
            }
        }

        // 解析规模
        if (StringUtils.hasText(excelVo.getFirmScale())) {
            if (excelVo.getFirmScale().contains("小型")) {
                lawFirm.setFirmScale(1);
            } else if (excelVo.getFirmScale().contains("中型")) {
                lawFirm.setFirmScale(2);
            } else if (excelVo.getFirmScale().contains("大型") && !excelVo.getFirmScale().contains("超大型")) {
                lawFirm.setFirmScale(3);
            } else if (excelVo.getFirmScale().contains("超大型")) {
                lawFirm.setFirmScale(4);
            }
        }

        // 解析状态
        if (StringUtils.hasText(excelVo.getStatus())) {
            lawFirm.setStatus("启用".equals(excelVo.getStatus()) ? 1 : 0);
        }

        // 解析认证状态
        if (StringUtils.hasText(excelVo.getCertificationStatus())) {
            switch (excelVo.getCertificationStatus()) {
                case "未认证":
                    lawFirm.setCertificationStatus(0);
                    break;
                case "认证中":
                    lawFirm.setCertificationStatus(1);
                    break;
                case "已认证":
                    lawFirm.setCertificationStatus(2);
                    break;
                case "认证失败":
                    lawFirm.setCertificationStatus(3);
                    break;
            }
        }

        // 解析日期
        if (StringUtils.hasText(excelVo.getEstablishmentDate())) {
            try {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                lawFirm.setEstablishmentDate(dateFormat.parse(excelVo.getEstablishmentDate()));
            } catch (Exception e) {
                log.warn("解析成立日期失败：{}", excelVo.getEstablishmentDate());
            }
        }

        return lawFirm;
    }

    /**
     * 获取单元格值作为字符串
     */
    private String getCellValueAsString(Cell cell) {
        if (cell == null) {
            return null;
        }
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
                } else {
                    double numericValue = cell.getNumericCellValue();
                    // 如果是整数，返回整数格式
                    if (numericValue == (long) numericValue) {
                        return String.valueOf((long) numericValue);
                    } else {
                        return String.valueOf(numericValue);
                    }
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return null;
        }
    }

    @Override
    public R<LawFirm> getLawFirmDetail(Integer id) {
        log.info("LawFirmServiceImpl.getLawFirmDetail?id={}", id);

        if (id == null) {
            return R.fail("律所ID不能为空");
        }

        // 使用 MyBatis-Plus 的 getById 方法获取律所详情
        LawFirm lawFirm = this.getById(id);

        if (lawFirm == null) {
            return R.fail("律所不存在");
        }

        // 检查是否已删除
        if (lawFirm.getDeleteFlag() != null && lawFirm.getDeleteFlag() == 1) {
            return R.fail("律所已被删除");
        }

        // 查询收款账号列表
        LambdaQueryWrapper<LawFirmPayment> paymentWrapper = new LambdaQueryWrapper<>();
        paymentWrapper.eq(LawFirmPayment::getFirmId, id);
        paymentWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
        List<LawFirmPayment> paymentList = lawFirmPaymentService.list(paymentWrapper);
        lawFirm.setPaymentList(paymentList);

        return R.data(lawFirm, "查询成功");
    }

    @Override
    public void downloadTemplate(HttpServletResponse response) throws IOException {
        log.info("LawFirmServiceImpl.downloadTemplate");
        
        XSSFWorkbook workbook = new XSSFWorkbook();
        try {
            Sheet sheet = workbook.createSheet("律所导入模板");

            // 获取带有 @ExcelHeader 注解的字段
            Field[] fields = LawFirmExcelVo.class.getDeclaredFields();
            List<Field> excelFields = Arrays.stream(fields)
                    .filter(f -> f.isAnnotationPresent(ExcelHeader.class))
                    .collect(Collectors.toList());

            // 创建表头样式
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            CellStyle headerCellStyle = workbook.createCellStyle();
            headerCellStyle.setFont(headerFont);
            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            // 创建表头
            Row headerRow = sheet.createRow(0);
            for (int i = 0; i < excelFields.size(); i++) {
                Field field = excelFields.get(i);
                ExcelHeader excelHeader = field.getAnnotation(ExcelHeader.class);
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(excelHeader.value());
                cell.setCellStyle(headerCellStyle);
            }

            // 设置列宽
            for (int i = 0; i < excelFields.size(); i++) {
                sheet.setColumnWidth(i, 20 * 256);
            }

            // 设置响应头（必须在获取输出流之前设置）
            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");

            // 输出到响应流
            OutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
        } finally {
            // 确保 workbook 被正确关闭
            if (workbook != null) {
                workbook.close();
            }
        }
    }

    /**
     * 批量填充律所的收款账号列表
     *
     * @param lawFirmList 律所列表
     */
    @Override
    public void fillPaymentList(List<LawFirm> lawFirmList) {
        if (lawFirmList == null || lawFirmList.isEmpty()) {
            return;
        }

        // 收集所有律所ID
        List<Integer> firmIds = lawFirmList.stream()
                .map(LawFirm::getId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        if (firmIds.isEmpty()) {
            return;
        }

        // 批量查询所有收款账号
        LambdaQueryWrapper<LawFirmPayment> paymentWrapper = new LambdaQueryWrapper<>();
        paymentWrapper.in(LawFirmPayment::getFirmId, firmIds);
        paymentWrapper.eq(LawFirmPayment::getDeleteFlag, 0);
        List<LawFirmPayment> allPayments = lawFirmPaymentService.list(paymentWrapper);

        // 按律所ID分组
        Map<Integer, List<LawFirmPayment>> paymentMap = allPayments.stream()
                .collect(Collectors.groupingBy(LawFirmPayment::getFirmId));

        // 为每个律所设置收款账号列表
        lawFirmList.forEach(lawFirm -> {
            List<LawFirmPayment> paymentList = paymentMap.getOrDefault(lawFirm.getId(), Collections.emptyList());
            lawFirm.setPaymentList(paymentList);
        });
    }

    @Override
    public R<IPage<LawFirmPaymentVO>> getPaymentPageWithFirm(
            int pageNum, int pageSize,
            Integer firmId, String paymentAccount, String firmName, String creditCode,
            Integer status, Integer certificationStatus, String directorName,
            String createdTimeStart, String createdTimeEnd) {
        log.info("LawFirmServiceImpl.getPaymentPageWithFirm?pageNum={},pageSize={},firmId={},paymentAccount={},firmName={},creditCode={},status={},certificationStatus={},directorName={},createdTimeStart={},createdTimeEnd={}",
                pageNum, pageSize, firmId, paymentAccount, firmName, creditCode, status, certificationStatus, directorName, createdTimeStart, createdTimeEnd);
        
        Page<LawFirmPaymentVO> page = new Page<>(pageNum, pageSize);
        IPage<LawFirmPaymentVO> pageResult = lawFirmPaymentMapper.selectPaymentPageWithFirm(
                page, firmId, paymentAccount, firmName, creditCode, status, certificationStatus, directorName, createdTimeStart, createdTimeEnd
        );
        return R.data(pageResult);
    }
}


