package com.liquidnet.client.admin.zhengzai.kylin.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.liquidnet.client.admin.common.exception.BusinessException;
import com.liquidnet.client.admin.common.utils.StringUtils;
import com.liquidnet.client.admin.zhengzai.kylin.dto.OrderOutLineVo;
import com.liquidnet.client.admin.zhengzai.kylin.service.IImportService;
import com.liquidnet.client.admin.zhengzai.kylin.utils.DataUtils;
import com.liquidnet.client.admin.zhengzai.kylin.utils.OrderUtils;
import com.liquidnet.commons.lang.util.*;
import com.liquidnet.service.adam.dto.vo.AdamUserInfoVo;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
import com.liquidnet.service.kylin.dto.param.SyncOrderParam;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketTimesVo;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinOrderTicketEntitiesVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinOrderTicketVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.entity.KylinOrderTicketEntities;
import com.liquidnet.service.kylin.entity.KylinOrderTicketRelations;
import com.liquidnet.service.kylin.entity.KylinOrderTicketStatus;
import com.liquidnet.service.kylin.entity.KylinOrderTickets;
import com.liquidnet.service.kylin.service.admin.IKylinPerformancesAdminService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;

@Service
public class ImportServiceImpl implements IImportService {

    @Autowired
    IKylinPerformancesAdminService kylinPerformancesService;
    @Value("${liquidnet.service.adam.url}")
    private String adamUrl;
    @Autowired
    private DataUtils dataUtils;
    @Autowired
    private OrderUtils orderUtils;
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 导入订单数据
     */
    public String importOrderOutLine(String performancesId, List<OrderOutLineVo> orderOutLineVoList, Boolean updateSupport, String operName) {
        if (StringUtils.isNull(orderOutLineVoList) || orderOutLineVoList.size() == 0) {
            throw new BusinessException("导入用户数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (OrderOutLineVo orderOutLineVo : orderOutLineVoList) {
            //获取账号维度数据
            String enterMobile = orderOutLineVo.getEnterMobile();
            String enterIdCode = orderOutLineVo.getEnterIdCode();
            String enterName = orderOutLineVo.getEnterName();
            Integer number = orderOutLineVo.getNumber();
            String address = orderOutLineVo.getAddress();
            MultiValueMap<String, String> params = new LinkedMultiValueMap();
            params.add("mobile", enterMobile);
            String returnData = HttpUtil.post(adamUrl.concat("/adam/rsc/reg/mobile"), params);
            AdamUserInfoVo adamUserInfoVo = JsonUtils.fromJson(returnData, new TypeReference<ResponseDto<AdamUserInfoVo>>() {
            }).getData();
            String uid = adamUserInfoVo.getUid();
            Boolean isMember;
            if (adamUserInfoVo.getStageMarker().equals("10") || adamUserInfoVo.getStageMarker().equals("11")) {
                isMember = true;
            } else {
                isMember = false;
            }
            //找到对应票种和场次
            String ticketTitle = orderOutLineVo.getTicketTitle();
            String startTime = orderOutLineVo.getUseStart();
            String endTime = orderOutLineVo.getUseEnd();
            KylinPerformanceVo performanceData = dataUtils.getPerformanceVo(performancesId);
            KylinTicketTimesVo ticketTimesData = null;
            KylinTicketVo ticketData = null;
            for (int x = 0; x < performanceData.getTicketTimeList().size(); x++) {
                KylinTicketTimesVo timeItem = performanceData.getTicketTimeList().get(x);
                if (timeItem.getUseStart().equals(startTime) && timeItem.getUseEnd().equals(endTime)) {
                    ticketTimesData = timeItem;
                    for (int y = 0; y < ticketTimesData.getTicketList().size(); y++) {
                        KylinTicketVo ticketItem = ticketTimesData.getTicketList().get(y);
                        if (ticketItem.getTitle().equals(ticketTitle)) {
                            ticketData = ticketItem;
                            break;
                        }
                    }
                    break;
                }
            }
            // 获取限购 实名
            int ticketLimit = ticketData.getLimitCount();//普通票种限购
            int ticketMemberLimit = ticketData.getLimitCountMember();//会员票种限购
            int performanceLimit = performanceData.getLimitCount();//普通演出限购
            int performanceMemberLimit = performanceData.getLimitCountMember();//会员演出限购
            int isTrueName = ticketData.getIsTrueName();//是否演出实名
            Integer isStudent = ticketData.getIsStudent();
            String ticketType = "";
            if (orderOutLineVo.getTicketType().contains("电子")) {
                ticketType = "electronic";
            } else if (orderOutLineVo.getTicketType().contains("快递")) {
                ticketType = "express";
            }
            //快递票判断
            if (ticketType.equals("express")) {
                if (address.isEmpty()) {
                    return "快递票未填写收货地址";
                }
            }
            //实名判断
            if (isTrueName == 1 && (enterIdCode.isEmpty() || enterName.isEmpty())) {
                return "实名票未填写入场人";
            }

            //学生票 判断
            if (isTrueName == 1) {
                if (isStudent == 1) {
                    int age = IDCard.getAgeByIdCard(enterIdCode);
                    if (age > 25) {
                        return "年龄不符合";//年龄超了
                    }
                }
            }

            //限购判断 如果实名 则身份证维度限购 如果不实名则数量限购
            if (isTrueName == 1) {
                String res1 = orderUtils.judgeOrderLimit(performanceData.getType(), uid, enterIdCode, performancesId, ticketData.getTicketsId(), performanceLimit, performanceMemberLimit, ticketLimit, ticketMemberLimit, 1, 1, 0, isTrueName);
                if (!res1.equals("")) {
                    return res1;//乱七八糟异常
                }
            } else {
                String res1 = orderUtils.judgeOrderLimit(performanceData.getType(), uid, "", performancesId, ticketData.getTicketsId(), performanceLimit, performanceMemberLimit, ticketLimit, ticketMemberLimit, number, number, 0, isTrueName);
                if (!res1.equals("")) {
                    return res1;//乱七八糟异常
                }
            }
            try {
                order(number, ticketType.equals("express") ? 1 : 0, uid, isMember, performanceData, ticketTimesData, ticketData, enterMobile, enterName, enterIdCode, address);
                successNum++;
            } catch (Exception e) {
                e.printStackTrace();
                failureNum++;
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new BusinessException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }


    private void order(Integer number, Integer IsExpress, String uid, boolean isMember,
                       KylinPerformanceVo performanceData, KylinTicketTimesVo ticketTimesVo, KylinTicketVo ticketData,
                       String enterMobile, String enterName, String enterIdCode, String address) throws Exception {
        String source = "OUTLINE";
        String version = "OUTLINE";
        LocalDateTime now = LocalDateTime.now();
        //生成订单 order_ticket
        KylinOrderTickets orderTickets = KylinOrderTickets.getNew();
        String orderTicketId = IDGenerator.nextSnowId();
        orderTickets.setOrderTicketsId(orderTicketId);
        orderTickets.setUserId(uid);
        Map token = CurrentUtil.getTokenClaims();
        orderTickets.setUserName(StringUtils.defaultString(((String) token.get("nickname")), ""));
        orderTickets.setUserMobile(StringUtils.defaultString(((String) token.get("mobile")), ""));
        orderTickets.setPerformanceTitle(performanceData.getTitle());
        orderTickets.setOrderCode(IDGenerator.ticketOrderCode(orderTicketId));
        orderTickets.setPayCode("OUTLINE");
        orderTickets.setQrCode(IDGenerator.ticketQrCode(orderTickets.getOrderTicketsId()));
        orderTickets.setOrderType(source);
        orderTickets.setOrderVersion(version);
        orderTickets.setNumber(number);
        orderTickets.setPrice(ticketData.getPrice());
        orderTickets.setPriceMember(ticketData.getMemberPrice());
        if (isMember) {
            orderTickets.setPriceTotal(ticketData.getMemberPrice().multiply(BigDecimal.valueOf(number)).add(IsExpress == 1 ? ticketData.getPriceExpress() : BigDecimal.valueOf(0)));
        } else {
            orderTickets.setPriceTotal(ticketData.getPrice().multiply(BigDecimal.valueOf(number)).add(IsExpress == 1 ? ticketData.getPriceExpress() : BigDecimal.valueOf(0)));
        }
        orderTickets.setPriceActual(orderTickets.getPriceTotal());
        orderTickets.setPriceVoucher(BigDecimal.valueOf(0.0));
        orderTickets.setPriceExpress(IsExpress == 1 ? ticketData.getPriceExpress() : BigDecimal.valueOf(0));
        orderTickets.setPriceRefund(BigDecimal.valueOf(0.0));
        orderTickets.setRefundNumber(0);
        orderTickets.setPayType("OUTLINE");
        orderTickets.setPaymentType("OUTLINE");
        orderTickets.setPaymentId("OUTLINE");
        orderTickets.setTimePay(DateUtil.getNowTime());
        if (IsExpress == 1) {
            orderTickets.setExpressContacts(enterName);
            orderTickets.setExpressAddress(address);
            orderTickets.setExpressPhone(enterMobile);
            orderTickets.setCity("");
            orderTickets.setProvince("");
            orderTickets.setCounty("");
            orderTickets.setGetTicketType("express");
        } else {
            orderTickets.setExpressContacts("");
            orderTickets.setExpressAddress("");
            orderTickets.setExpressPhone("");
            orderTickets.setCity("");
            orderTickets.setProvince("");
            orderTickets.setCounty("");
            orderTickets.setGetTicketType("electronic");
        }
        orderTickets.setCouponType("no");
        orderTickets.setGetTicketDescribe("");
        orderTickets.setPayCountdownMinute(performanceData.getPayCountdownMinute());
        orderTickets.setCreatedAt(now);
        orderTickets.setUpdatedAt(null);

        //生成订单 order_ticket_status
        KylinOrderTicketStatus orderTicketStatus = KylinOrderTicketStatus.getNew();
        String orderTicketStatusId = IDGenerator.nextSnowId();
        orderTicketStatus.setOrderTicketStatusId(orderTicketStatusId);
        orderTicketStatus.setOrderId(orderTicketId);
        orderTicketStatus.setExpressType(2);
        orderTicketStatus.setTransferStatus(KylinTableStatusConst.ORDER_TRANSFER_STATUS0);
        orderTicketStatus.setStatus(KylinTableStatusConst.ORDER_STATUS1);
        orderTicketStatus.setIsStudent(ticketData.getIsStudent());
        orderTicketStatus.setPayStatus(KylinTableStatusConst.ORDER_PAY_STATUS1);
        orderTicketStatus.setCreatedAt(now);
        orderTicketStatus.setUpdatedAt(null);

        //生成订单 order_ticket_relation
        KylinOrderTicketRelations orderTicketRelations = KylinOrderTicketRelations.getNew();
        String orderTicketRelationId = IDGenerator.nextSnowId();
        orderTicketRelations.setOrderTicketRelationsId(orderTicketRelationId);
        orderTicketRelations.setOrderId(orderTicketId);
        orderTicketRelations.setTransferId("");
        orderTicketRelations.setLiveId("");
        orderTicketRelations.setAgentId("0");
        orderTicketRelations.setIsMember(isMember ? 1 : 0);
        orderTicketRelations.setPerformanceId(performanceData.getPerformancesId());
        orderTicketRelations.setTimeId(ticketTimesVo.getTimeId());
        orderTicketRelations.setTicketId(ticketData.getTicketsId());
        orderTicketRelations.setCreatedAt(now);
        orderTicketRelations.setUpdatedAt(null);


        //生成票
        KylinOrderTicketEntities orderTicketEntities = KylinOrderTicketEntities.getNew();
        if (performanceData.getIsTrueName() == 1) {
            String orderTicketEntitiesId = IDGenerator.nextSnowId();
            orderTicketEntities.setOrderTicketEntitiesId(orderTicketEntitiesId);
            orderTicketEntities.setOrderId(orderTicketId);
            orderTicketEntities.setUserId(uid);
            orderTicketEntities.setTicketId(ticketData.getTicketsId());
            orderTicketEntities.setPerformanceId(performanceData.getPerformancesId());
            orderTicketEntities.setTimeId(ticketTimesVo.getTimeId());
            orderTicketEntities.setEnterType(1);
            orderTicketEntities.setEnterName(enterName);
            orderTicketEntities.setEnterMobile(enterMobile);
            orderTicketEntities.setEnterIdCode(enterIdCode);
            orderTicketEntities.setStatus(KylinTableStatusConst.ENTITIES_STATUS0);
            orderTicketEntities.setSysDamai(ticketData.getSysDamai());
            orderTicketEntities.setCheckClient("");
            orderTicketEntities.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT1);
            orderTicketEntities.setRefundPrice(BigDecimal.valueOf(0.0));
            orderTicketEntities.setComment("");
            orderTicketEntities.setCreatedAt(now);
            orderTicketEntities.setUpdatedAt(null);
            // 生成vo
            KylinOrderTicketEntitiesVo orderTicketEntitiesVo = KylinOrderTicketEntitiesVo.getNew();
            BeanUtils.copyProperties(orderTicketEntities, orderTicketEntitiesVo);
            orderTicketEntitiesVo.setPerformanceTitle(performanceData.getTitle());
            orderTicketEntitiesVo.setTicketTitle(ticketData.getTitle());
            orderTicketEntitiesVo.setUseStart(ticketData.getUseStart());
            orderTicketEntitiesVo.setUseEnd(ticketData.getUseEnd());
            orderTicketEntitiesVo.setCreatedAt(orderTicketEntities.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            orderTicketEntitiesVo.setUpdatedAt(null);
            orderTicketEntitiesVo.setChangeDate(orderTicketEntities.getCreatedAt());
            mongoTemplate.insert(orderTicketEntitiesVo, KylinOrderTicketEntitiesVo.class.getSimpleName());
            dataUtils.changeBuyInfo(orderTicketEntitiesVo.getUserId(), orderTicketEntitiesVo.getEnterIdCode(), orderTicketEntitiesVo.getPerformanceId(), orderTicketEntitiesVo.getTicketId(), 1);
        } else {
            String orderTicketEntitiesId = IDGenerator.nextSnowId();
            orderTicketEntities.setOrderTicketEntitiesId(orderTicketEntitiesId);
            orderTicketEntities.setOrderId(orderTicketId);
            orderTicketEntities.setUserId(uid);
            orderTicketEntities.setTicketId(ticketData.getTicketsId());
            orderTicketEntities.setPerformanceId(performanceData.getPerformancesId());
            orderTicketEntities.setTimeId(ticketTimesVo.getTimeId());
            orderTicketEntities.setEnterType(0);
            orderTicketEntities.setEnterName("");
            orderTicketEntities.setEnterMobile("");
            orderTicketEntities.setEnterIdCode("");
            orderTicketEntities.setStatus(KylinTableStatusConst.ENTITIES_STATUS0);
            orderTicketEntities.setSysDamai(ticketData.getSysDamai());
            orderTicketEntities.setCheckClient("");
            orderTicketEntities.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT1);
            orderTicketEntities.setComment("");
            orderTicketEntities.setCreatedAt(now);
            orderTicketEntities.setUpdatedAt(null);
            // 生成vo
            KylinOrderTicketEntitiesVo orderTicketEntitiesVo = KylinOrderTicketEntitiesVo.getNew();
            BeanUtils.copyProperties(orderTicketEntities, orderTicketEntitiesVo);
            orderTicketEntitiesVo.setPerformanceTitle(performanceData.getTitle());
            orderTicketEntitiesVo.setTicketTitle(ticketData.getTitle());
            orderTicketEntitiesVo.setUseStart(ticketData.getUseStart());
            orderTicketEntitiesVo.setUseEnd(ticketData.getUseEnd());
            orderTicketEntitiesVo.setCreatedAt(orderTicketEntities.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            orderTicketEntitiesVo.setUpdatedAt(null);
            orderTicketEntitiesVo.setChangeDate(orderTicketEntities.getCreatedAt());
            mongoTemplate.insert(orderTicketEntitiesVo, KylinOrderTicketEntitiesVo.class.getSimpleName());
            dataUtils.changeBuyInfo(orderTicketEntitiesVo.getUserId(), orderTicketEntitiesVo.getEnterIdCode(), orderTicketEntitiesVo.getPerformanceId(), orderTicketEntitiesVo.getTicketId(), 1);
        }

        // 生成vo
        KylinOrderTicketVo orderTicketVo = KylinOrderTicketVo.getNew();
        orderTicketVo.setOrderTicket(orderTickets);
        orderTicketVo.setOrderTicketStatus(orderTicketStatus);
        orderTicketVo.setOrderTicketRelation(orderTicketRelations);
        orderTicketVo.setPerformanceImg(performanceData.getImgPoster());
        orderTicketVo.setTicketTitle(ticketData.getTitle());
        orderTicketVo.setUseStart(ticketData.getUseStart());
        orderTicketVo.setTimeStart(performanceData.getTimeStart());
        orderTicketVo.setOverdueAt(orderTickets.getCreatedAt().plusMinutes(performanceData.getPayCountdownMinute()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        orderTicketVo.setCreatedAt(orderTickets.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        orderTicketVo.setChangeDate(orderTickets.getCreatedAt());
        mongoTemplate.insert(orderTicketVo, KylinOrderTicketVo.class.getSimpleName());

        orderUtils.resetOrderListVo(uid, 1, orderTicketVo.getOrderTicketsId(), orderTicketVo);
    }

}
