package com.tourism.webadmin.app.website.service.impl;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.page.PageMethod;
import com.tourism.common.additional.config.ApplicationConfig;
import com.tourism.common.additional.utils.MapConvertUtils;
import com.tourism.common.additional.utils.StringUtils;
import com.tourism.common.additional.utils.UrlConvertUtils;
import com.tourism.common.core.object.*;
import com.tourism.common.core.util.IpUtil;
import com.tourism.common.core.util.MyModelUtil;
import com.tourism.common.core.util.MyPageUtil;
import com.tourism.webadmin.app.website.dto.TourProjectGroupPurchaseDtoToWebDto;
import com.tourism.webadmin.app.website.dto.TourismBookProjectDto;
import com.tourism.webadmin.app.website.dto.TourismProjectToWebDto;
import com.tourism.webadmin.app.website.service.TourismProjectToWebService;
import com.tourism.webadmin.app.website.vo.DateRange;
import com.tourism.webadmin.app.website.vo.TourismProjectDatePriceVo;
import com.tourism.webadmin.app.website.vo.WebSiteProjectDatePriceVo;
import com.tourism.webadmin.back.model.*;
import com.tourism.webadmin.back.model.constant.Enable;
import com.tourism.webadmin.back.service.*;
import com.tourism.webadmin.back.vo.TourismProjectVo;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 门户网站首页Service
 *
 * @author tourism
 */
@Slf4j
@Service("TourismProjectToWebService")
public class TourismProjectToWebServiceImpl implements TourismProjectToWebService {

    @Autowired
    private TourismProjectService tourismProjectService;
    @Autowired
    private ApplicationConfig applicationConfig;
    @Autowired
    private TourismDatePriceService tourismDatePriceService;
    @Autowired
    private TourUserService tourUserService;
    @Autowired
    private TourBookInfoService tourBookInfoService;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private DirectoryInfoService directoryInfoService;
    @Autowired
    private TourismFileService tourismFileService;
    @Autowired
    private TourProjectGroupPurchaseService tourProjectGroupPurchaseService;


    @Override
    public MyPageData<TourismProjectVo> list(TourismProjectToWebDto tourismProjectDtoFilter) {
        if(StringUtils.isEmpty(tourismProjectDtoFilter.getAreaId()) && StringUtils.isEmpty(tourismProjectDtoFilter.getCountryId())){
            //判断是否为全部的地区
        }else if(StringUtils.isNotEmpty(tourismProjectDtoFilter.getAreaId()) && StringUtils.isEmpty(tourismProjectDtoFilter.getCountryId())){
            //判断是否为该地区的所有国家
            DirectoryInfo directoryInfo = new DirectoryInfo();
            directoryInfo.setParentId(Long.parseLong(tourismProjectDtoFilter.getAreaId()));
            directoryInfo.setEnable(1);
            List<DirectoryInfo> directoryInfoList =
                    directoryInfoService.getDirectoryInfoList(directoryInfo, "");
            List<Long> directoryIdList =
                    directoryInfoList.stream().map(DirectoryInfo::getId).collect(Collectors.toList());
            tourismProjectDtoFilter.setDirectoryInfoIds(directoryIdList);
        }else {
            //如果查询的是某个国家的游记的话
            if(StringUtils.isNotEmpty(tourismProjectDtoFilter.getCountryId())) {
                tourismProjectDtoFilter.setBelongTab(Long.valueOf(tourismProjectDtoFilter.getCountryId()));
            }
        }
        TourismProject tourismProjectFilter = MyModelUtil.copyTo(tourismProjectDtoFilter, TourismProject.class);
        //首页展示的为启用的内容
        tourismProjectFilter.setEnable(1);
//        String orderBy = MyOrderParam.buildOrderBy(tourismProjectDtoFilter.getOrderParamList(), TourismProject.class);
        MyOrderParam myOrderParam = new MyOrderParam();
        myOrderParam.add(new MyOrderParam.OrderInfo("isHotspot", true, null));
        myOrderParam.add(new MyOrderParam.OrderInfo("showOrder", true, null));
        myOrderParam.add(new MyOrderParam.OrderInfo("updateTime", false, null));
        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourismProject.class);
        if (tourismProjectDtoFilter.getPageNum() != null && tourismProjectDtoFilter.getPageSize() != null ) {
            PageMethod.startPage(tourismProjectDtoFilter.getPageNum(), tourismProjectDtoFilter.getPageSize(), true);
        }
        List<TourismProject> tourismProjectList =
                tourismProjectService.getTourismProjectList(tourismProjectFilter, orderBy);
//        List<TourismProject> tourismProjectList =
//                tourismProjectService.getTourismProjectListWithRelation(tourismProjectFilter, orderBy);
        MyPageData<TourismProjectVo> tourismProjectVoMyPageData = MyPageUtil.makeResponseData(tourismProjectList, TourismProjectVo.class);

        List<TourismProjectVo> dataList = tourismProjectVoMyPageData.getDataList();

        // 获取dataList里的项目id
        List<Long> projectIdList = tourismProjectList.stream().map(TourismProject::getId).collect(Collectors.toList());
        // 查询最低价格的团购
        List<TourProjectGroupPurchase> lowestPriceGroupPurchase = tourProjectGroupPurchaseService.getLowestPriceGroupPurchase(projectIdList);
        // 把项目和团购价格以project_id为key，以TourProjectGroupPurchase对象为value处理成map,便于后边匹配
        Map<Long, TourProjectGroupPurchase> collect = lowestPriceGroupPurchase.stream().collect(Collectors.toMap(TourProjectGroupPurchase::getProjectId, item -> item, (v1, v2) -> v2));


        //先把imgUrl由jaon转换为List<FileUrlObject>
        dataList.stream().forEach(item ->{
            //遍历查询关联的tourismFile
            TourismFile tourismFile = new TourismFile();
            tourismFile.setAssociationTableId(item.getId());
            List<TourismFile> tourismFileListWithRelation = tourismFileService.getTourismFileList(tourismFile, "");
            //判断是否为空
            if(tourismFileListWithRelation != null && tourismFileListWithRelation.size() > 0){
                //不为空则进行转换,提取数据
                TourismFile tourismFile1 = tourismFileListWithRelation.get(0);
                String fileUrl = tourismFile1.getFileUrl();
                //进行转换url
                List<String> fileUrlList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), fileUrl);
                item.setFileUrlList(fileUrlList);
            }
            List<String> urlList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getHomeHotPicture());
            item.setHomeHotPicturesAfterConvert(urlList);
            List<String> arrayList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTourismUrl());
            item.setTourismUrlsAfterConvert(arrayList);
            List<String> arrayList1 = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTravelNotesBanner());
            item.setTravelNotesBannerAfterConvert(arrayList1);

            // 匹配团购信息
            TourProjectGroupPurchase tourProjectGroupPurchase = collect.get(Long.valueOf(item.getId()));
            if(tourProjectGroupPurchase != null) {
                item.setHasGroup(1);
                item.setLowestPrice(tourProjectGroupPurchase.getAdultPrice());
                item.setGroupPeopleCount(tourProjectGroupPurchase.getMaxCount());
            }else {
                item.setHasGroup(0);
            }
        });

        return tourismProjectVoMyPageData;
    }

    @Override
    public TourismProjectVo detail(TourismProject tourismProject) {
        TourismProjectVo tourismProjectVo = MyModelUtil.copyTo(tourismProject, TourismProjectVo.class);
        List<String> arrayList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getTourismUrl());
        tourismProjectVo.setTourismUrlsAfterConvert(arrayList);
        List<String> arrayList1 = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getHomeHotPicture());
        tourismProjectVo.setHomeHotPicturesAfterConvert(arrayList1);
        List<String> arrayList2 = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getTravelNotesBanner());
        tourismProjectVo.setTravelNotesBannerAfterConvert(arrayList2);
        if(tourismProjectVo.getTourismFile() != null){
            // 使用 Jackson 的 ObjectMapper 进行转换
            ObjectMapper objectMapper = new ObjectMapper();
            TourismFile tourismFile = objectMapper.convertValue(tourismProjectVo.getTourismFile(), TourismFile.class);
            tourismFile.setFileUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismFile.getFileUrl()));
            tourismProjectVo.setTourismFile(MapConvertUtils.convertObjectToMap(tourismFile));
        }
        // 查询项目有没有可用的团购信息
        TourProjectGroupPurchaseDtoToWebDto dto = new TourProjectGroupPurchaseDtoToWebDto();
        dto.setProjectId(tourismProject.getId());
        dto.setState(Enable.ENABLE_YES);
        List<String> dates = tourProjectGroupPurchaseService.queryUniqueGroupPurchaseDates(dto);
        // 如果有日期列表，则说明有团购，值是1
        if(dates != null && dates.size() > 0) {
            tourismProjectVo.setHasGroup(1);
        }else {
            tourismProjectVo.setHasGroup(0);
        }

        if(tourismProjectVo != null) {
            tourismProjectVo.setContactCodeConvert("https://v.xiaoyaotravel.com/image/ContactQRCode/tourism.png");
        }
        return tourismProjectVo;
    }

    @Override
    public WebSiteProjectDatePriceVo view(String projectId) {

        TourismDatePrice tourismDatePrice = new TourismDatePrice();
        tourismDatePrice.setProjectId(projectId);
        tourismDatePrice.setNowDate(new Date());

        //查询进行排序
        MyOrderParam myOrderParam = new MyOrderParam();
        MyOrderParam.OrderInfo orderInfo = new MyOrderParam.OrderInfo();
        orderInfo.setFieldName("departureDate");
        orderInfo.setAsc(true);
        myOrderParam.add(orderInfo);
        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourismDatePrice.class);
        List<TourismDatePrice> tourismDatePriceList =
                tourismDatePriceService.getTourismDatePriceList(tourismDatePrice, orderBy);
//        List<TourismDatePrice> tourismDatePriceSortList = tourismDatePriceList.stream()
//                .sorted(Comparator.comparing(TourismDatePrice::getDepartureDate))
//                .collect(Collectors.toList());
        List<TourismProjectDatePriceVo> tourismProjectDatePriceVos = MyModelUtil.copyCollectionTo(tourismDatePriceList, TourismProjectDatePriceVo.class);

        DateRange dateRange = new DateRange();
        dateRange.setStartDate(new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
        if(!CollectionUtils.isEmpty(tourismDatePriceList)) {
            Optional<Date> max = tourismDatePriceList.stream()
                    .map(TourismDatePrice::getDepartureDate)
                    .max(Comparator.naturalOrder());
            dateRange.setEndDate(max.get().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
        }else {
            dateRange.setEndDate(DateUtils.addDays(new Date(), 30).toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
        }
//        //查询项目的默认价格
//        TourismProject tourismProject = tourismProjectService.getById(projectId);
//        if(tourismProject != null){
//            tourismProjectDatePriceVos.stream().forEach(item->{
//                item.setProjectPrice(tourismProject.getPrice().toString().concat(tourismProject.getPriceUnit()));
//            });
//        }
        WebSiteProjectDatePriceVo webSiteProjectDatePriceVo = new WebSiteProjectDatePriceVo();
        // 使用 Stream API 将列表转换为 Map
        Map<LocalDate, TourismProjectDatePriceVo> map = tourismProjectDatePriceVos.stream()
                .collect(Collectors.toMap(
                        TourismProjectDatePriceVo::getDepartureDate, // key
                        vo -> vo // value
                ));
        webSiteProjectDatePriceVo.setTourismProjectDatePriceVos(map);
        webSiteProjectDatePriceVo.setDateRange(dateRange);
        return webSiteProjectDatePriceVo;
    }

    @Override
    public Boolean bookProject(HttpServletRequest request, TourismBookProjectDto tourBookInfoDto) {

        //获取用户的手机号
        Long userId = TokenData.takeFromRequest().getUserId();
        TourUser tourUser = tourUserService.getById(userId);
        String mobile = tourUser.getMobile();

        RBucket<Object> bucket = redissonClient.getBucket(tourBookInfoDto.getString().concat(mobile));
        if(bucket.get() != null){
            return false;
        }

        if(tourBookInfoDto == null){
            throw new RuntimeException("预定参数为空！");
        }

        //根据当前日期，查询当天的项目日历价格
        TourismDatePrice tourismDatePrice = new TourismDatePrice();
        tourismDatePrice.setProjectId(tourBookInfoDto.getProjectId());
        tourismDatePrice.setDepartureDate(tourBookInfoDto.getStartDate());
        TourismDatePrice tourismDatePriceOne = tourismDatePriceService.getOne(tourismDatePrice);


        //构建预定的数据进行保存
        TourBookInfo tourBookInfo = new TourBookInfo();
        tourBookInfo.setType(tourBookInfoDto.getType());
        tourBookInfo.setProjectId(Long.parseLong(tourBookInfoDto.getProjectId()));
        tourBookInfo.setAdultNumber(tourBookInfoDto.getAdultNumber());
        tourBookInfo.setChildrenNumber(tourBookInfoDto.getChildrenNumber());
        tourBookInfo.setAdultPrice(tourismDatePriceOne.getAdultPrice());
        tourBookInfo.setChildrenPrice(tourismDatePriceOne.getChildrenPrice());
        tourBookInfo.setBookMobile(mobile);
        tourBookInfo.setBookName(mobile);
        //默认初始化状态为0未处理
        tourBookInfo.setIsHandle(0);
        tourBookInfo.setBookTime(tourBookInfoDto.getStartDate());
        tourBookInfo.setTotalPrice( tourismDatePriceOne.getAdultPrice().multiply(BigDecimal.valueOf(tourBookInfoDto.getAdultNumber()))
                .add(tourismDatePriceOne.getChildrenPrice().multiply(BigDecimal.valueOf(tourBookInfoDto.getChildrenNumber()))));
        tourBookInfo.setBookIp(IpUtil.getRemoteIpAddress(request));
        tourBookInfoService.saveNew(tourBookInfo);
        bucket.set("预约成功!");
        return true;
    }
}
