package com.happy.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.happy.Model.HotelDict;
import com.happy.Model.House;
import com.happy.Model.HousePrice;
import com.happy.Model.weixin.WeiXinUtil;
import com.happy.Until.*;
import com.happy.Until.Excel.toExcel;
import com.happy.dao.HotelDictDao;
import com.happy.dao.HouseDao;
import com.happy.dao.HousePriceDao;
import com.happy.dto.HousePriceDto;
import com.happy.dto.IPage;
import com.happy.service.HousePriceService;
import com.happy.vo.HotelPriceDataVo;
import com.happy.vo.HousePriceDataVo;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service("housePriceService")
public class HousePriceServiceImpl implements HousePriceService {
    @Resource(name = "housePriceDao")
    private HousePriceDao housePriceDao;
    @Resource(name = "HouseDao")
    private HouseDao houseDao;
    @Resource
    public HotelDictDao hotelDictDao;

    @SneakyThrows
    @Override
    public void modifyPriceBatch(List<String> dateList, List<HousePrice> priceList) {
        List<HousePrice> housePriceList = new ArrayList<>();
        Date now = DateUtil.formateDate(DateUtil.getCurrentDate(), DateUtil.Time_Formatter_Second);
        priceList.forEach(item -> {
            item.setCreateDate(now);
            item.setStatus(1);
            dateList.forEach(date -> {
                HousePrice housePrice = new HousePrice();
                BeanUtils.copyProperties(item, housePrice);
                housePrice.setId(Func.newGuid());
                housePrice.setSetDate(date);
                housePriceList.add(housePrice);
            });
        });
        housePriceDao.insertBatch(housePriceList);
    }

    @SneakyThrows
    @Override
    public void modifyPrice(HousePriceDto housePriceDto) {
        Date now = DateUtil.formateDate(DateUtil.getCurrentDate(), DateUtil.Time_Formatter_Second);
        housePriceDto.setId(Func.newGuid());
        housePriceDto.setCreateDate(now);
        housePriceDto.setStatus(1);
        housePriceDao.insertBatch(Collections.singletonList(housePriceDto));
    }

    @Override
    public JSONObject queryPage(HousePriceDto housePriceDto, Integer pageNumber, Integer pageSize) {
        List<JSONObject> pageJsonObjectList = new ArrayList<>(Collections.emptyList());
        List<JSONObject> dataTimes = new ArrayList<>(Collections.emptyList());
        HotelDict hotelDict = hotelDictDao.getById(1000011003);
        int m = 20;
        if (hotelDict!=null){
            m = Integer.parseInt(hotelDict.getName());
        }
        int total = housePriceDao.queryTotalOne(housePriceDto);
        if (total != 0) {
            List<HousePriceDto> pageList = housePriceDao.queryListOne(housePriceDto, pageNumber, pageSize);
            String startDateStr = housePriceDto.getSetDate();
            Date startDate = DateUtil.parseDateOnly(startDateStr);
            Date endDate = DateUtil.addDate(startDate, Calendar.DATE, m);
            System.out.println("===="+endDate);
            //region 周期内的改价记录
            housePriceDto.setSetDate(String.format("%s,%s", startDateStr, DateUtil.parseDateToStr(endDate, DateUtil.Time_Formatter_Day)));
            List<String> houseIdList = pageList.stream().map(HousePriceDto::getHouseId).collect(Collectors.toList());
            housePriceDto.setHouseIdList(houseIdList);
            List<HousePriceDto> housePriceDtoList = housePriceDao.queryListTwo(housePriceDto);
            //endregion

            List<Date> dateListBetween = DateUtil.getDateListBetween(startDate, endDate);
            dateListBetween.forEach(date -> {
                JSONObject time = new JSONObject(new LinkedHashMap<>());
                time.put("dateStr",DateUtil.parseDateToStr(date, DateUtil.Time_Formatter_Day));
                dataTimes.add(time);
            });
            pageList.forEach(item -> {
                JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());

                jsonObject.put("id", item.getHouseId());
                jsonObject.put("houseName", item.getHouseName());
                dateListBetween.forEach(date -> {
                    jsonObject.put(DateUtil.parseDateToStr(date, DateUtil.Time_Formatter_Day), getPrice(date, item, housePriceDtoList));
                });
                pageJsonObjectList.add(jsonObject);
            });
        }
        JSONObject result = new JSONObject();
        result.put("pageList", pageJsonObjectList);
        result.put("dateTimes",dataTimes);
        result.put("page", pageNumber);
        result.put("rows", pageSize);
        result.put("total", total);
        result.put("totalPage", (int) Math.ceil((double) total / pageSize));
        return result;
    }

    public JSONObject queryDate() {
        List<JSONObject> dataTimes = new ArrayList<>(Collections.emptyList());
        HotelDict hotelDict = hotelDictDao.getById(1000011003);
        int m = 20;
        if (hotelDict!=null){
            m = Integer.parseInt(hotelDict.getName());
        }
        String startDateStr = TimeExchange.getDateStr();
        Date startDate = DateUtil.parseDateOnly(startDateStr);
        Date endDate = DateUtil.addDate(startDate, Calendar.DATE, m);
        System.out.println("===="+endDate);
        List<Date> dateListBetween = DateUtil.getDateListBetween(startDate, endDate);
        dateListBetween.forEach(date -> {
            JSONObject time = new JSONObject(new LinkedHashMap<>());
            time.put("dateStr",DateUtil.parseDateToStr(date, DateUtil.Time_Formatter_Day));
            dataTimes.add(time);
        });
        JSONObject result = new JSONObject();
        result.put("dateTimes",dataTimes);
        return result;
    }

    @Override
    public IPage<HousePriceDto> queryPageHistory(HousePriceDto housePriceDto, Integer pageNumber, Integer pageSize) {
        List<HousePriceDto> pageList = Collections.emptyList();
        int total = housePriceDao.queryTotalThree(housePriceDto);
        if (total != 0) {
            pageList = housePriceDao.queryListThree(housePriceDto, pageNumber, pageSize);
        }
        IPage<HousePriceDto> result = new IPage<>();
        result.setPageList(pageList);
        result.setPage(pageNumber);
        result.setRows(pageSize);
        result.setTotal(total);
        result.setTotalPage((int) Math.ceil((double) total / pageSize));
        return result;
    }

    @Override
    public List<House> queryHouseListByManagerId(String managerId) {
        if (StringUtils.isBlank(managerId)) return Collections.emptyList();
        String sqlx = String.format(" and manager_id = %s %s", managerId, " order by id desc");
        return houseDao.queryList(sqlx);
    }

    @Override
    public JSONObject queryPageHouseListByManagerId(String managerId, Integer pageNumber, Integer pageSize) {
        Assert.hasLength(managerId,"商家id不能为空！");
        Assert.notNull(pageNumber,"页码不能为空！");
        Assert.notNull(pageSize,"每页数量不能为空！");
        String sqlx = String.format(" and manager_id = %s", managerId);
        int total = houseDao.queryTotal(sqlx);
        String sql = String.format(" and manager_id = %s order by id desc limit %s, %s", managerId, (pageNumber - 1) * pageSize, pageSize);
        List<House> houseList =  Collections.emptyList();
        if (total != 0) {
            houseList = houseDao.queryList(sql);
        }
        JSONObject result = new JSONObject();
        result.put("pageList",houseList);
        result.put("page",pageNumber);
        result.put("rows",pageSize);
        result.put("total",total);
        result.put("totalPage",(int) Math.ceil((double) total / pageSize));
        return result;
    }

    @Override
    public void exportHistory(HousePriceDto housePriceDto) {
        if (StringUtils.isBlank(housePriceDto.getManagerId())) return;
        List<HousePriceDto> list = housePriceDao.queryListThree(housePriceDto, null, null);
        if (list == null || list.isEmpty()) return;
        // List<Vector<Object>> vectorsList = new ArrayList<>();
        List<Vector> vectorsList = new ArrayList<>();
        list.forEach(housePrice -> {
            Vector columnValue = new Vector<>();
            columnValue.add(housePrice.getHouseName());
            columnValue.add(housePrice.getSetDate());
            columnValue.add(housePrice.getPrice());
            columnValue.add(housePrice.getOperationName());
            columnValue.add(housePrice.getOperationTime());
            vectorsList.add(columnValue);
        });
        // 项目路径地址
        String path = ServletActionContext.getRequest().getSession().getServletContext()
                .getRealPath("/download/");// File.separator
        Vector<String> columnName = new Vector<>();
        columnName.add("房型");
        columnName.add("价格日期");
        columnName.add("修改后价格");
        columnName.add("操作人");
        columnName.add("操作时间");
        String filePathName = "改价记录" + UUIDUtil.generateID() + "Report.xls";

        // 导出文件
        new toExcel().book(vectorsList, path + filePathName,
                "sheet1", columnName);
        String url = WeiXinUtil.ip_h;//"https://chtech.ncjti.edu.cn/hotelReservation/mhotel";
        JSONObject result = new JSONObject();
        result.put("downurl", url + "/download/" + filePathName);
        result.put("code", 200);
        result.put("message", "导出成功");
        ResponseUtil.writeJson(ServletActionContext.getResponse(),
                result.toString());
    }

    /**
     * 获取房型指定日期的价格
     *
     * @return 原价 or 周日内最新一条改价记录的价格
     */
    private Double getPrice(Date dateIn, HousePriceDto housePriceDto, List<HousePriceDto> housePriceDtoList) {
        Double price = housePriceDto.getOriginalPrice();
        if (housePriceDtoList == null || housePriceDtoList.isEmpty()) return price;
        for (HousePriceDto priceDto : housePriceDtoList) {
            String[] date = priceDto.getSetDate().split(",");
            Date startDate = DateUtil.parseDateOnly(date[0]);
            Date endDate = DateUtil.parseDateOnly(date[1]);
            assert startDate != null;
            boolean flag = DateUtil.isEffectiveDate(dateIn, startDate, endDate) && housePriceDto.getHouseId().equals(priceDto.getHouseId());
            if (flag) {
                price = priceDto.getPrice();
                break;
            }
        }
        return price;
    }

    @Override
    public List<HousePriceDataVo> queryHousePriceDatas(Integer managerId, String startTime, String endTime) {
        List<HousePriceDataVo> result = housePriceDao.queryHousePriceDatas(managerId, startTime, endTime);
        return result;
    }

    @Override
    public List<HotelPriceDataVo> queryHotelPriceDatas(String managerIds, String startTime) {
        List<HotelPriceDataVo> result = housePriceDao.queryHotelPriceDatas(managerIds, startTime);
        return result;
    }


    @Override
    public List<HousePriceDataVo> queryPriceByHouseId(String houseId, String startTime, String endTime){
        List<HousePriceDataVo> result = housePriceDao.queryPriceByHouseId(houseId, startTime, endTime);
        return result;
    }
}
