package cn.freemud.service.impl;

import cn.freemud.adapter.StoreAdapter;
import cn.freemud.base.util.DateUtil;
import cn.freemud.entities.db.OpenPlatformIappWxappConfig;
import cn.freemud.entities.db.OpenPlatformIappWxappConfigDelivery;
import cn.freemud.entities.db.OpenPlatformPartnerStoreDeliveryConfig;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.manager.*;
//import cn.freemud.service.thirdparty.StoreClient;
import cn.freemud.service.thirdparty.DeliveryFeiginClient;
import cn.freemud.utils.*;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.geom.Point2D;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class StoreServiceImpl {

    private Logger log = LoggerFactory.getLogger(StoreServiceImpl.class);

    private final Integer RESPONSE_SUCCESS_CODE = 100;

    private static Gson gson = new Gson();

    @Autowired
    private StoreAdapter storeAdapter;
//    @Autowired
//    private StoreClient storeClient;
    @Autowired
    private IappWxappConfigManager iappWxappConfigManager;
    @Autowired
    private OpenPlatformPartnerStoreDeliveryConfigManager deliveryConfigManager;
    @Autowired
    private OpenPlatformIappWxappConfigDeliveryManager openPlatformIappWxappConfigDeliveryManager;
    @Autowired
    private OpenPlatformIappWxappConfigManager openPlatformIappWxappConfigManager;
    @Autowired
    private DeliveryFeiginClient deliveryFeiginClient;
    /**
     * 确定门店是否打烊
     */
    public boolean checkStoreOpen(String businessHoursDay) {
        if (StringUtils.isBlank(businessHoursDay)) {
            return false;
        }
        String businessHourStr = businessHoursDay.replace("-", ",").replace("_", ",");
        String[] businessHours = businessHourStr.split(",");
        if (businessHours.length != 2) {
            log.error("checkStoreOpen businessHoursDay is invaild , businessHoursDay：{}", businessHoursDay);
            return false;
        }
        String startDateTimeStr = DateUtil.convert2String(new Date(), DateUtil.FORMAT_YMD) + " " + businessHours[0] + ":00";
        Date startDateTime = DateUtil.convert2Date(startDateTimeStr, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
        String endDateTimeStr = DateUtil.convert2String(new Date(), DateUtil.FORMAT_YMD) + " " + businessHours[1] + ":00";
        SimpleDateFormat hhmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date endDateTime;
        try {
            endDateTime = hhmmss.parse(endDateTimeStr);
        } catch (ParseException e) {
            log.error("checkStoreOpen businessHoursDay endDateTimeStr is invaild , endDateTimeStr：{}", endDateTimeStr);
            return false;
        }
        Date nowDate = new Date();
        if (startDateTime != null && endDateTime != null && nowDate.getTime() >= startDateTime.getTime()
                && nowDate.getTime() <= endDateTime.getTime()) {
            return true;
        }
        return false;
    }




    /**
     * 查询门店图片（1 :门店banner  2:门店照片）
     */
//    private List<StoreImagesResponseVo> getStoreImages(String partnerId, String storeId, Integer typeFlag) {
//        StoreImagesRequestDto storeImagesRequestDto = storeAdapter.convert2StoreImagesRequestDto(partnerId, storeId, typeFlag);
//        try {
//            StoreBaseResponseDto<StoreImageListResponseDto> storeImages = storeClient.findStoreImages(storeImagesRequestDto);
//            if (!RESPONSE_SUCCESS_CODE.equals(storeImages.getStatusCode()) || storeImages.getBizVO() == null
//                    || CollectionUtils.isEmpty(storeImages.getBizVO().getList())) {
//                log.info("getStoreImages storeImages:{}", gson.toJson(storeImages));
//                return Collections.emptyList();
//            }
//            List<StoreImgResponseDto> storeImgResponseDtos = storeImages.getBizVO().getList();
//            List<StoreImagesResponseVo> images = new ArrayList<>();
//            for (int i = 0; i < storeImgResponseDtos.size(); i++) {
//                storeImgResponseDtos.get(i).getImg().forEach(storeImgResponseDto -> {
//                    StoreImagesResponseVo storeImagesResponse = new StoreImagesResponseVo();
//                    storeImagesResponse.setImageUrl(storeImgResponseDto.getImageUrl());
//                    images.add(storeImagesResponse);
//                });
//            }
//            return images;
//        } catch (Exception e) {
//            log.error("findStoreImages is error !!!", e);
//            return Collections.emptyList();
//        }
//    }

    /**
     * 获取门店信息
     */
//    public StoreResponseDto getStoreInfo(String partnerId, String storeCode) {
//        StoreInfoRequestDto storeInfoRequestDto = new StoreInfoRequestDto(partnerId, storeCode);
//        LogUtil.info("getStoreInfo_request_start", gson.toJson(storeInfoRequestDto), null);
//        StoreBaseResponseDto<StoreResponseDto> response;
//        try {
//            // 根据商户ID 和 门店编码查询门店信息
//            response = storeClient.getStoreInfo(storeInfoRequestDto);
//            LogUtil.info("getStoreInfo_request_end", gson.toJson(storeInfoRequestDto), gson.toJson(response));
//            if (!RESPONSE_SUCCESS_CODE.equals(response.getStatusCode()) || response.getBizVO() == null) {
//                LogUtil.info("getStoreInfo 获取门店信息失败", gson.toJson(storeInfoRequestDto), gson.toJson(response));
//                throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
//            }
//        } catch (Exception e) {
//            LogUtil.error("getStoreInfo 获取门店信息异常", gson.toJson(storeInfoRequestDto), gson.toJson(storeInfoRequestDto), e);
//            log.error("getStoreInfo is error ,storeInfoRequestDto:{} !! ", storeInfoRequestDto, e);
//            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
//        }
//        StoreResponseDto storeResponseDto = response.getBizVO();
//        //TODO 设置营业开始和结束时间
//        String businessHourStr = storeResponseDto.getBusinessHoursDay().replace("-", ",").replace("_", ",");
//        String[] businessHours = businessHourStr.split(",");
//        if (businessHours.length != 2) {
//            log.error("checkStoreOpen businessHoursDay is invaild , businessHoursDay：{}", storeResponseDto.getBusinessHoursDay());
//            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
//        }
//        String startDateTimeStr = DateUtil.convert2String(new Date(), DateUtil.FORMAT_YMD) + " " + businessHours[0] + ":00";
//        Date startDateTime = DateUtil.convert2Date(startDateTimeStr, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
//        String endDateTimeStr = DateUtil.convert2String(new Date(), DateUtil.FORMAT_YMD) + " " + businessHours[1] + ":00";
//        SimpleDateFormat hhmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Date endDateTime;
//        try {
//            endDateTime = hhmmss.parse(endDateTimeStr);
//        } catch (ParseException e) {
//            log.error("checkStoreOpen businessHoursDay endDateTimeStr is invaild , endDateTimeStr：{}", endDateTimeStr);
//            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
//        }
//        storeResponseDto.setBusinessHoursDayStartTime(startDateTime);
//        storeResponseDto.setBusinessHoursDayEndTime(endDateTime);
//        //TODO 设置门店图片
//        List<StoreImagesResponseVo> storeImagesResponseVos = getStoreImages(partnerId, storeResponseDto.getStoreId(), 2);
//        if (CollectionUtils.isNotEmpty(storeImagesResponseVos)) {
//            storeResponseDto.setImageUrl(storeImagesResponseVos.get(0).getImageUrl());
//        }
//        //TODO 查询门店外卖配送信息
//        OpenPlatformPartnerStoreDeliveryConfig deliveryConfig = deliveryConfigManager.findByPartnerIdAndStoreCode(partnerId, storeCode);
//        storeResponseDto.setStoreDeliveryConfig(deliveryConfig);
//        return storeResponseDto;
//    }

    /**
     * 获取门店配送信息
     */
    public StoreDeliveryInfoDto getStoreDeliveryInfo(StoreResponseDto storeResponseDto, String wxAppid) {
        if (storeResponseDto == null) {
            return null;
        }
        StoreDeliveryInfoDto storeDeliveryInfoDto = new StoreDeliveryInfoDto();
        storeDeliveryInfoDto.setPartnerId(storeResponseDto.getPartnerId());
        storeDeliveryInfoDto.setStoreId(storeResponseDto.getStoreCode());
        storeDeliveryInfoDto.setStoreName(storeResponseDto.getStoreName());
        //TODO 查询外卖配送信息
        OpenPlatformPartnerStoreDeliveryConfig deliveryConfig = deliveryConfigManager.findByPartnerIdAndStoreCode(storeResponseDto.getPartnerId(),
                storeResponseDto.getStoreCode());
        //TODO 判断门店是否启用外卖，只有当小程序开通外卖，且门店开通外卖,设置 外卖配送时间 才开启外卖功能
        boolean hasTakeaway = checkStoreHasTakeaway(storeResponseDto, deliveryConfig, wxAppid);
        storeDeliveryInfoDto.setEnableTakeaway(hasTakeaway);
        storeDeliveryInfoDto.setDeliveryLimitAmount(deliveryConfig == null ? 0 : deliveryConfig.getDeliveryLimitAmount());
        storeDeliveryInfoDto.setDeliveryAmount(deliveryConfig == null ? 0 : deliveryConfig.getDeliveryAmount());
        storeDeliveryInfoDto.setDefaultDeliveryRange(deliveryConfig == null ? 0L : deliveryConfig.getDefaultDeliveryRange());
        storeDeliveryInfoDto.setAddRangeAmount(deliveryConfig == null ? 0L : deliveryConfig.getAddRangeAmount());
        storeDeliveryInfoDto.setAddRangeCount(deliveryConfig == null ? 0L : deliveryConfig.getAddRangeCount());
        storeDeliveryInfoDto.setPoint2DList(getDeliveryPoint2DList(storeResponseDto.getDistributionScope()));
        storeDeliveryInfoDto.setDeliveryHoursDay(storeResponseDto.getDeliveryHoursDay());
        if (StringUtils.isNotBlank(storeDeliveryInfoDto.getDeliveryHoursDay())) {
            String businessHourStr = storeDeliveryInfoDto.getDeliveryHoursDay().replace("-", ",").replace("_", ",");
            String[] businessHours = businessHourStr.split(",");
            if (businessHours.length == 2) {
                SimpleDateFormat hhmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
                String startDateTimeStr = yyyyMMdd.format(new Date()) + " " + businessHours[0] + ":00";
                String endDateTimeStr = yyyyMMdd.format(new Date()) + " " + businessHours[1] + ":00";
                try {
                    storeDeliveryInfoDto.setDeliveryStartTime(hhmmss.parse(startDateTimeStr));
                    storeDeliveryInfoDto.setDeliveryEndTime(hhmmss.parse(endDateTimeStr));
                } catch (Exception e) {
                    LogUtil.info("getStoreDeliveryInfo parse deliveryHoursDay error", storeDeliveryInfoDto.getDeliveryHoursDay(), null);
                }
            }
        }
        storeDeliveryInfoDto.setLongitude(storeResponseDto.getLongitude());
        storeDeliveryInfoDto.setLatitude(storeResponseDto.getLatitude());
        storeDeliveryInfoDto.setScopeConfig(storeResponseDto.getScopeConfig());
        if (StringUtils.isNotEmpty(storeResponseDto.getDeliveryRadius())) {
            storeDeliveryInfoDto.setDeliveryRadius(Integer.valueOf(storeResponseDto.getDeliveryRadius()));
        } else {
            storeDeliveryInfoDto.setDeliveryRadius(0);
        }

        // 只有小程序设置了外卖，并且开通了第三方配送账户，才是第三方配送单
        OpenPlatformIappWxappConfig openPlatformIappWxappConfig = openPlatformIappWxappConfigManager.selectIappWxappConfigByWxAppId(wxAppid);
        if (openPlatformIappWxappConfig == null) {

            storeDeliveryInfoDto.setDeliveryType("self");
            storeDeliveryInfoDto.setPushOrderTime(0);
        } else {
            if (ObjectUtils.equals(openPlatformIappWxappConfig.getTakeType(), 1)) {
                storeDeliveryInfoDto.setDeliveryType("self");
                storeDeliveryInfoDto.setPushOrderTime(0);
            } else {
                OpenPlatformIappWxappConfigDelivery deliveryConfigByAppid = openPlatformIappWxappConfigDeliveryManager.findDeliveryConfigByAppid(wxAppid);
                if (deliveryConfigByAppid == null) {
                    storeDeliveryInfoDto.setDeliveryType("self");
                    storeDeliveryInfoDto.setPushOrderTime(0);
                } else {
                    storeDeliveryInfoDto.setDeliveryType("thrid");
                    if (ObjectUtils.equals(deliveryConfigByAppid.getPushOrderType(), 1)) {
                        storeDeliveryInfoDto.setPushOrderTime(deliveryConfigByAppid.getPushOrderTime());
                    } else {
                        storeDeliveryInfoDto.setPushOrderTime(0);
                    }
                }
            }
        }
        return storeDeliveryInfoDto;
    }

    /**
     * 通过用户地址获取实际配送信息
     *
     * @param storeDeliveryInfoDto 门店配送信息
     * @param userLongitude        用户配送地址经度
     * @param userLatitude         用户配送地址维度
     * @return
     */
    public UserDeliveryInfoDto getUserDeliveryInfo(StoreDeliveryInfoDto storeDeliveryInfoDto, String userLongitude, String userLatitude) {
        UserDeliveryInfoDto userDeliveryInfoDto = UserDeliveryInfoDto.builder()
                .userLongitude(userLongitude)
                .userLatitude(userLatitude)
                .deliveryLimitAmount(storeDeliveryInfoDto.getDeliveryLimitAmount())
                .userEnableTakeaway(checkUserEnableDelivery(storeDeliveryInfoDto, userLongitude, userLatitude))
                .realDeliveryAmount(getUserRealDeliveryAmount(storeDeliveryInfoDto, userLongitude, userLatitude))
                .storeId(storeDeliveryInfoDto.getStoreId())
                .storeName(storeDeliveryInfoDto.getStoreName())
                .storeDeliveryInfoDto(storeDeliveryInfoDto).build();
        return userDeliveryInfoDto;

    }


    /**
     * 获取配送范围内集合
     */
    public List<Point2D.Double> getDeliveryPoint2DList(String distributionScope) {
        if (StringUtils.isBlank(distributionScope)) {
            return Collections.emptyList();
        }
        /**
         * 如果点不为整数，返回空
         */
        String[] points = distributionScope.split(",");
        if (points.length % 2 != 0) {
            return Collections.emptyList();
        }
        List<String> pointList = Arrays.asList(points);
        List<Point2D.Double> point2DList = Lists.newArrayList();
        for (int i = 0; i < pointList.size(); i++) {
            Double pointX = Double.parseDouble(pointList.get(i));
            Double pointY = Double.parseDouble(pointList.get(++i));
            point2DList.add(new Point2D.Double(pointX, pointY));
        }
        return point2DList;
    }

    /**
     * 判断门店是否开启外卖
     */
    public boolean checkStoreHasTakeaway(StoreResponseDto storeResponseDto, OpenPlatformPartnerStoreDeliveryConfig deliveryConfig, String wxAppid) {
        SimpleDateFormat hhmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (deliveryConfig == null) {
            return false;
        }
        if (storeResponseDto.getDelivery() == null || storeResponseDto.getDelivery() == 2) {
            return false;
        }
        OpenPlatformIappWxappConfig iappWxappConfig = iappWxappConfigManager.findIappWxappConfigByWxAppid(wxAppid);
        if (iappWxappConfig == null || iappWxappConfig.getTakeaway() == null || iappWxappConfig.getTakeaway() == 0) {
            return false;
        }
        if (StringUtils.isNotBlank(storeResponseDto.getDeliveryHoursDay()) && storeResponseDto.getDelivery() != null
                && storeResponseDto.getDelivery() == 1) {
            String deliveryStr = storeResponseDto.getDeliveryHoursDay().replace("-", ",")
                    .replace("_", ",");
            String[] deliverys = deliveryStr.split(",");
            if (deliverys.length == 2) {
                String endDateTimeStr = DateUtil.convert2Str(new Date(), DateUtil.FORMAT_yyyyMMdd_date) + " " + deliverys[1] + ":00";
                Date endDate = null;
                try {
                    endDate = hhmmss.parse(endDateTimeStr);
                } catch (ParseException e) {
                    LogUtil.info("getStoreDeliveryInfo endDate format error", endDateTimeStr, null);
                    return false;
                }
                if (endDate == null || new Date().after(endDate)) {
                    return false;
                }
            }
        }
        return true;
    }


    /**
     * 判断收货地址是否在配送范围
     *
     * @param storeDeliveryInfoDto 门店配送信息
     * @param userLongitude        用户经度
     * @param userLatitude         用户维度
     * @return
     */
    public boolean checkUserEnableDelivery(StoreDeliveryInfoDto storeDeliveryInfoDto, String userLongitude, String userLatitude) {
        if (!storeDeliveryInfoDto.getEnableTakeaway()) {
            return false;
        }
        //兼容老版本 为空设置默认按自定义配送
        if (storeDeliveryInfoDto.getScopeConfig() == null) {
            storeDeliveryInfoDto.setScopeConfig(ScopeConfigType.DEFINITION.getCode());
        }
        if (ScopeConfigType.getByCode(storeDeliveryInfoDto.getScopeConfig()) == null) {
            return false;
        }
        ScopeConfigType scopeConfigType = ScopeConfigType.getByCode(storeDeliveryInfoDto.getScopeConfig());
        if (ScopeConfigType.RADIUS.equals(scopeConfigType)) {
            if (storeDeliveryInfoDto.getDeliveryRadius() == null || storeDeliveryInfoDto.getDeliveryRadius() <= 0) {
                return false;
            }
            //用户收货地址距离门店距离 单位米
            double distance = getDistance(storeDeliveryInfoDto.getLongitude(), storeDeliveryInfoDto.getLatitude(),
                    userLongitude, userLatitude);
            if (distance > storeDeliveryInfoDto.getDeliveryRadius().doubleValue()) {
                return false;
            }
            return true;
        }
        List<Point2D.Double> points = storeDeliveryInfoDto.getPoint2DList();
        if (CollectionUtils.isEmpty(points)) {
            return false;
        }
        Point2D.Double point2D = new Point2D.Double(Double.parseDouble(userLongitude), Double.parseDouble(userLatitude));
        return WebUtil.IsPtInPoly(point2D, points);
    }

    /**
     * 计算用户收货地址实际配送费
     *
     * @param storeDeliveryInfoDto 门店配送信息
     * @param userLongitude        用户地址经度
     * @param userLatitude         用户地址维度
     * @return
     */
    public Long getUserRealDeliveryAmount(StoreDeliveryInfoDto storeDeliveryInfoDto, String userLongitude, String userLatitude) {
        if (!checkUserEnableDelivery(storeDeliveryInfoDto, userLongitude, userLatitude)) {
            return 0L;
        }
        // TODO 用户收货地址距离门店距离 单位米 如果门店没有设置阶层配送费，配送费默认=基础配送费
        if (storeDeliveryInfoDto.getAddRangeCount() == null || storeDeliveryInfoDto.getAddRangeCount() <= 0) {
            return storeDeliveryInfoDto.getDeliveryAmount();
        }
        if (storeDeliveryInfoDto.getAddRangeAmount() == null || storeDeliveryInfoDto.getAddRangeAmount() <= 0) {
            return storeDeliveryInfoDto.getDeliveryAmount();
        }
        double distance = getDistance(storeDeliveryInfoDto.getLongitude(), storeDeliveryInfoDto.getLatitude(),
                userLongitude, userLatitude);
        Long defaultDeliveryRange = storeDeliveryInfoDto.getDefaultDeliveryRange();
        Long deliveryAmount = storeDeliveryInfoDto.getDeliveryAmount();
        Long addRangeCount = storeDeliveryInfoDto.getAddRangeCount();
        Long addRangeAmount = storeDeliveryInfoDto.getAddRangeAmount();
        if (new BigDecimal(distance).compareTo(new BigDecimal(defaultDeliveryRange)) <= 0) {
            return deliveryAmount;
        } else {
            //计算实际配送费
            BigDecimal extraAmount = (new BigDecimal(distance).subtract(new BigDecimal(defaultDeliveryRange)))
                    .divide(new BigDecimal(addRangeCount), 0, BigDecimal.ROUND_UP)
                    .multiply(new BigDecimal(addRangeAmount));
            BigDecimal realAmount = new BigDecimal(deliveryAmount).add(extraAmount);
            return realAmount.longValue();
        }
    }




    /**
     * 获取两个点的距离 单位米
     *
     * @param shopLng
     * @param shopLat
     * @param addressLng
     * @param addressLat
     * @return
     */
    public double getDistance(String shopLng, String shopLat, String addressLng, String addressLat) {
//        return WebUtil.calDistance(Double.valueOf(shopLng), Double.valueOf(shopLat), Double.valueOf(addressLng), Double.valueOf(addressLat));
        QueryDeliveryDistanceResponseVo responseVo = deliveryFeiginClient.queryDeliveryDistance(new QueryDeliveryDistanceRequest(Double.parseDouble(shopLat), Double.parseDouble(shopLng), Double.parseDouble(addressLat), Double.parseDouble(addressLng)));
        if (responseVo == null || responseVo.getCode() != 100 || responseVo.getData().getDistance() == null) {
            throw new ServiceException(ResponseResult.STORE_DELIVERY_AMOUNT_ERROR);
        }
        return responseVo.getData().getDistance();
    }

}
