package cn.freemud.adapter;

import cn.freemud.entities.dto.*;
import cn.freemud.entities.vo.AddDeliveryAddressVo;
import cn.freemud.entities.vo.CreateOrderVo;
import cn.freemud.entities.vo.QueryReceiveAddressResponseVo;
import cn.freemud.entities.vo.UserLoginVo;
import cn.freemud.enums.ReceiveAddressLabelType;
import cn.freemud.enums.SexType;
import cn.freemud.manager.OpenPlatformPartnerStoreDeliveryConfigManager;
import cn.freemud.service.impl.StoreServiceImpl;
import cn.freemud.utils.UnicodeUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class UserAdapter {

    @Autowired
    private OpenPlatformPartnerStoreDeliveryConfigManager deliveryConfigManager;
    @Autowired
    private StoreServiceImpl storeService;

    public MemberRegisterDto getMemberRegister(String mobile, String openid, String partnerId) {
        MemberRegisterDto memberRegisterDto = new MemberRegisterDto();
        memberRegisterDto.setMobile(mobile);
        memberRegisterDto.setThirdPartyCode(openid);
        memberRegisterDto.setPartnerId(partnerId);
        memberRegisterDto.setChannelCode("dcxcx");
        memberRegisterDto.setChannelType("1");
        memberRegisterDto.setRegisterType("2");
        memberRegisterDto.setVer("1");
        return memberRegisterDto;
    }

    public UserLoginVo getUserLoginVo(String sessionId, String mobile, Integer registered) {
        UserLoginVo userLoginVo = new UserLoginVo();
        userLoginVo.setSessionId(sessionId);
        userLoginVo.setMobile(mobile);
        userLoginVo.setRegistered(registered);
        return userLoginVo;
    }

    public EditMemberInfo getEditMemberInfo(String memberId, String partnerId, String mobile) {
//        return EditMemberInfo.builder()
//                .memberId(memberId)
//                .partnerId(partnerId)
//                .mobile(mobile)
//                .ver("1").build();
        return null;
    }

    public UserLoginInfoDto getUserLoginInfoDto(Map<String, Object> map) {
        UserLoginInfoDto userLoginInfoDto = new UserLoginInfoDto();
        userLoginInfoDto.setOpenId(String.valueOf(map.get("openid")));
        userLoginInfoDto.setWxAppid(String.valueOf(map.get("wxAppid")));
        userLoginInfoDto.setSessionKey(String.valueOf(map.get("session_key")));
        userLoginInfoDto.setMobile(String.valueOf(map.get("mobile")));
        userLoginInfoDto.setAppsecret(String.valueOf(map.get("appsecret")));
        userLoginInfoDto.setMemberId(String.valueOf(map.get("memberId")));
        userLoginInfoDto.setPartnerId(String.valueOf(map.get("partnerId")));
        userLoginInfoDto.setUnionId(String.valueOf(map.get("unionId")));
        userLoginInfoDto.setNewMemeber(Boolean.valueOf(map.get("newMember").toString()));
        return userLoginInfoDto;
    }


    public QueryReceiveAddressResponseVo getQueryReceiveAddress(GetReceiveAddressListResponseDto responseDto,
                                                                StoreDeliveryInfoDto storeDeliveryInfoDto) {
        QueryReceiveAddressResponseVo queryReceiveAddressResponseVo = new QueryReceiveAddressResponseVo();
        if (responseDto.getData() == null || CollectionUtils.isEmpty(responseDto.getData().getList())) {
            queryReceiveAddressResponseVo.setTotal(0);
            queryReceiveAddressResponseVo.setPageNo(1);
            queryReceiveAddressResponseVo.setPageSize(10);
            queryReceiveAddressResponseVo.setDisableDeliveryList(Collections.emptyList());
            queryReceiveAddressResponseVo.setEnableDeliveryList(Collections.emptyList());
            queryReceiveAddressResponseVo.setList(Collections.emptyList());
            return queryReceiveAddressResponseVo;
        }
        List<QueryReceiveAddressResponseVo.ReceivingAddress> list = Lists.newArrayList();
        //TODO 判断门店是否可配送 如果不可配送 配送地址都不可用
        for (GetReceiveAddressListResponseDto.ResultBean.ReceivingAddress receiveAddress : responseDto.getData().getList()) {
            QueryReceiveAddressResponseVo.ReceivingAddress responseAddress = new QueryReceiveAddressResponseVo.ReceivingAddress();
            responseAddress.setReceiveId(receiveAddress.getAddressId());
            responseAddress.setLatitude(receiveAddress.getLatitude());
            responseAddress.setLongitude(receiveAddress.getLongitude());
            if (storeDeliveryInfoDto != null) {
                responseAddress.setDistance(storeService.getDistance(storeDeliveryInfoDto.getLongitude(), storeDeliveryInfoDto.getLatitude(),
                        receiveAddress.getLongitude(), receiveAddress.getLatitude()));
            }
            responseAddress.setSex(receiveAddress.getSex());
            responseAddress.setIsDefault(receiveAddress.getIsDefault());
            responseAddress.setSexDesc(Optional.ofNullable(SexType.getByCode(receiveAddress.getSex())).map(SexType::getDesc).orElse(""));
            String officeName = "";
            String receiveAddressStr = receiveAddress.getReceiveAddress();
            if (StringUtils.isNotBlank(receiveAddressStr)) {
                if (receiveAddressStr.contains("officeName") && receiveAddressStr.contains("address")) {
                    JSONObject jsonObject = JSONObject.parseObject(receiveAddressStr);
                    officeName = jsonObject.getString("officeName");
                    receiveAddressStr = jsonObject.getString("address");
                }
            }
            responseAddress.setOfficeName(officeName);
            responseAddress.setReceiveAddress(receiveAddressStr);
            responseAddress.setReceiveUsername(receiveAddress.getReceiveName());
            responseAddress.setReceiveMobile(receiveAddress.getMobile());
            responseAddress.setLabel(ReceiveAddressLabelType.getByCode(receiveAddress.getLabelType()) != null ?
                    ReceiveAddressLabelType.getByCode(receiveAddress.getLabelType()).getDesc() : "");

            //TODO 判断收货地址是否可配送 计算实际配送费 如果storeDeliveryInfoDto为空，默认查询用户地址信息
            if (storeDeliveryInfoDto != null) {
                UserDeliveryInfoDto userDeliveryInfoDto = storeService.getUserDeliveryInfo(storeDeliveryInfoDto, receiveAddress.getLongitude(), receiveAddress.getLatitude());
                responseAddress.setEnableTakeaway(userDeliveryInfoDto.getUserEnableTakeaway());
                responseAddress.setDeliveryAmount(userDeliveryInfoDto.getRealDeliveryAmount());
            } else {
                responseAddress.setEnableTakeaway(false);
                responseAddress.setDeliveryAmount(0L);
            }
            list.add(responseAddress);
        }
        List<QueryReceiveAddressResponseVo.ReceivingAddress> enableDeliveryList = list.stream().filter(QueryReceiveAddressResponseVo.ReceivingAddress::getEnableTakeaway).collect(Collectors.toList());
        List<QueryReceiveAddressResponseVo.ReceivingAddress> disableDeliveryList = list.stream().filter(p -> !p.getEnableTakeaway()).collect(Collectors.toList());

        queryReceiveAddressResponseVo.setTotal(list.size());
        queryReceiveAddressResponseVo.setPageNo(responseDto.getData().getPageNum());
        queryReceiveAddressResponseVo.setPageSize(responseDto.getData().getPageSize());
        queryReceiveAddressResponseVo.setEnableDeliveryList(enableDeliveryList);
        queryReceiveAddressResponseVo.setDisableDeliveryList(disableDeliveryList);
        queryReceiveAddressResponseVo.setTotal(list.size());
        queryReceiveAddressResponseVo.setList(list);

        //按照默认地址排序
        if (CollectionUtils.isNotEmpty(queryReceiveAddressResponseVo.getList())) {
            queryReceiveAddressResponseVo.getList().sort(Comparator.comparing(QueryReceiveAddressResponseVo.ReceivingAddress::getIsDefault).reversed());
        }
        if (storeDeliveryInfoDto != null) {
            if (CollectionUtils.isNotEmpty(queryReceiveAddressResponseVo.getEnableDeliveryList())) {
                queryReceiveAddressResponseVo.getEnableDeliveryList().sort(Comparator.comparing(QueryReceiveAddressResponseVo.ReceivingAddress::getDistance));
            }
            if (CollectionUtils.isNotEmpty(queryReceiveAddressResponseVo.getDisableDeliveryList())) {
                queryReceiveAddressResponseVo.getDisableDeliveryList().sort(Comparator.comparing(QueryReceiveAddressResponseVo.ReceivingAddress::getDistance));
            }
        }
        return queryReceiveAddressResponseVo;
    }

    public AddReceiveAddressDto convent2AddReceiveAddressDto(CreateOrderVo createOrderVo, String partnerId, String userId) {
        AddReceiveAddressDto addReceiveAddressDto = new AddReceiveAddressDto();
        addReceiveAddressDto.setMemberId(userId);
        addReceiveAddressDto.setIsDefault(2);
        addReceiveAddressDto.setLabelType(1);
        addReceiveAddressDto.setLatitude(createOrderVo.getLatitude());
        addReceiveAddressDto.setLongitude(createOrderVo.getLongitude());
        addReceiveAddressDto.setPartnerId(partnerId);
        String officeName = UnicodeUtil.filterSpecialChars(createOrderVo.getOfficeName());
        String receiveAddress = UnicodeUtil.filterSpecialChars(createOrderVo.getReceiveAddress());
        String receiveUserName = UnicodeUtil.filterSpecialChars(createOrderVo.getReceiveUsername());
        Map<String, String> addressMap = Maps.newTreeMap();
        addressMap.put("officeName", officeName);
        addressMap.put("address", receiveAddress);
        addReceiveAddressDto.setReceiveAddress(new Gson().toJson(addressMap));
        addReceiveAddressDto.setMobile(createOrderVo.getReceiveMobile());
        addReceiveAddressDto.setReceiveName(receiveUserName);
        addReceiveAddressDto.setSex(createOrderVo.getSex());
        return addReceiveAddressDto;
    }

    public AddReceiveAddressDto convent2AddReceiveAddressDto(AddDeliveryAddressVo addDeliveryAddressVo, String partnerId, String userId) {
        AddReceiveAddressDto addReceiveAddressDto = new AddReceiveAddressDto();
        addReceiveAddressDto.setMemberId(userId);
        addReceiveAddressDto.setIsDefault(2);
        addReceiveAddressDto.setLabelType(Optional.ofNullable(ReceiveAddressLabelType.getByDesc(addDeliveryAddressVo.getLabel()))
                .map(ReceiveAddressLabelType::getCode).orElse(1));
        addReceiveAddressDto.setLatitude(addDeliveryAddressVo.getLatitude());
        addReceiveAddressDto.setLongitude(addDeliveryAddressVo.getLongitude());
        addReceiveAddressDto.setPartnerId(partnerId);
        String officeName = UnicodeUtil.filterSpecialChars(addDeliveryAddressVo.getOfficeName());
        String receiveAddress = UnicodeUtil.filterSpecialChars(addDeliveryAddressVo.getReceiveAddress());
        String receiveUserName = UnicodeUtil.filterSpecialChars(addDeliveryAddressVo.getReceiveUsername());
        Map<String, String> addressMap = Maps.newTreeMap();
        addressMap.put("officeName", officeName);
        addressMap.put("address", receiveAddress);
        addReceiveAddressDto.setReceiveAddress(new Gson().toJson(addressMap));
        addReceiveAddressDto.setMobile(addDeliveryAddressVo.getReceiveMobile());
        addReceiveAddressDto.setReceiveName(receiveUserName);
        addReceiveAddressDto.setSex(addDeliveryAddressVo.getSex());
        return addReceiveAddressDto;
    }

    public UpdateReceiveAddressDto convent2UpdateReceiveAddressDto(AddDeliveryAddressVo addDeliveryAddressVo, String partnerId, String userId) {
        UpdateReceiveAddressDto updateReceiveAddressDto = new UpdateReceiveAddressDto();
        updateReceiveAddressDto.setAddressId(addDeliveryAddressVo.getReceiveId());
        updateReceiveAddressDto.setReceiveId(addDeliveryAddressVo.getReceiveId());
        updateReceiveAddressDto.setMemberId(userId);
        updateReceiveAddressDto.setIsDefault(true);
        updateReceiveAddressDto.setLabelType(Optional.ofNullable(ReceiveAddressLabelType.getByDesc(addDeliveryAddressVo.getLabel()))
                .map(ReceiveAddressLabelType::getCode).orElse(1));
        updateReceiveAddressDto.setLatitude(addDeliveryAddressVo.getLatitude());
        updateReceiveAddressDto.setLongitude(addDeliveryAddressVo.getLongitude());
        updateReceiveAddressDto.setPartnerId(partnerId);
        String officeName = UnicodeUtil.filterSpecialChars(addDeliveryAddressVo.getOfficeName());
        String receiveAddress = UnicodeUtil.filterSpecialChars(addDeliveryAddressVo.getReceiveAddress());
        String receiveUserName = UnicodeUtil.filterSpecialChars(addDeliveryAddressVo.getReceiveUsername());
        Map<String, String> addressMap = Maps.newTreeMap();
        addressMap.put("officeName", officeName);
        addressMap.put("address", receiveAddress);
        updateReceiveAddressDto.setReceiveAddress(new Gson().toJson(addressMap));
        updateReceiveAddressDto.setMobile(addDeliveryAddressVo.getReceiveMobile());
        updateReceiveAddressDto.setReceiveName(receiveUserName);
        updateReceiveAddressDto.setSex(addDeliveryAddressVo.getSex());
        return updateReceiveAddressDto;
    }


    public UpdateReceiveAddressDto convent2UpdateReceiveAddressDto(CreateOrderVo createOrderVo, String partnerId, String userId) {
        UpdateReceiveAddressDto updateReceiveAddressDto = new UpdateReceiveAddressDto();
        updateReceiveAddressDto.setReceiveId(createOrderVo.getReceiveId());
        updateReceiveAddressDto.setMemberId(userId);
        updateReceiveAddressDto.setIsDefault(true);
        updateReceiveAddressDto.setLabelType(ReceiveAddressLabelType.COMPANY.getCode());
        updateReceiveAddressDto.setLatitude(createOrderVo.getLatitude());
        updateReceiveAddressDto.setLongitude(createOrderVo.getLongitude());
        updateReceiveAddressDto.setPartnerId(partnerId);
        updateReceiveAddressDto.setSex(createOrderVo.getSex());
        Map<String, String> addressMap = Maps.newTreeMap();
        String officeName = UnicodeUtil.filterSpecialChars(createOrderVo.getOfficeName());
        String receiveAddress = UnicodeUtil.filterSpecialChars(createOrderVo.getReceiveAddress());
        String receiveUserName = UnicodeUtil.filterSpecialChars(createOrderVo.getReceiveUsername());
        addressMap.put("officeName", officeName);
        addressMap.put("address", receiveAddress);
        updateReceiveAddressDto.setReceiveAddress(new Gson().toJson(addressMap));
        updateReceiveAddressDto.setReceiveName(receiveUserName);
        updateReceiveAddressDto.setMobile(createOrderVo.getReceiveMobile());
        return updateReceiveAddressDto;
    }


}
