/*
 * Copyright (c) 2021, orioc and/or its affiliates. All rights reserved.
 * Use, Copy is subject to authorized license.
 */
package com.bonus.sharedstation.web.service.impl;

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.WashClothingOrderDTO;
import com.bonus.sharedstation.app.entity.WashClothingOrder;
import com.bonus.sharedstation.app.entity.WashClothingOrderInfo;
import com.bonus.sharedstation.app.entity.WashClothingPrice;
import com.bonus.sharedstation.app.mapper.WashClothingOrderInfoMapper;
import com.bonus.sharedstation.app.mapper.WashClothingOrderMapper;
import com.bonus.sharedstation.app.mapper.WashClothingPriceMapper;
import com.bonus.sharedstation.app.vo.WashClothingOrderWithInfoVO;
import com.bonus.sharedstation.common.Constant.Constant;
import com.bonus.sharedstation.common.utils.DateUtils;
import com.bonus.sharedstation.common.utils.ExcelUtils;
import com.bonus.sharedstation.web.dto.WashClothingPriceDTO;
import com.bonus.sharedstation.web.service.IWashClothingPriceWebService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Service实现
 *
 * @author hyq
 * @date 2024-03-15
 */
@Service
@Transactional(readOnly = true)
@Slf4j
public class WashClothingPriceWebServiceImpl extends ServiceImpl<WashClothingPriceMapper, WashClothingPrice> implements IWashClothingPriceWebService
{


    /**
     * Dao
     */
    @Resource
    private WashClothingPriceMapper dao;

    @Resource
    private WashClothingOrderMapper washClothingOrderMapper;
    @Resource
    private WashClothingOrderInfoMapper washClothingOrderInfoMapper;

    @Override
    @Transactional(readOnly = false)
    public AjaxResult insert(WashClothingPrice dto) {
        log.info("新增日期配置:{} ", dto);
        //得到登录人
        dto.setCreatedBy(SecurityUtils.getUsername());
        dto.setCreatedTime(new Date());
        boolean b = save(dto);
        if (!b) {
            return AjaxResult.error("新增洗衣服务种类价格失败");
        }
        return AjaxResult.success("新增洗衣服务种类价格成功");
    }

    @Override
    @Transactional(readOnly = false)
    public AjaxResult updateInfoById(WashClothingPrice dto) {
        log.info("修改 入参: {}", dto);
        dto.setCreatedBy(SecurityUtils.getUsername());
        dto.setCreatedTime(new Date());
        boolean b = updateById(dto);
        if (!b) {
            return AjaxResult.error("洗衣服务种类价格修改失败");
        }
        return AjaxResult.success( "洗衣服务价格修改成功");
    }

    /**
     * 分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public AjaxResult getListPage(WashClothingPriceDTO dto) {
        log.info("查询 入参: {}", dto);
        LambdaQueryWrapper<WashClothingPrice> queryWrapper = new LambdaQueryWrapper<>();
        // 创建分页对象
        Page<WashClothingPrice> page = new Page<>(dto.getCurrentPage(), dto.getLimit());
        if (StringUtils.isNotEmpty( dto.getName())){
            queryWrapper.like(WashClothingPrice::getName,dto.getName());
        }
        queryWrapper
                .eq(WashClothingPrice::getIsDeleted, dto.getIsDeleted())
                .orderByDesc(WashClothingPrice::getCreatedTime);

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

    /**
     * 分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public AjaxResult getListPageApp(WashClothingPriceDTO dto) {
        log.info("查询 入参: {}", dto);
        LambdaQueryWrapper<WashClothingPrice> queryWrapper = new LambdaQueryWrapper<>();
        // 创建分页对象
        Page<WashClothingPrice> page = new Page<>(dto.getCurrentPage(), dto.getLimit());
        if (StringUtils.isNotEmpty( dto.getName())){
            queryWrapper.like(WashClothingPrice::getName,dto.getName());
        }
        queryWrapper
                .eq(WashClothingPrice::getIsDeleted, dto.getIsDeleted())
                .orderByDesc(WashClothingPrice::getCreatedTime);

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

    @Override
    @Transactional(readOnly = false)
    public AjaxResult delete(WashClothingPrice dto) {
        return AjaxResult.success(dao.deleteById(dto.getId()));
    }

    /**
     * 查询全部
     *
     * @param
     * @return
     */
    @Override
    public AjaxResult selectAll(WashClothingPrice dto) {
        log.info("查询 入参: {}", dto);
        LambdaQueryWrapper<WashClothingPrice> queryWrapper = new LambdaQueryWrapper<>();
        // 创建分页对象
        queryWrapper
                .eq(WashClothingPrice::getIsDeleted, dto.getIsDeleted())
                .orderByDesc(WashClothingPrice::getCreatedTime);

        List<WashClothingPrice> result = dao.selectList(queryWrapper);
        return AjaxResult.success(result);
    }


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

    /**
     * 分页
     *
     * @param dto
     * @return
     */
    @Override
    public AjaxResult getListWeb(WashClothingOrderDTO dto) {
        log.info("查询分页入参: {}", dto);
        LambdaQueryWrapper<WashClothingOrder> queryWrapper = new LambdaQueryWrapper<>();
        // 创建分页对象
        Page<WashClothingOrder> page = new Page<>(dto.getCurrentPage(), dto.getLimit());

        if (StringUtils.isNotEmpty(dto.getName())) {
            queryWrapper.like(WashClothingOrder::getName, dto.getName());
        }
        queryWrapper
                .eq(WashClothingOrder::getIsDeleted, dto.getIsDeleted())
                .orderByDesc(WashClothingOrder::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<WashClothingOrder> result = washClothingOrderMapper.selectPage(page, queryWrapper);
        //处理参数问题
        List<WashClothingOrder> records = result.getRecords();
        if (records == null) {
            return AjaxResult.success(result);
        }
        //查询所有的绿植订单信息
        LambdaQueryWrapper<WashClothingOrderInfo> greenOrderInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        greenOrderInfoLambdaQueryWrapper
                .eq(WashClothingOrderInfo::getIsDeleted, dto.getIsDeleted())
                .orderByDesc(WashClothingOrderInfo::getCreatedTime);
        List<WashClothingOrderInfo> greenOrderInfos = washClothingOrderInfoMapper.selectList(greenOrderInfoLambdaQueryWrapper);
        for (WashClothingOrder record : records) {
            if (record != null) {
                Integer id = record.getId();
                List<WashClothingOrderInfo> collect = greenOrderInfos.stream().
                        filter(greenOrderInfo -> greenOrderInfo.getOrderId() != null
                                && greenOrderInfo.getOrderId().equals(id)).collect(Collectors.toList());
                if (collect != null) {
                    record.setOrderInfoList(collect);
                }
            }
        }
        return AjaxResult.success(result);
    }


    /**
     *处理参数问题
     * @param
     * @return
     */
    public AjaxResult changeParam(Page<WashClothingOrder> result){
        //处理参数问题
        List<WashClothingOrder> records = result.getRecords();
        if (records == null) {
            return AjaxResult.success(result);
        }
        //查询所有的绿植订单信息
        LambdaQueryWrapper<WashClothingOrderInfo> greenOrderInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        greenOrderInfoLambdaQueryWrapper
                .eq(WashClothingOrderInfo::getIsDeleted, "0")
                .orderByDesc(WashClothingOrderInfo::getCreatedTime);
        List<WashClothingOrderInfo> greenOrderInfos = washClothingOrderInfoMapper.selectList(greenOrderInfoLambdaQueryWrapper);
        for (WashClothingOrder record : records) {
            if (record != null) {
                Integer id = record.getId();
                List<WashClothingOrderInfo> collect = greenOrderInfos.stream().
                        filter(s -> s.getOrderId() != null
                                && s.getOrderId().equals(id)).collect(Collectors.toList());
                if (collect != null) {
                    record.setOrderInfoList(collect);
                }
            }
        }
        return AjaxResult.success(result);
    }


    /**
     * 导出订单
     * @param dto
     * @param response
     */
    @Override
    public void getOrderListWebExpertor(WashClothingOrderDTO dto, HttpServletResponse response) {
        log.info("查询 入参: {}", dto);
        LambdaQueryWrapper<WashClothingOrder> queryWrapper = new LambdaQueryWrapper<>();
        // 创建分页对象
        if (StringUtils.isNotEmpty(dto.getName())) {
            queryWrapper.like(WashClothingOrder::getName, dto.getName());
        }
        queryWrapper
                .eq(WashClothingOrder::getIsDeleted, dto.getIsDeleted())
                .orderByDesc(WashClothingOrder::getCreatedTime);     // 降序排序
        if (StringUtils.isNotEmpty(dto.getTimeType())) {
            switch (dto.getTimeType()) {
                case Constant.CUTHOTIMS_TIME://自定义时间
                    changeTimeToDate(dto);
                    listByCustomDateRangeNoPage(response, dto.getBeginTime(), dto.getEndTime(),dto);
                    break;
                case Constant.MNONTH_TIME://月 yyyy-MM
                    listByMonthNoPage(response, dto.getYearMonth(),dto);
                    break;
                case Constant.QUARTER_TIME://季度
                    listByQuarterNoPage( response,dto.getYear(), dto.getQuarter(),dto);
                    break;
                case Constant.YEAR_TIME://年
                    listByYearNoPage(response,dto.getYear(),dto);
                    break;
                default:
                    break;
            }
        }else{
            List<WashClothingOrder> cleaningServicesOrders = washClothingOrderMapper.selectList(queryWrapper);
            //处理参数问题
            if (cleaningServicesOrders != null){
                exportExcel(response,cleaningServicesOrders);
            }
        }
    }


    private void changeTimeToDate(WashClothingOrderDTO dto) {
        if (StringUtils.isNotEmpty(dto.getRunTime()) && StringUtils.isNotEmpty(dto.getStopTime())){
            Date startTime = DateUtils.parseString(dto.getRunTime());
            Date endTime = DateUtils.parseString(dto.getStopTime());
            dto.setBeginTime(startTime);
            dto.setEndTime(endTime);
        }else{
            log.info("处理自定义时间格式失败,清洗服务导出");
            throw new RuntimeException("处理自定义时间格式失败,清洗服务导出");
        }
    }



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


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

        Page<WashClothingOrder> result = washClothingOrderMapper.selectPage(page, queryWrapper);

        return changeParam(result);

    }

    // 构建日期范围查询条件
    private LambdaQueryWrapper<WashClothingOrder> buildDateRangeQuery(Date startTime, Date endTime,WashClothingOrderDTO dto) {
        LambdaQueryWrapper<WashClothingOrder> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(dto.getName())) {
            queryWrapper.like(WashClothingOrder::getName, dto.getName());
        }
        queryWrapper.eq(WashClothingOrder::getIsDeleted, "0")
                .orderByDesc(WashClothingOrder::getCreatedTime);
        queryWrapper.between(WashClothingOrder::getOrderTime, startTime, endTime);
        return queryWrapper;
    }




    // 按月查询订单列表
    public void listByMonthNoPage(HttpServletResponse response, String yearMonth, WashClothingOrderDTO dto) {
        LocalDate startOfMonth = LocalDate.parse(yearMonth + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endOfMonth = startOfMonth.withDayOfMonth(startOfMonth.lengthOfMonth());

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

        List<WashClothingOrder> list = washClothingOrderMapper.selectList(queryWrapper);
        if (list != null){
            exportExcel(response,list);
        }
    }

    // 按季度查询订单列表
    public void listByQuarterNoPage(HttpServletResponse response,Integer year, Integer quarter,WashClothingOrderDTO dto) {
//        LocalDate startOfQuarter = LocalDate.of(year, (quarter - 1) * 3 + 1, 1);
//        LocalDate endOfQuarter = startOfQuarter.plusMonths(2).withDayOfMonth(startOfQuarter.getMonth().length(false));

        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<WashClothingOrder> queryWrapper = buildDateRangeQueryNoPage(
                toUtilDate(startOfQuarter.atStartOfDay()),
                toUtilDate(endOfQuarter.atTime(23, 59, 59)),dto
        );

        List<WashClothingOrder> list = washClothingOrderMapper.selectList(queryWrapper);
        if (list != null){
            exportExcel(response,list);
        }
    }

    // 按年查询订单列表
    public void listByYearNoPage(HttpServletResponse response,Integer year,WashClothingOrderDTO dto) {
        LocalDate startOfYear = LocalDate.of(year, 1, 1);
        LocalDate endOfYear = LocalDate.of(year, 12, 31);

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

        List<WashClothingOrder> list = washClothingOrderMapper.selectList(queryWrapper);
        if (list != null){
            exportExcel(response,list);
        }
    }

    // 按自定义时间段查询订单列表
    public void listByCustomDateRangeNoPage(HttpServletResponse response,Date startDate, Date endDate,WashClothingOrderDTO dto) {
        LambdaQueryWrapper<WashClothingOrder> queryWrapper = buildDateRangeQueryNoPage(startDate, endDate,dto);
        List<WashClothingOrder> list = washClothingOrderMapper.selectList(queryWrapper);
        if (list != null){
            exportExcel(response,list);
        }
    }

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


    private void exportExcel(HttpServletResponse response, List<WashClothingOrder> cleaningServicesOrders) {
        try {
            //处理参数
            changeParamForExport(cleaningServicesOrders);
            List<WashClothingOrderWithInfoVO> cleaningServicesOrderVOS = new ArrayList<>();
            if (cleaningServicesOrders != null){
                for (WashClothingOrder record : cleaningServicesOrders) {
                    WashClothingOrderWithInfoVO cleaningServicesOrderVO = new WashClothingOrderWithInfoVO();
                    BeanUtils.copyProperties(record,cleaningServicesOrderVO);
                    //处理 一个订单多个商品信息的问题
                    dealMethodGreen(cleaningServicesOrderVO,record);
                    cleaningServicesOrderVOS.add(cleaningServicesOrderVO);
                }
                ExcelUtils.write(response, "强袭.xls", "数据", WashClothingOrderWithInfoVO.class, cleaningServicesOrderVOS);
            }
        } catch (IOException e){
            log.error("导出洗衣服务异常"+ e);
        }

    }


    public void changeParamForExport(List<WashClothingOrder> records) {
        //处理参数问题
        //查询所有的绿植订单信息
        LambdaQueryWrapper<WashClothingOrderInfo> greenOrderInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        greenOrderInfoLambdaQueryWrapper
                .eq(WashClothingOrderInfo::getIsDeleted, "0")
                .orderByDesc(WashClothingOrderInfo::getCreatedTime);
        List<WashClothingOrderInfo> greenOrderInfos = washClothingOrderInfoMapper.selectList(greenOrderInfoLambdaQueryWrapper);
        for (WashClothingOrder record : records) {
            if (record != null) {
                Integer id = record.getId();
                List<WashClothingOrderInfo> collect = greenOrderInfos.stream().
                        filter(greenOrderInfo -> greenOrderInfo.getOrderId() != null
                                && greenOrderInfo.getOrderId().equals(id)).collect(Collectors.toList());
                if (collect != null) {
                    record.setOrderInfoList(collect);
                }
            }
        }
    }



    private void dealMethodGreen(WashClothingOrderWithInfoVO cleaningServicesOrderVO, WashClothingOrder record) {
        List<WashClothingOrderInfo> greenOrderInfoList = record.getOrderInfoList();
        if (greenOrderInfoList != null){
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < greenOrderInfoList.size(); i++) {
                WashClothingOrderInfo info = greenOrderInfoList.get(i);
                if (info.getClothingName() != null) {
                    // 将greenName和greenNum拼接，中间用"*"隔开
                    sb.append(info.getClothingName()).append("*").append(info.getClothingName());
                    // 检查是否是列表中的最后一个元素，如果不是，则追加","作为分隔符
                    if (i < greenOrderInfoList.size() - 1) {
                        sb.append(",");
                    }
                }
            }
            String s = sb.toString();
            if (StringUtils.isNotEmpty(s)){
                cleaningServicesOrderVO.setClothingName(s);
            }
        }
    }



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

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


        Page<WashClothingOrder> result = washClothingOrderMapper.selectPage(page, queryWrapper);
        //处理参数问题
        return changeParam(result);
    }

    // 按季度查询订单列表
    public AjaxResult listByQuarter(Page<WashClothingOrder> page, Integer year, Integer quarter,WashClothingOrderDTO dto) {
//        LocalDate startOfQuarter = LocalDate.of(year, (quarter - 1) * 3 + 1, 1);
//        LocalDate endOfQuarter = startOfQuarter.plusMonths(2).withDayOfMonth(startOfQuarter.getMonth().length(false));

        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<WashClothingOrder> queryWrapper = buildDateRangeQuery(
                toUtilDate(startOfQuarter.atStartOfDay()),
                toUtilDate(endOfQuarter.atTime(23, 59, 59)),dto
        );

        Page<WashClothingOrder> result = washClothingOrderMapper.selectPage(page, queryWrapper);
        //处理参数问题
        return changeParam(result);
    }

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

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

        Page<WashClothingOrder> result = washClothingOrderMapper.selectPage(page, queryWrapper);
        //处理参数问题
        return changeParam(result);
    }

}
