package shop.alien.store.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.commons.lang.math.RandomUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import shop.alien.entity.result.R;
import shop.alien.entity.store.*;
import shop.alien.entity.store.dto.LawyerConsultationOrderDto;
import shop.alien.entity.store.dto.PayStatusRequest;
import shop.alien.entity.store.excelVo.LawyerConsultationOrderExcelVo;
import shop.alien.entity.store.vo.LawyerConsultationOrderVO;
import shop.alien.mapper.*;
import shop.alien.store.service.LawyerConsultationOrderService;
import shop.alien.store.service.LawyerUserService;
import shop.alien.store.service.OrderExpirationService;
import shop.alien.store.util.ali.AliApi;
import shop.alien.util.common.constant.LawyerStatusEnum;
import shop.alien.util.excel.EasyExcelUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 咨询订单 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Transactional
@Service
@RequiredArgsConstructor
public class LawyerConsultationOrderServiceImpl extends ServiceImpl<LawyerConsultationOrderMapper, LawyerConsultationOrder> implements LawyerConsultationOrderService {

    private final LawyerConsultationOrderMapper consultationOrderMapper;
    private final LawyerUserService lawyerUserService;
    private final LawyerServiceAreaMapper lawyerServiceAreaMapper;
    private final LawyerUserMapper lawyerUserMapper;
    private final LawyerExpertiseAreaMapper lawyerExpertiseAreaMapper;
    private final OrderExpirationService orderExpirationService;
    private final AliApi aliApi;
    private final LawFirmMapper lawFirmMapper;

    @Override
    public R<IPage<LawyerConsultationOrderVO>> getConsultationOrderList(int pageNum, int pageSize, String orderNumber,
                                                                 Integer clientUserId, Integer lawyerUserId, String lawyerName, Integer orderStatus) {
        log.info("LawyerConsultationOrderServiceImpl.getConsultationOrderList?pageNum={},pageSize={},orderNumber={},clientUserId={},lawyerUserId={},lawyerName={},orderStatus={}",
                pageNum, pageSize, orderNumber, clientUserId, lawyerUserId, lawyerName, orderStatus);
        
        // 創建分頁對象
        Page<LawyerConsultationOrderVO> page = new Page<>(pageNum, pageSize);
        
        // 如果按律師姓名搜索，先查詢匹配的律師ID列表
        List<Integer> lawyerUserIds = null;
        if (StringUtils.hasText(lawyerName)) {
            LambdaQueryWrapper<LawyerUser> lawyerQueryWrapper = new LambdaQueryWrapper<>();
            lawyerQueryWrapper.eq(LawyerUser::getDeleteFlag, 0);
            lawyerQueryWrapper.like(LawyerUser::getName, lawyerName);
            List<LawyerUser> lawyerUsers = lawyerUserService.list(lawyerQueryWrapper);
            if (lawyerUsers != null && !lawyerUsers.isEmpty()) {
                lawyerUserIds = lawyerUsers.stream()
                        .map(LawyerUser::getId)
                        .collect(Collectors.toList());
            } else {
                // 如果沒有找到匹配的律師，返回空結果
                Page<LawyerConsultationOrderVO> emptyPage = new Page<>(pageNum, pageSize);
                emptyPage.setRecords(Collections.emptyList());
                emptyPage.setTotal(0);
                return R.data(emptyPage);
            }
        }
        
        // 使用JOIN查詢，直接聯查律師信息
        IPage<LawyerConsultationOrderVO> voPage = consultationOrderMapper.getConsultationOrderListWithLawyer(
                page, orderNumber, clientUserId, lawyerUserId, lawyerName, orderStatus, lawyerUserIds);

        // 為待支付訂單計算倒計時（30分鐘有效期）
        if (voPage != null && voPage.getRecords() != null) {
            Date now = new Date();
            long validitySeconds = 30 * 60; // 30分鐘 = 1800秒
            
            for (LawyerConsultationOrderVO vo : voPage.getRecords()) {
                // 僅對待支付訂單（orderStatus=0）計算倒計時
                if (vo.getOrderStatus() != null && vo.getOrderStatus() == 0) {
                    Date orderTime = vo.getOrderTime();
                    if (orderTime != null) {
                        long elapsedSeconds = (now.getTime() - orderTime.getTime()) / 1000;
                        long remainingSeconds = validitySeconds - elapsedSeconds;
                        // 如果已過期，設置為0
                        vo.setCountdownSeconds(Math.max(0, remainingSeconds));
                    } else {
                        vo.setCountdownSeconds(0L);
                    }
                } else {
                    // 非待支付訂單，倒計時為null
                    vo.setCountdownSeconds(null);
                }
            }
        }

        return R.data(voPage);
    }

    /**
     * 將訂單分頁結果轉換為VO並填充律師信息
     */
    private IPage<LawyerConsultationOrderVO> convertToVO(IPage<LawyerConsultationOrder> pageResult) {
        // 創建VO分頁對象
        Page<LawyerConsultationOrderVO> voPage = new Page<>(pageResult.getCurrent(), pageResult.getSize(), pageResult.getTotal());

        List<LawyerConsultationOrder> records = pageResult.getRecords();
        if (records == null || records.isEmpty()) {
            voPage.setRecords(Collections.emptyList());
            return voPage;
        }

        // 收集所有律師ID
        Set<Integer> lawyerUserIds = records.stream()
                .map(LawyerConsultationOrder::getLawyerUserId)
                .filter(id -> id != null)
                .collect(Collectors.toSet());

        // 批量查詢律師信息
        Map<Integer, LawyerUser> lawyerMap = new HashMap<>();
        if (!lawyerUserIds.isEmpty()) {
            LambdaQueryWrapper<LawyerUser> lawyerWrapper = new LambdaQueryWrapper<>();
            lawyerWrapper.in(LawyerUser::getId, lawyerUserIds);
            lawyerWrapper.eq(LawyerUser::getDeleteFlag, 0);
            List<LawyerUser> lawyerUsers = lawyerUserService.list(lawyerWrapper);
            if (lawyerUsers != null && !lawyerUsers.isEmpty()) {
                lawyerMap = lawyerUsers.stream()
                        .collect(Collectors.toMap(LawyerUser::getId, lawyer -> lawyer, (k1, k2) -> k1));
            }
        }

        // 批量查询律所信息
        Map<Integer, LawFirm> lawFirmMap = new HashMap<>();
        if (lawyerMap != null && !lawyerMap.isEmpty()) {
            Set<Integer> firmIds = lawyerMap.values().stream()
                    .map(LawyerUser::getFirmId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            if (!firmIds.isEmpty()) {
                List<LawFirm> lawFirms = lawFirmMapper.selectBatchIds(firmIds);
                if (lawFirms != null) {
                    lawFirmMap = lawFirms.stream()
                            .filter(firm -> firm.getDeleteFlag() == null || firm.getDeleteFlag() == 0)
                            .collect(Collectors.toMap(LawFirm::getId, firm -> firm, (k1, k2) -> k1));
                }
            }
        }

        // 轉換為VO並填充律師信息
        final Map<Integer, LawyerUser> finalLawyerMap = lawyerMap;
        final Map<Integer, LawFirm> finalLawFirmMap = lawFirmMap;
        List<LawyerConsultationOrderVO> voList = records.stream()
                .map(order -> {
                    LawyerConsultationOrderVO vo = new LawyerConsultationOrderVO();
                    // 複製訂單基本信息
                    BeanUtils.copyProperties(order, vo);

                    // 填充律師信息
                    LawyerUser lawyer = finalLawyerMap.get(order.getLawyerUserId());
                    if (lawyer != null) {
                        vo.setLawyerName(lawyer.getName());
                        vo.setLawyerPhone(lawyer.getPhone());
                        vo.setLawyerEmail(lawyer.getEmail());
                        vo.setLawyerCertificateNo(lawyer.getLawyerCertificateNo());
                        // 通过firm_id查询律所名称
                        if (lawyer.getFirmId() != null) {
                            LawFirm lawFirm = finalLawFirmMap.get(lawyer.getFirmId());
                            vo.setLawFirm(lawFirm != null ? lawFirm.getFirmName() : null);
                        } else {
                            vo.setLawFirm(null);
                        }
                        vo.setPracticeYears(lawyer.getPracticeYears());
                        vo.setSpecialtyFields(lawyer.getSpecialtyFields());
                        vo.setCertificationStatus(lawyer.getCertificationStatus());
                        vo.setServiceScore(lawyer.getServiceScore());
                        vo.setServiceCount(lawyer.getServiceCount());
                        vo.setLawyerConsultationFee(lawyer.getConsultationFee());
                        vo.setProvince(lawyer.getProvince());
                        vo.setCity(lawyer.getCity());
                        vo.setDistrict(lawyer.getDistrict());
                        vo.setAddress(lawyer.getAddress());
                        vo.setHeadImg(lawyer.getHeadImg());
                        vo.setNickName(lawyer.getNickName());
                        vo.setPersonalIntroduction(lawyer.getPersonalIntroduction());
                    }

                    return vo;
                })
                .collect(Collectors.toList());

        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public R<LawyerConsultationOrder> addConsultationOrder(LawyerConsultationOrder consultationOrder) {
        log.info("LawyerConsultationOrderServiceImpl.addConsultationOrder?consultationOrder={}", consultationOrder);
        boolean result = this.save(consultationOrder);
        if (result) {
            return R.data(consultationOrder);
        }
        return R.fail("新增失败");
    }

    /**
     * 编辑咨询订单
     * <p>
     * 编辑前会进行以下校验：
     * 1. 参数校验：订单ID不能为空
     * 2. 订单存在性校验：订单必须存在
     * 3. 订单状态校验：已完成的订单不允许修改关键信息
     * </p>
     *
     * @param consultationOrder 咨询订单
     * @return 编辑结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<LawyerConsultationOrder> editConsultationOrder(LawyerConsultationOrder consultationOrder) {
        Integer orderId = consultationOrder.getId();
        log.info("开始编辑咨询订单，订单ID={}", orderId);
        
        // 参数校验：订单ID不能为空
        if (orderId == null) {
            log.warn("编辑咨询订单失败：订单ID为空");
            return R.fail("订单ID不能为空");
        }
        
        // 查询订单信息，验证订单是否存在
        LawyerConsultationOrder existingOrder = consultationOrderMapper.selectById(orderId);
        if (existingOrder == null) {
            log.warn("编辑咨询订单失败：订单不存在，订单ID={}", orderId);
            return R.fail("订单不存在");
        }
        
        // 记录修改前的订单状态
        Integer oldOrderStatus = existingOrder.getOrderStatus();
        Integer oldPaymentStatus = existingOrder.getPaymentStatus();
        Integer newOrderStatus = consultationOrder.getOrderStatus();
        Integer newPaymentStatus = consultationOrder.getPaymentStatus();
        
        log.info("编辑咨询订单，订单ID={}, 订单编号={}, 原订单状态={}, 新订单状态={}, 原支付状态={}, 新支付状态={}", 
                orderId, existingOrder.getOrderNumber(), oldOrderStatus, newOrderStatus, 
                oldPaymentStatus, newPaymentStatus);
        
        // 订单状态校验：已完成的订单不允许修改关键信息（订单状态、支付状态、订单金额等）
        Integer completedStatus = LawyerStatusEnum.COMPLETE.getStatus(); // 3:已完成
        if (completedStatus.equals(oldOrderStatus)) {
            // 如果订单已完成，只允许修改评价相关字段（rating, comment）
            if (newOrderStatus != null && !newOrderStatus.equals(oldOrderStatus)) {
                log.warn("编辑咨询订单失败：订单已完成，不允许修改订单状态，订单ID={}, 订单编号={}", 
                        orderId, existingOrder.getOrderNumber());
                return R.fail("订单已完成，不允许修改订单状态");
            }
            if (newPaymentStatus != null && !newPaymentStatus.equals(oldPaymentStatus)) {
                log.warn("编辑咨询订单失败：订单已完成，不允许修改支付状态，订单ID={}, 订单编号={}", 
                        orderId, existingOrder.getOrderNumber());
                return R.fail("订单已完成，不允许修改支付状态");
            }
            if (consultationOrder.getOrderAmount() != null && 
                !consultationOrder.getOrderAmount().equals(existingOrder.getOrderAmount())) {
                log.warn("编辑咨询订单失败：订单已完成，不允许修改订单金额，订单ID={}, 订单编号={}", 
                        orderId, existingOrder.getOrderNumber());
                return R.fail("订单已完成，不允许修改订单金额");
            }
        }
        
        // 已取消的订单不允许修改为其他状态（除非是管理员操作，这里暂不限制）
        Integer cancelStatus = LawyerStatusEnum.CANCEL.getStatus(); // 4:已取消
        if (cancelStatus.equals(oldOrderStatus) && newOrderStatus != null && 
            !cancelStatus.equals(newOrderStatus)) {
            log.warn("编辑咨询订单警告：订单已取消，尝试修改订单状态，订单ID={}, 订单编号={}, 原状态={}, 新状态={}", 
                    orderId, existingOrder.getOrderNumber(), oldOrderStatus, newOrderStatus);
            // 这里可以根据业务需求决定是否允许，暂时允许修改
        }
        
        // 如果订单状态从待支付变为已支付，需要更新支付时间
        Integer waitPayStatus = LawyerStatusEnum.WAIT_PAY.getStatus(); // 0:待支付
        if (waitPayStatus.equals(oldOrderStatus) && newOrderStatus != null && 
            !waitPayStatus.equals(newOrderStatus) && newPaymentStatus != null && newPaymentStatus == 1) {
            if (consultationOrder.getPaymentTime() == null) {
                consultationOrder.setPaymentTime(new Date());
                log.info("订单状态从待支付变为已支付，自动设置支付时间，订单ID={}, 订单编号={}", 
                        orderId, existingOrder.getOrderNumber());
            }
        }
        
        // 设置更新时间
        consultationOrder.setUpdatedTime(new Date());
        
        // 执行更新操作
        boolean result = this.updateById(consultationOrder);
        if (result) {
            log.info("编辑咨询订单成功，订单ID={}, 订单编号={}, 原订单状态={}, 新订单状态={}", 
                    orderId, existingOrder.getOrderNumber(), oldOrderStatus, newOrderStatus);
            // 重新查询更新后的订单信息
            LawyerConsultationOrder updatedOrder = consultationOrderMapper.selectById(orderId);
            return R.data(updatedOrder != null ? updatedOrder : consultationOrder);
        } else {
            log.error("编辑咨询订单失败：数据库更新失败，订单ID={}, 订单编号={}", 
                    orderId, existingOrder.getOrderNumber());
            return R.fail("修改失败");
        }
    }

    /**
     * 删除咨询订单
     * <p>
     * 删除前会进行以下校验：
     * 1. 参数校验：订单ID不能为空
     * 2. 订单存在性校验：订单必须存在
     * 3. 订单状态校验：进行中的订单不允许删除
     * 4. 如果订单是待支付状态，会取消Redis中的支付超时计时器
     * </p>
     *
     * @param id 订单ID
     * @return 删除结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> deleteConsultationOrder(Integer id) {
        log.info("开始删除咨询订单，订单ID={}", id);
        
        // 参数校验
        if (id == null) {
            log.warn("删除咨询订单失败：订单ID为空");
            return R.fail("订单ID不能为空");
        }
        
        // 查询订单信息
        LawyerConsultationOrder order = consultationOrderMapper.selectById(id);
        if (order == null) {
            log.warn("删除咨询订单失败：订单不存在，订单ID={}", id);
            return R.fail("订单不存在");
        }
        
        // 检查订单状态：进行中的订单不允许删除
        Integer orderStatus = order.getOrderStatus();
        Integer inProgressStatus = LawyerStatusEnum.INPROGRESS.getStatus(); // 2:进行中
        if (inProgressStatus.equals(orderStatus)) {
            log.warn("删除咨询订单失败：订单进行中，不允许删除，订单ID={}, 订单编号={}", 
                    id, order.getOrderNumber());
            return R.fail("订单进行中，不允许删除");
        }
        
        // 如果订单是待支付状态，取消Redis中的订单支付超时计时
        Integer waitPayStatus = LawyerStatusEnum.WAIT_PAY.getStatus(); // 0:待支付
        if (waitPayStatus.equals(orderStatus) && order.getOrderNumber() != null) {
            try {
                orderExpirationService.cancelOrderPaymentTimeout(order.getOrderNumber());
                log.info("已取消订单支付超时计时，订单编号={}", order.getOrderNumber());
            } catch (Exception e) {
                log.error("取消订单支付超时计时失败，订单编号={}", order.getOrderNumber(), e);
                // 继续执行删除操作，不因取消计时器失败而中断
            }
        }
        
        // 执行删除操作
        boolean result = this.removeById(id);
        if (result) {
            log.info("删除咨询订单成功，订单ID={}, 订单编号={}", id, order.getOrderNumber());
            return R.data(true, "删除成功");
        } else {
            log.error("删除咨询订单失败：数据库操作失败，订单ID={}, 订单编号={}", id, order.getOrderNumber());
            return R.fail("删除失败");
        }
    }

    /*@Override
    public R<Map<String, Object>> startConsultation(Integer lawyerId, String question, String sessionId, Integer clientUserId, Integer problemScenarioId) {
        log.info("LawyerConsultationOrderServiceImpl.startConsultation?lawyerId={},question={},sessionId={},clientUserId={},problemScenarioId={}",
                lawyerId, question, sessionId, clientUserId, problemScenarioId);

        // 创建咨询订单
        LawyerConsultationOrder order = new LawyerConsultationOrder();
        order.setLawyerUserId(lawyerId);
        order.setClientUserId(clientUserId);
        order.setProblemScenarioId(problemScenarioId);
        order.setProblemDescription(question);
        order.setOrderStatus(0);  // 待支付
        order.setPaymentStatus(0);  // 未支付

        boolean saved = this.save(order);
        if (!saved) {
            return R.fail("创建咨询订单失败");
        }

        Map<String, Object> result = new HashMap<>();
        result.put("consultationId", order.getId());
        result.put("lawyerId", lawyerId);
        result.put("status", "pending");  // pending(待响应), active(进行中), closed(已结束)
        result.put("createTime", order.getCreatedTime() != null ?
                new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(order.getCreatedTime()) : "");

        return R.data(result);
    }*/


    /**
     * 立即咨询创建订单
     * <p>
     * 创建咨询订单前会进行以下处理：
     * 1. 参数校验：客户端用户ID、律师用户ID、订单金额不能为空
     * 2. 生成订单编号：LAW + 年月日（8位） + 随机5位数字
     * 3. 计算本单收益：根据律所平台佣金比例计算咨询费用
     * 4. 设置订单初始状态：待支付、未支付
     * </p>
     *
     * @param lawyerConsultationOrder 咨询订单信息
     * @return 创建结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<LawyerConsultationOrderDto> consultNow(LawyerConsultationOrder lawyerConsultationOrder) {
        log.info("LawyerConsultationOrderServiceImpl.consultNow?lawyerConsultationOrder={}", lawyerConsultationOrder);

        // 参数校验
        if (lawyerConsultationOrder == null) {
            log.warn("创建咨询订单失败：订单信息为空");
            return R.fail("订单信息不能为空");
        }

        Integer clientUserId = lawyerConsultationOrder.getClientUserId();
        Integer lawyerUserId = lawyerConsultationOrder.getLawyerUserId();
        Integer orderAmount = lawyerConsultationOrder.getOrderAmount();

        if (clientUserId == null || clientUserId <= 0) {
            log.warn("创建咨询订单失败：客户端用户ID无效，clientUserId={}", clientUserId);
            return R.fail("客户端用户ID不能为空");
        }

        if (lawyerUserId == null || lawyerUserId <= 0) {
            log.warn("创建咨询订单失败：律师用户ID无效，lawyerUserId={}", lawyerUserId);
            return R.fail("律师用户ID不能为空");
        }

        if (orderAmount == null || orderAmount <= 0) {
            log.warn("创建咨询订单失败：订单金额无效，orderAmount={}", orderAmount);
            return R.fail("订单金额不能为空且必须大于0");
        }

        // 创建订单DTO对象
        LawyerConsultationOrderDto order = new LawyerConsultationOrderDto();
        Date now = new Date();

        // 设置订单基本信息
        order.setClientUserId(clientUserId);
        order.setLawyerUserId(lawyerUserId);
        order.setProblemScenarioId(lawyerConsultationOrder.getProblemScenarioId());
        order.setProblemDescription(lawyerConsultationOrder.getProblemDescription());
        order.setOrderAmount(orderAmount);
        order.setAlipayNo(lawyerConsultationOrder.getAlipayNo());
        order.setOrderStr(lawyerConsultationOrder.getOrderStr());
        order.setPlaceId(lawyerConsultationOrder.getPlaceId());

        // 设置订单状态
        order.setOrderStatus(0); // 待支付
        order.setPaymentStatus(0); // 未支付
        order.setOrderTime(now);
        order.setCreatedTime(now);
        order.setUpdatedTime(now);
        order.setDeleteFlag(0);

        // 生成订单编号：LAW + 年月日（8位数字）+ 随机5位数字
        String orderNumber = generateOrderNumber();
        order.setOrderNumber(orderNumber);
        log.info("生成订单编号：orderNumber={}", orderNumber);

        // 计算本单收益（平台收益）
        Integer consultationFee = calculateConsultationFee(lawyerUserId, orderAmount);
        order.setConsultationFee(consultationFee);
        log.info("计算咨询费用：lawyerUserId={}, orderAmount={}, consultationFee={}", 
                lawyerUserId, orderAmount, consultationFee);

        // 计算律师收益（订单金额-平台收益）
        Integer lawyerEarnings =  orderAmount - consultationFee;
        order.setLawyerEarnings(lawyerEarnings);
        // 插入订单
        int insertCount = consultationOrderMapper.insertOrder(order);
        if (insertCount > 0) {
            log.info("创建咨询订单成功：orderNumber={}, orderId={}", orderNumber, order.getId());
            return R.data(order);
        } else {
            log.error("创建咨询订单失败：数据库插入失败，orderNumber={}", orderNumber);
            return R.fail("创建订单失败");
        }
    }

    /**
     * 生成订单编号
     * <p>
     * 格式：LAW + 年月日（8位数字）+ 随机5位数字
     * 示例：LAW2025011512345
     * </p>
     *
     * @return 订单编号
     */
    private String generateOrderNumber() {
        String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String randomStr = String.format("%05d", RandomUtils.nextInt(100000));
        return "LAW" + dateStr + randomStr;
    }

    /**
     * 计算咨询费用（本单收益）
     * <p>
     * 根据律所的平台佣金比例计算咨询费用
     * 如果律师没有关联律所或律所没有设置佣金比例，则使用默认佣金比例3%
     * </p>
     *
     * @param lawyerUserId 律师用户ID
     * @param orderAmount  订单金额（单位：分）
     * @return 咨询费用（单位：分）
     */
    private Integer calculateConsultationFee(Integer lawyerUserId, Integer orderAmount) {
        // 默认佣金比例：3%
        float defaultCommissionRate = 3.0F;
        float commissionRate = defaultCommissionRate;

        // 查询律师信息
        LawyerUser lawyerUser = lawyerUserMapper.selectById(lawyerUserId);
        if (lawyerUser != null) {
            // 获取律所信息
            Integer firmId = lawyerUser.getFirmId();
            if (firmId != null && firmId > 0) {
                LawFirm lawyerFirm = lawFirmMapper.selectById(firmId);
                if (lawyerFirm != null && lawyerFirm.getPlatformCommissionRatio() != null
                        && lawyerFirm.getPlatformCommissionRatio().floatValue() > 0) {
                    commissionRate = lawyerFirm.getPlatformCommissionRatio().floatValue();
                }
            }
        }

        // 计算咨询费用：订单金额 * 佣金比例 / 100，四舍五入
        int consultationFee = Math.round(orderAmount * commissionRate / 100);
        return consultationFee;
    }


    @Override
    public R<LawyerConsultationOrderDto> payStatus(PayStatusRequest request) {
        log.info("LawyerConsultationOrderServiceImpl.payStatus?orderNumber={},paymentStatus={},orderStatus={}",
                request.getOrderNumber(), request.getPaymentStatus(), request.getOrderStatus());

        LawyerConsultationOrderDto order = new LawyerConsultationOrderDto();

        if (null != request.getOrderStr()){
            order.setOrderStr(request.getOrderStr());
        }
        order.setOrderNumber(request.getOrderNumber());
        order.setPaymentStatus(request.getPaymentStatus());
        order.setOrderStatus(request.getOrderStatus());
        order.setUpdatedTime(new Date());
        order.setDeleteFlag(0);
        order.setPaymentTime(new Date());
        order.setStartTime(new Date());
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime validityDateTime = now.plusDays(7)
                .withHour(0)
                .withMinute(0)
                .withSecond(0)
                .withNano(0);
        order.setValidityPeriod(Date.from(validityDateTime.atZone(ZoneId.systemDefault()).toInstant()));
//        boolean result = this.updateById(order);
        Integer result = consultationOrderMapper.updateOrder(order);

        if (result>0) {
            return R.data(order);
        }
        return R.fail("失败");
    }

    /**
     * 根据用户ID查询订单列表（包含律师信息）
     *
     * @param pageNum    页码
     * @param pageSize   页容量
     * @param userId     用户ID
     * @param orderStatus 订单状态
     * @param lawyerName 律师姓名（支持模糊查询）
     * @return 分页订单列表
     */
    @Override
    public R<IPage<LawyerConsultationOrderVO>> getConsultationOrderListById(int pageNum, int pageSize, 
                                                                              String userId, String orderStatus, 
                                                                              String lawyerName) {
        Page<LawyerConsultationOrderVO> page = new Page<>(pageNum, pageSize);
        
        // 如果按律师姓名搜索，先查询匹配的律师ID列表
        List<Integer> lawyerUserIds = null;
        if (StringUtils.hasText(lawyerName)) {
            lawyerUserIds = queryLawyerIdsByName(lawyerName);
            // 如果没有找到匹配的律师，返回空结果
            if (CollectionUtils.isEmpty(lawyerUserIds)) {
                Page<LawyerConsultationOrderVO> emptyPage = new Page<>(pageNum, pageSize);
                emptyPage.setRecords(Collections.emptyList());
                emptyPage.setTotal(0);
                return R.data(emptyPage);
            }
        }

        // 查询订单列表
        IPage<LawyerConsultationOrderVO> voPage = consultationOrderMapper.getConsultationOrderListById(
                page, userId, orderStatus, lawyerUserIds);
        
        // 填充律师问题场景信息
        fillLawyerServiceArea(voPage);

        // 為待支付訂單計算倒計時（30分鐘有效期）
        if (voPage != null && voPage.getRecords() != null) {
            Date now = new Date();
            long validitySeconds = 30 * 60; // 30分鐘 = 1800秒

            for (LawyerConsultationOrderVO vo : voPage.getRecords()) {
                // 僅對待支付訂單（orderStatus=0）計算倒計時
                if (vo.getOrderStatus() != null && vo.getOrderStatus() == 0) {
                    Date orderTime = vo.getOrderTime();
                    if (orderTime != null) {
                        long elapsedSeconds = (now.getTime() - orderTime.getTime()) / 1000;
                        long remainingSeconds = validitySeconds - elapsedSeconds;
                        // 如果已過期，設置為0
                        vo.setCountdownSeconds(Math.max(0, remainingSeconds));
                    } else {
                        vo.setCountdownSeconds(0L);
                    }
                } else {
                    // 非待支付訂單，倒計時為null
                    vo.setCountdownSeconds(null);
                }
            }
        }
        
        return R.data(voPage);
    }

    /**
     * 根据律师姓名查询律师ID列表
     *
     * @param lawyerName 律师姓名
     * @return 律师ID列表
     */
    private List<Integer> queryLawyerIdsByName(String lawyerName) {
        LambdaQueryWrapper<LawyerUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LawyerUser::getDeleteFlag, 0)
                  .like(LawyerUser::getName, lawyerName);
        List<LawyerUser> lawyerUsers = lawyerUserService.list(queryWrapper);
        
        if (CollectionUtils.isEmpty(lawyerUsers)) {
            return Collections.emptyList();
        }
        
        return lawyerUsers.stream()
                .map(LawyerUser::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 填充律师服务领域信息到订单VO列表
     *
     * @param voPage 订单VO分页对象
     */
    private void fillLawyerServiceArea(IPage<LawyerConsultationOrderVO> voPage) {
        List<LawyerConsultationOrderVO> orderList = voPage.getRecords();
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        
        // 提取所有律师ID
        List<Integer> lawyerIdList = orderList.stream()
                .map(LawyerConsultationOrderVO::getLawyerUserId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        
        if (CollectionUtils.isEmpty(lawyerIdList)) {
            return;
        }
        
        // 批量查询律师问题场景
        Map<String, List<String>> serviceAreaMap = getLawyerServiceArea(lawyerIdList);
        if (serviceAreaMap.isEmpty()) {
            return;
        }
        
        // 填充问题场景
        orderList.forEach(order -> {
            Integer lawyerUserId = order.getLawyerUserId();
            if (lawyerUserId != null) {
                String lawyerUserIdStr = String.valueOf(lawyerUserId);
                List<String> serviceAreaList = serviceAreaMap.get(lawyerUserIdStr);
                if (CollectionUtils.isNotEmpty(serviceAreaList)) {
                    order.setLawyerLegalProblemScenarioList(serviceAreaList);
                }
            }
        });
    }

    /**
     * 批量查询律师问题场景
     *
     * @param lawyerIdList 律师ID列表
     * @return 律师问题场景Map，key为律师ID（String），value为问题场景名称列表
     */
    private Map<String, List<String>> getLawyerServiceArea(List<Integer> lawyerIdList) {
        Map<String, List<String>> serviceAreaMap = new HashMap<>();
        if (CollectionUtils.isEmpty(lawyerIdList)) {
            return serviceAreaMap;
        }
        
        QueryWrapper<LawyerServiceArea> wrapper = new QueryWrapper<>();
        wrapper.in("lsa.lawyer_user_id", lawyerIdList)
              .eq("lsa.delete_flag", 0)
              .eq("lsa.status", 1);
        
        List<Map<String, Object>> serviceAreaDataList = lawyerServiceAreaMapper.getLawyerLegalProblemScenarioList(wrapper);
        if (CollectionUtils.isEmpty(serviceAreaDataList)) {
            return serviceAreaMap;
        }
        
        for (Map<String, Object> row : serviceAreaDataList) {
            Object lawyerUserIdObj = row.get("lawyer_user_id");
            if (lawyerUserIdObj == null) {
                continue;
            }
            
            String lawyerUserId = String.valueOf(lawyerUserIdObj);
            String scenarioName = (String) row.get("name");
            String scenarioNameValue = StringUtils.hasText(scenarioName) ? scenarioName : "";
            
            serviceAreaMap.computeIfAbsent(lawyerUserId, k -> new ArrayList<>())
                         .add(scenarioNameValue);
        }
        
        return serviceAreaMap;
    }

    /**
     * 获取咨询订单详情
     *
     * @param lawyerOrderId 订单ID
     * @return 咨询订单详情VO
     */
    @Override
    public LawyerConsultationOrderVO getConsultationOrderDetail(String lawyerOrderId) {
        log.info("LawyerConsultationOrderServiceImpl.getConsultationOrderDetail?lawyerOrderId={}", lawyerOrderId);
        
        LawyerConsultationOrderVO orderVO = new LawyerConsultationOrderVO();
        
        // 参数校验
        if (!StringUtils.hasText(lawyerOrderId)) {
            return orderVO;
        }
        
        // 查询订单信息
        LawyerConsultationOrder order = consultationOrderMapper.selectById(lawyerOrderId);
        if (order == null) {
            return orderVO;
        }
        
        // 复制订单基本信息
        BeanUtils.copyProperties(order, orderVO);
        
        // 查询并填充律师信息
        Integer lawyerUserId = order.getLawyerUserId();
        if (lawyerUserId != null) {
            LawyerUser lawyerUser = lawyerUserMapper.selectById(lawyerUserId);
            if (lawyerUser != null) {
                fillLawyerInfo(orderVO, lawyerUser);
            }

            Integer serviceCount =consultationOrderMapper.selectCount(new QueryWrapper<LawyerConsultationOrder>().eq("lawyer_user_id", lawyerUserId).eq("order_status", 3).eq("delete_flag", 0));
            orderVO.setServiceCount(serviceCount);
            // 查询律师问题场景
            List<Integer> lawyerIdList = Collections.singletonList(lawyerUserId);
            Map<String, List<String>> serviceAreaMap = getLawyerServiceArea(lawyerIdList);
            String lawyerUserIdStr = String.valueOf(lawyerUserId);
            if (!serviceAreaMap.isEmpty() && serviceAreaMap.containsKey(lawyerUserIdStr)) {
                orderVO.setLawyerLegalProblemScenarioList(serviceAreaMap.get(lawyerUserIdStr));
            }
        }
        
        return orderVO;
    }

    /**
     * 取消律师咨询订单
     *
     * @param id 订单ID
     * @return 是否取消成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelOrder(String id) {
        // 参数校验
        if (!StringUtils.hasText(id)) {
            log.warn("取消订单失败：订单ID为空");
            return false;
        }

        // 查询订单信息
        LawyerConsultationOrder order = consultationOrderMapper.selectById(id);
        if (order == null) {
            log.warn("取消订单失败：订单不存在，订单ID={}", id);
            return false;
        }

        // 检查订单状态：已完成或已取消的订单不允许再次取消
        Integer orderStatus = order.getOrderStatus();
        Integer cancelStatus = LawyerStatusEnum.CANCEL.getStatus();
        if (cancelStatus.equals(orderStatus)) {
            log.warn("取消订单失败：订单已取消，订单ID={}, 订单编号={}", id, order.getOrderNumber());
            return false;
        }

        // 如果订单已完成，不允许取消
        Integer completedStatus = LawyerStatusEnum.COMPLETE.getStatus(); // 3:已完成
        if (completedStatus.equals(orderStatus)) {
            log.warn("取消订单失败：订单已完成，不允许取消，订单ID={}, 订单编号={}", id, order.getOrderNumber());
            return false;
        }

        // 如果订单是待支付状态，取消Redis中的订单支付超时计时
        Integer waitPayStatus = LawyerStatusEnum.WAIT_PAY.getStatus(); // 0:待支付
        if (waitPayStatus.equals(orderStatus) && order.getOrderNumber() != null) {
            orderExpirationService.cancelOrderPaymentTimeout(order.getOrderNumber());
            log.info("已取消订单支付超时计时，订单编号={}", order.getOrderNumber());
        }

        // 更新订单状态为已取消
        LambdaUpdateWrapper<LawyerConsultationOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(LawyerConsultationOrder::getId, id)
                .set(LawyerConsultationOrder::getOrderStatus, cancelStatus)
                .set(LawyerConsultationOrder::getUpdatedTime, new Date());

        int updateCount = consultationOrderMapper.update(null, updateWrapper);
        boolean success = updateCount > 0;

        if (success) {
            log.info("取消订单成功，订单ID={}, 订单编号={}, 原状态={}", id, order.getOrderNumber(), orderStatus);
        } else {
            log.error("取消订单失败：更新数据库失败，订单ID={}, 订单编号={}", id, order.getOrderNumber());
        }

        return success;
    }

    @Override
    public R<IPage<LawyerConsultationOrderVO>> getLawyerConsultationOrderList(int pageNum, int pageSize, String startDate, String endDate, String lawyerId) {
        Page<LawyerConsultationOrderVO> page = new Page<>(pageNum, pageSize);

        // 如果按律师姓名搜索，先查询匹配的律师ID列表
        if (!StringUtils.hasText(lawyerId)) {
            Page<LawyerConsultationOrderVO> emptyPage = new Page<>(pageNum, pageSize);
            emptyPage.setRecords(Collections.emptyList());
            emptyPage.setTotal(0);
            return R.data(emptyPage);
        }

        // 查询订单列表
        QueryWrapper<LawyerConsultationOrderVO> lawyerConsultationOrderQueryWrapper = new QueryWrapper<>();
        lawyerConsultationOrderQueryWrapper.in("lco.order_status", Arrays.asList("2", "3"));
        lawyerConsultationOrderQueryWrapper.eq("lco.lawyer_user_id", lawyerId);
        if(StringUtils.hasText(startDate) && StringUtils.hasText(startDate)){
            lawyerConsultationOrderQueryWrapper.between("lco.payment_time", startDate + " 00:00:00", endDate + " 23:59:59");
        }
        lawyerConsultationOrderQueryWrapper.eq("lco.delete_flag", 0);
        IPage<LawyerConsultationOrderVO> voPage = consultationOrderMapper.getLawyerConsultationOrderList(
                page, lawyerConsultationOrderQueryWrapper);

        // 填充律师问题场景信息
        fillLawyerServiceArea(voPage);

        // 為待支付訂單計算倒計時（30分鐘有效期）
        if (voPage != null && voPage.getRecords() != null) {
            Date now = new Date();
            long validitySeconds = 30 * 60; // 30分鐘 = 1800秒

            for (LawyerConsultationOrderVO vo : voPage.getRecords()) {
                // 僅對待支付訂單（orderStatus=0）計算倒計時
                if (vo.getOrderStatus() != null && vo.getOrderStatus() == 0) {
                    Date orderTime = vo.getOrderTime();
                    if (orderTime != null) {
                        long elapsedSeconds = (now.getTime() - orderTime.getTime()) / 1000;
                        long remainingSeconds = validitySeconds - elapsedSeconds;
                        // 如果已過期，設置為0
                        vo.setCountdownSeconds(Math.max(0, remainingSeconds));
                    } else {
                        vo.setCountdownSeconds(0L);
                    }
                } else {
                    // 非待支付訂單，倒計時為null
                    vo.setCountdownSeconds(null);
                }
            }
        }

        return R.data(voPage);
    }

    /**
     * 填充律师信息到订单VO
     *
     * @param orderVO 订单VO对象
     * @param lawyerUser 律师用户对象
     */
    private void fillLawyerInfo(LawyerConsultationOrderVO orderVO, LawyerUser lawyerUser) {
        orderVO.setLawyerName(lawyerUser.getName());
        orderVO.setLawyerPhone(lawyerUser.getPhone());
        orderVO.setLawyerEmail(lawyerUser.getEmail());
        orderVO.setLawyerCertificateNo(lawyerUser.getLawyerCertificateNo());
        // 通过firm_id查询律所名称
        if (lawyerUser.getFirmId() != null) {
            LawFirm lawFirm = lawFirmMapper.selectById(lawyerUser.getFirmId());
            orderVO.setLawFirm(lawFirm != null && (lawFirm.getDeleteFlag() == null || lawFirm.getDeleteFlag() == 0) 
                    ? lawFirm.getFirmName() : null);
        } else {
            orderVO.setLawFirm(null);
        }
        orderVO.setPracticeYears(lawyerUser.getPracticeYears());
        orderVO.setSpecialtyFields(lawyerUser.getSpecialtyFields());
        orderVO.setCertificationStatus(lawyerUser.getCertificationStatus());
        orderVO.setServiceCount(lawyerUser.getServiceCount());
        orderVO.setServiceScore(lawyerUser.getServiceScore());
        orderVO.setLawyerConsultationFee(lawyerUser.getConsultationFee());
        orderVO.setProvince(lawyerUser.getProvince());
        orderVO.setCity(lawyerUser.getCity());
        orderVO.setDistrict(lawyerUser.getDistrict());
        orderVO.setAddress(lawyerUser.getAddress());
        orderVO.setHeadImg(lawyerUser.getHeadImg());
        orderVO.setNickName(lawyerUser.getNickName());
        orderVO.setPersonalIntroduction(lawyerUser.getPersonalIntroduction());
    }


    /**
     * 查询律师订单列表
     *

     * @param clientUserId 用户id
     * @param lawyerUserId 律师ID
     * @return 订单列表
     */
    @Override
    public R<Map<String, String>> checkOrder(Integer clientUserId, Integer lawyerUserId) {
        log.info("LawyerConsultationOrderController.checkOrder?clientUserId={},lawyerUserId{}", clientUserId, lawyerUserId);
        List<LawyerConsultationOrder>  orderDto  =consultationOrderMapper.selectOrder(clientUserId, lawyerUserId);
        if (CollectionUtils.isNotEmpty(orderDto)){
            return R.fail("您已存在咨询该律师的订单");
        }
        return R.success("可以咨询该律师");
    }

    @Override
    public void exportConsultationOrderList(HttpServletResponse response, String lawyerName, Integer orderStatus, String orderNumber) throws IOException {
        log.info("LawyerConsultationOrderServiceImpl.exportConsultationOrderList?lawyerName={},orderStatus={},orderNumber={}", 
                lawyerName, orderStatus, orderNumber);
        try {
            // 查询所有数据（使用大分页）
            Page<LawyerConsultationOrderVO> page = new Page<>(1, Integer.MAX_VALUE);
            
            // 如果按律師姓名搜索，先查詢匹配的律師ID列表
            List<Integer> lawyerUserIds = null;
            if (StringUtils.hasText(lawyerName)) {
                LambdaQueryWrapper<LawyerUser> lawyerQueryWrapper = new LambdaQueryWrapper<>();
                lawyerQueryWrapper.eq(LawyerUser::getDeleteFlag, 0);
                lawyerQueryWrapper.like(LawyerUser::getName, lawyerName);
                List<LawyerUser> lawyerUsers = lawyerUserService.list(lawyerQueryWrapper);
                if (lawyerUsers != null && !lawyerUsers.isEmpty()) {
                    lawyerUserIds = lawyerUsers.stream()
                            .map(LawyerUser::getId)
                            .collect(Collectors.toList());
                } else {
                    // 如果沒有找到匹配的律師，返回空结果
                    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                    response.getWriter().write("暂无数据可导出");
                    return;
                }
            }
            
            // 查询订单列表
            IPage<LawyerConsultationOrderVO> voPage = consultationOrderMapper.getConsultationOrderListWithLawyer(
                    page, orderNumber, null, null, lawyerName, orderStatus, lawyerUserIds);

            List<LawyerConsultationOrderVO> orderList = voPage != null ? voPage.getRecords() : Collections.emptyList();

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

            // 转换为Excel VO
            List<LawyerConsultationOrderExcelVo> excelVoList = orderList.stream()
                    .map(this::convertToExcelVo)
                    .collect(Collectors.toList());

            // 使用EasyExcelUtil导出
            EasyExcelUtil.exportExcel(response, excelVoList, LawyerConsultationOrderExcelVo.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);
        }
    }

    /**
     * 转换为Excel VO
     */
    private LawyerConsultationOrderExcelVo convertToExcelVo(LawyerConsultationOrderVO vo) {
        LawyerConsultationOrderExcelVo excelVo = new LawyerConsultationOrderExcelVo();
        
        // 律师信息
        excelVo.setLawyerName(vo.getLawyerName());
        excelVo.setLawyerPhone(vo.getLawyerPhone());
        
        // 订单信息
        excelVo.setOrderNumber(vo.getOrderNumber());
        
        // 订单金额（分转元）
        if (vo.getOrderAmount() != null) {
            BigDecimal amount = new BigDecimal(vo.getOrderAmount()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
            excelVo.setOrderAmount(amount.toString());
        } else {
            excelVo.setOrderAmount("0.00");
        }
        
        // 订单状态转换
        if (vo.getOrderStatus() != null) {
            String statusDesc = LawyerStatusEnum.getDescription(vo.getOrderStatus());
            excelVo.setOrderStatus(statusDesc != null ? statusDesc : "未知状态");
        } else {
            excelVo.setOrderStatus("");
        }
        
        // 支付方式转换
        if (StringUtils.hasText(vo.getPayType())) {
            if ("1".equals(vo.getPayType())) {
                excelVo.setPayType("支付宝");
            } else if ("2".equals(vo.getPayType())) {
                excelVo.setPayType("微信");
            } else {
                excelVo.setPayType(vo.getPayType());
            }
        } else {
            excelVo.setPayType("");
        }
        
        // 分钟收费-钱数（分转元）
        if (vo.getChargeMinute() != null) {
            BigDecimal chargeMinute = new BigDecimal(vo.getChargeMinute()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
            excelVo.setChargeMinute(chargeMinute.toString());
        } else {
            excelVo.setChargeMinute("");
        }
        
        // 分钟收费-分钟数
        excelVo.setMinuteNum(vo.getMinuteNum() != null ? vo.getMinuteNum().toString() : "");
        
        // 次数收费-钱数（分转元）
        if (vo.getChargeTime() != null) {
            BigDecimal chargeTime = new BigDecimal(vo.getChargeTime()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
            excelVo.setChargeTime(chargeTime.toString());
        } else {
            excelVo.setChargeTime("");
        }
        
        // 次数收费-次数
        excelVo.setTimeNum(vo.getTimeNum() != null ? vo.getTimeNum().toString() : "");
        
        return excelVo;
    }
}

