package com.bonus.sharedstation.app.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.sharedstation.app.dto.CleaningServicesOrderDTO;
import com.bonus.sharedstation.app.dto.PaymentDto;
import com.bonus.sharedstation.app.entity.CleaningServicesOrder;
import com.bonus.sharedstation.app.feign.OtherServiceClient;
import com.bonus.sharedstation.app.mapper.CleaningServicesOrderMapper;
import com.bonus.sharedstation.app.service.CleaningServicesOrderService;
import com.bonus.sharedstation.app.vo.AjaxResultVo;
import com.bonus.sharedstation.common.Constant.Constant;
import com.bonus.sharedstation.common.utils.OrderNumberGeneratorUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.Date;

@Service("cleaningServicesOrderService")
@Slf4j
public class CleaningServicesOrderServiceImpl extends ServiceImpl<CleaningServicesOrderMapper, CleaningServicesOrder> implements CleaningServicesOrderService {

    @Resource
    private CleaningServicesOrderMapper dao;

    @Resource
    private OtherServiceClient otherServiceClient;

    @Override
    @Transactional
    public AjaxResult insertAndPay(CleaningServicesOrder dto) {
        //得到登录人
        dto.setCreatedBy(SecurityUtils.getUsername());
        dto.setCreatedTime(new Date());
        dto.setUserId(String.valueOf(SecurityUtils.getUserId()));
        dto.setOrderTime(new Date());
        dto.setIsDeleted("0");
        //流水号
        dto.setOrdno(OrderNumberGeneratorUtils.generateOrderNumber());
        //支付相关接入第三方小牛支付
        return payment(dto);
    }

    private AjaxResult payment(CleaningServicesOrder dto) {
        PaymentDto bean = new PaymentDto();
        bean.setMoney(dto.getUsePrice());
        bean.setCustId(SecurityUtils.getLoginUser().getCustId());
        try {
            if (ObjectUtil.isEmpty(dto.getUsePrice())) {
                throw new IllegalArgumentException("价格不能为空");
            }
            AjaxResult result = otherServiceClient.payMoneyForStage(bean);
            AjaxResultVo ajaxResultVo = JSON.parseObject(JSON.toJSONString(result), AjaxResultVo.class);
            if (!ajaxResultVo.getCode().equals("200")) {
                return AjaxResult.error(ajaxResultVo.getMsg());
            }
            dto.setOrderPayInfo(ajaxResultVo.getMsg());
            bean.setOrderPayInfo(ajaxResultVo.getMsg());
        } catch (Exception e) {
            log.error("支付失败", e);
            return AjaxResult.error("支付失败");
        }
        try {
            int payInsert = dao.insert(dto);
            if (payInsert == 0) {
                return AjaxResult.error("数据新增失败");
            }
        } catch (Exception e) {
            //调用食堂卡退款
            AjaxResult refundResultVo = refundOperation(bean);
            if (refundResultVo != null) return refundResultVo;
            //删除当前订单
            int delCode = dao.deleteById(dto.getId());
            if (delCode == 0) {
                return AjaxResult.error("数据新增-订单删除失败，请联系管理员进行处理！");
            }
            return AjaxResult.error("数据新增失败");
        }
        return AjaxResult.success("支付成功");
    }

    /**
     * 退款操作
     *
     * @param bean 退款信息
     * @return 结果
     */
    private AjaxResult refundOperation(PaymentDto bean) {
        AjaxResult refundResult = otherServiceClient.refundMoneyForStage(bean);
        AjaxResultVo refundResultVo = JSON.parseObject(JSON.toJSONString(refundResult), AjaxResultVo.class);
        if (!refundResultVo.getCode().equals("200")) {
            return AjaxResult.error(refundResultVo.getMsg());
        }
        return null;
    }

//
//    /**
//     * 支付相关接入第三方小牛支付
//     *
//     * @param userInfo
//     * @param dto
//     * @return
//     */
//    private RestResult payByNiu(GreenUserInfo userInfo, CleaningServicesOrder dto) {
//        //1 先查询人员对应的卡号
//        //应用秘钥
//        String appsecret = applicationidpsw;
//        //传参
//        HashMap<Object, Object> bodyMap = new HashMap<>(2);
//        if (StringUtils.isEmpty(userInfo.getMobile())) {
//            log.info("下单没有配置手机号,无法下单,请联系管理员配置");
//            return new RestResult(Constant.FAILED, "没有配置手机号,无法下单,请联系管理员配置");
//        }
////        bodyMap.put("mobile", "15996330508");
//        bodyMap.put("mobile", userInfo.getMobile());
//        //请求内容字典排序，转换为String
//        String content = JSON.toJSONString(bodyMap, SerializerFeature.MapSortField, SerializerFeature.WriteMapNullValue);
//        log.info("请求内容转换为JSON字符串，字典排序：{}", content);
//        //构造请求验签参数方法
//
////        Map<String, Object> map = makeSign(content, appsecret, bodyMap);
//        Map<String, Object> map = makeSign(content, applicationidpsw, bodyMap);
////        HttpRequest request = HttpUtil.createPost(IpConfig.SEARCH_USER);
//        HttpRequest request = HttpUtil.createPost(niusearchuserurl);
//        log.info("request=" + JSONUtil.toJsonStr(map));
//        request.body(JSONUtil.toJsonStr(map), ContentType.JSON.toString());
//        HttpResponse response = request.execute();
//        log.info("response={}", response.body());
//        //转成实体类
//        ObjectMapper objectMapper = new ObjectMapper();
//        try {
//            ApiResponse apiResponse = objectMapper.readValue(response.body(), ApiResponse.class);
//            ResponseDatad data = apiResponse.getData();
//            List<Customer> customerList = data.getCustomerList();
//            if (StringUtils.isEmpty(customerList)) {
//                log.info("没有找到对应餐卡,无法下单,请联系管理员配置");
//                return new RestResult(Constant.FAILED, "没有找到对应餐卡,无法下单,请联系管理员配置");
//            }
//            Customer customer = customerList.get(0);
//            //传参
//            HashMap<Object, Object> bodyMapForPayContent = new HashMap<>(2);
//            //构建 content
//            intoMapEnity(bodyMapForPayContent, dto, customer);
//            String payContent = JSON.toJSONString(bodyMapForPayContent, SerializerFeature.MapSortField, SerializerFeature.WriteMapNullValue);
//            log.info("content: " + payContent);
////            Map<String, Object> payBodyMap = makeSign(payContent, appsecret, bodyMapForPayContent);
//            Map<String, Object> payBodyMap = makeSign(payContent, applicationidpsw, bodyMapForPayContent);
//
////            HttpRequest requestForPay = HttpUtil.createPost(IpConfig.PAY_URL_TEST);
//            HttpRequest requestForPay = HttpUtil.createPost(niupayurl);
//            log.info("request=" + JSONUtil.toJsonStr(payBodyMap));
//            requestForPay.body(JSONUtil.toJsonStr(payBodyMap), ContentType.JSON.toString());
//            HttpResponse responseForPay = requestForPay.execute();
//            log.info("response={}", response.body());
//            log.info("responseForPay={}", responseForPay.body());
//            //转成实体类响应数据
//            ApiResponseForPay apiResponseForPay = objectMapper.readValue(responseForPay.body(), ApiResponseForPay.class);
//            if (apiResponseForPay == null) {
//                log.error("扣款食堂卡失败,请检查");
//                return new RestResult(Constant.FAILED, "扣款食堂卡无响应,请联系管理员");
//            }
//            if (StringUtils.isNotNull(apiResponseForPay) && apiResponseForPay.getCode() == 10000) {
//                int result = dao.insert(dto);
//                if (result == 1) {
//                    return new RestResult(Constant.SUCCESS, "扣款成功," + "扣款金额为:" + apiResponseForPay.getData().getRealAmount() + "余额为:" + apiResponseForPay.getData().getWalletBal());
//                }
//            }
//            return new RestResult(Constant.FAILED, "小牛支付提示:" + apiResponseForPay.getCode() + apiResponseForPay.getMsg());
//        } catch (Exception e) {
//            log.error("下单失败");
//            e.printStackTrace();
//            return new RestResult(Constant.FAILED, "有异常 请处理");
//        }
//    }
//
//    private void intoMapEnity(HashMap bodyMap, CleaningServicesOrder dto, Customer customer) {
//        //金额
//        Double usePrice = dto.getUsePrice();
//        int convertedPrice = (int) (usePrice * 100);
//        bodyMap.put("amount", convertedPrice);
//        //人员 id
//        bodyMap.put("custId", Long.valueOf(customer.getCustId()));
//        //流水号
//        bodyMap.put("macOrdId", dto.getOrdno());
//        //sn码
//        bodyMap.put("machineSn", sncode);
//        //
//        bodyMap.put("nuClearMode", 2);
//
//        bodyMap.put("ordTime", DateUtils.formatDate(dto.getOrderTime()));
//
//        bodyMap.put("deliveryType", "2");
//    }
//
//
//    private Map<String, Object> makeSign(String content, String appsecret, HashMap<Object, Object> bodyMap) {
//        Map<String, Object> map = new TreeMap<>();
////        map.put("appid", IpConfig.APPLICATION_ID);
//        map.put("appid", applicationid);
//        map.put("version", "1.0.0");
//        map.put("signtype", "md5");
//        map.put("timestamp", String.valueOf(System.currentTimeMillis()));
//        map.put("nonce", RandomUtil.randomNumbers(10));
//        map.put("content", content);
//        //生成sign，防篡改
//        String toSignStr = Joiner.on("&")
//                .useForNull("")
//                .withKeyValueSeparator("=")
//                .join(map) + "&appsecret=" + appsecret;
//        log.info("所有参数字典排序，待加签String：{}", toSignStr);
//
//        // md5/sha256 加签（其他方式待提供）
//        String sign = DigestUtils.md5Hex(toSignStr).toUpperCase();
//        System.err.println("sign: " + sign);
//        log.info("加签String：{}", sign);
//        map.put("sign", sign);
//
//        //post请求
//        map.replace("content", bodyMap);
//        return map;
//    }

    @Override
    public AjaxResult getListPageApp(CleaningServicesOrderDTO dto) {
        log.info("查询 入参: {}", dto);
        LambdaQueryWrapper<CleaningServicesOrder> queryWrapper = new LambdaQueryWrapper<>();

        Page<CleaningServicesOrder> page = new Page<>(dto.getCurrentPage(), dto.getLimit());
        queryWrapper.eq(CleaningServicesOrder::getUserId, SecurityUtils.getUserId());
        queryWrapper
                .eq(CleaningServicesOrder::getIsDeleted, dto.getIsDeleted())
                .orderByDesc(CleaningServicesOrder::getCreatedTime);     // 降序排序

        Page<CleaningServicesOrder> result = dao.selectPage(page, queryWrapper);
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult getListWeb(CleaningServicesOrderDTO dto) {
        log.info("查询 入参: {}", dto);
        LambdaQueryWrapper<CleaningServicesOrder> queryWrapper = new LambdaQueryWrapper<>();
        // 创建分页对象
        Page<CleaningServicesOrder> page = new Page<>(dto.getCurrentPage(), dto.getLimit());
        if (StringUtils.isNotEmpty(dto.getName())) {
            queryWrapper.like(CleaningServicesOrder::getName, dto.getName());
        }
        queryWrapper
                .eq(CleaningServicesOrder::getIsDeleted, dto.getIsDeleted())
                .orderByDesc(CleaningServicesOrder::getCreatedTime);     // 降序排序

        if (StringUtils.isNotEmpty(dto.getTimeType())) {
            switch (dto.getTimeType()) {
                case Constant.CUTHOTIMS_TIME:
                    return listByCustomDateRange(page, dto.getBeginTime(), dto.getEndTime(), dto);
                case Constant.MNONTH_TIME://2024-12
                    return listByMonth(page, dto.getYearMonth(), dto);
                case Constant.QUARTER_TIME:
                    return listByQuarter(page, dto.getYear(), dto.getQuarter(), dto);
                case Constant.YEAR_TIME:
                    return listByYear(page, dto.getYear(), dto);
                default:
                    break;
            }
        }
        Page<CleaningServicesOrder> result = dao.selectPage(page, queryWrapper);
        //处理参数问题
        return AjaxResult.success(result);
    }


    // 按月查询订单列表
    public AjaxResult listByMonth(Page<CleaningServicesOrder> page, String yearMonth, CleaningServicesOrderDTO dto) {
        //格式为2024-12
        LocalDate startOfMonth = LocalDate.parse(yearMonth + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endOfMonth = startOfMonth.withDayOfMonth(startOfMonth.lengthOfMonth());

        LambdaQueryWrapper<CleaningServicesOrder> queryWrapper = buildDateRangeQuery(
                toUtilDate(startOfMonth.atStartOfDay()),
                toUtilDate(endOfMonth.atTime(23, 59, 59)), dto
        );


        Page<CleaningServicesOrder> result = dao.selectPage(page, queryWrapper);
        //处理参数问题
        return AjaxResult.success(result);
    }

    // 按季度查询订单列表
    public AjaxResult listByQuarter(Page<CleaningServicesOrder> page, Integer year, Integer quarter, CleaningServicesOrderDTO dto) {
        LocalDate startOfQuarter = LocalDate.of(year, (quarter - 1) * 3 + 1, 1);
        int lastMonthOfQuarter = ((quarter - 1) * 3 + 3) % 12 + 1;
        YearMonth yearMonth = YearMonth.of(year, lastMonthOfQuarter);
        int daysInLastMonth = yearMonth.lengthOfMonth();
        LocalDate endOfQuarter = LocalDate.of(year, lastMonthOfQuarter, daysInLastMonth);

        LambdaQueryWrapper<CleaningServicesOrder> queryWrapper = buildDateRangeQuery(
                toUtilDate(startOfQuarter.atStartOfDay()),
                toUtilDate(endOfQuarter.atTime(23, 59, 59)), dto
        );

        Page<CleaningServicesOrder> result = dao.selectPage(page, queryWrapper);
        //处理参数问题
        return AjaxResult.success(result);
    }

    // 按年查询订单列表
    public AjaxResult listByYear(Page<CleaningServicesOrder> page, Integer year, CleaningServicesOrderDTO dto) {
        LocalDate startOfYear = LocalDate.of(year, 1, 1);
        LocalDate endOfYear = LocalDate.of(year, 12, 31);

        LambdaQueryWrapper<CleaningServicesOrder> queryWrapper = buildDateRangeQuery(
                toUtilDate(startOfYear.atStartOfDay()),
                toUtilDate(endOfYear.atTime(23, 59, 59)), dto
        );

        Page<CleaningServicesOrder> result = dao.selectPage(page, queryWrapper);
        //处理参数问题
        return AjaxResult.success(result);
    }


    // 将 LocalDateTime 转换为 Date
    private Date toUtilDate(LocalDateTime localDateTime) {
        return java.sql.Timestamp.valueOf(localDateTime);
    }


    // 按自定义时间段查询订单列表
    public AjaxResult listByCustomDateRange(Page<CleaningServicesOrder> page, Date startDate, Date endDate, CleaningServicesOrderDTO dto) {
        LambdaQueryWrapper<CleaningServicesOrder> queryWrapper = buildDateRangeQuery(startDate, endDate, dto);

        Page<CleaningServicesOrder> result = dao.selectPage(page, queryWrapper);
        return AjaxResult.success(result);

    }

    // 构建日期范围查询条件
    private LambdaQueryWrapper<CleaningServicesOrder> buildDateRangeQuery(Date startTime, Date endTime, CleaningServicesOrderDTO dto) {
        LambdaQueryWrapper<CleaningServicesOrder> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(dto.getName())) {
            queryWrapper.like(CleaningServicesOrder::getName, dto.getName());
        }
        queryWrapper.eq(CleaningServicesOrder::getIsDeleted, "0")
                .orderByDesc(CleaningServicesOrder::getCreatedTime);     // 降序排序; // 只查询未删除的记录
        queryWrapper.between(CleaningServicesOrder::getOrderTime, startTime, endTime);
        return queryWrapper;
    }

    @Override
    public AjaxResult selectInfoById(CleaningServicesOrder dto) {
        CleaningServicesOrder result = dao.selectById(dto.getId());
        if (StringUtils.isNull(result)) {
            return AjaxResult.error("此服务不存在");
        }
        //处理参数问题
        return AjaxResult.success(result);
    }


    // 构建日期范围查询条件
    private LambdaQueryWrapper<CleaningServicesOrder> buildDateRangeQueryNoPage(Date startTime, Date endTime, CleaningServicesOrderDTO dto) {
        LambdaQueryWrapper<CleaningServicesOrder> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(dto.getName())) {
            queryWrapper.like(CleaningServicesOrder::getName, dto.getName());
        }
        queryWrapper.eq(CleaningServicesOrder::getIsDeleted, "0"); // 只查询未删除的记录
        queryWrapper.between(CleaningServicesOrder::getOrderTime, startTime, endTime);
        return queryWrapper;
    }

}

