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

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.type.TypeReference;
import com.github.pagehelper.PageInfo;
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.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.*;
import com.liquidnet.service.kylin.mapper.*;
import com.liquidnet.service.kylin.service.admin.IKylinPerformancesAdminService;
import lombok.extern.slf4j.Slf4j;
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.MultiValueMap;

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

@Service
@Slf4j
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;

    @Autowired
    private KylinOrderTicketsMapper orderTicketsMapper;
    @Autowired
    private KylinOrderTicketStatusMapper orderTicketStatusMapper;
    @Autowired
    private KylinOrderTicketRelationsMapper orderTicketRelationsMapper;
    @Autowired
    private KylinOrderTicketEntitiesMapper orderTicketEntitiesMapper;
    @Autowired
    private KylinOrderImportMapper orderImportMapper;

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

        String importId = IDGenerator.nextSnowId();
        KylinOrderImport orderImport = new KylinOrderImport();
        orderImport.setImportId(importId);
        orderImport.setPerformanceId(performancesId);
        orderImport.setStatus(0);
        orderImport.setTitle(fileName);
        orderImport.setAllCount(0);
        orderImport.setErrorCount(0);
        orderImport.setSuccessCount(0);
        orderImport.setCreatedAt(LocalDateTime.now());
        orderImportMapper.insert(orderImport);


        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        KylinPerformanceVo performanceData = dataUtils.getPerformanceVo(performancesId);
        List<OrderOutLineVo> vos = new ArrayList();
        for (OrderOutLineVo orderOutLineVo : orderOutLineVoList) {
            //获取账号维度数据
            String enterMobile = orderOutLineVo.getEnterMobile();
            String enterIdCode = orderOutLineVo.getEnterIdCode();
            String enterName = orderOutLineVo.getEnterName();
            int number = 1;
            String address = orderOutLineVo.getAddress();
            MultiValueMap<String, String> params = CollectionUtil.linkedMultiValueMapStringString();
            params.add("mobile", enterMobile);
            MultiValueMap<String, String> headers = CollectionUtil.linkedMultiValueMapStringString();
            headers.add("Accept", "application/json;charset=UTF-8");
            String returnData = HttpUtil.post(adamUrl.concat("/adam/rsc/reg/mobile"), params, headers);
            AdamUserInfoVo adamUserInfoVo = JsonUtils.fromJson(returnData, new TypeReference<ResponseDto<AdamUserInfoVo>>() {
            }).getData();
            String uid = adamUserInfoVo.getUid();
            boolean isMember = false;
            //找到对应票种和场次
            String ticketTitle = orderOutLineVo.getTicketTitle();
            String startTime = orderOutLineVo.getUseStart();
            String endTime = orderOutLineVo.getUseEnd();
            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;
                }
            }
            if (ticketData == null) {
//                KylinOrderImport orderImportFinal = new KylinOrderImport();
//                orderImportFinal.setPerformanceId(performancesId);
//                orderImportFinal.setStatus(2);
//                orderImportFinal.setAllCount(failureNum+successNum);
//                orderImportFinal.setErrorCount(failureNum+successNum);
//                orderImportFinal.setSuccessCount(0);
//                orderImportFinal.setUpdatedAt(LocalDateTime.now());
//                orderImportMapper.update(orderImportFinal, Wrappers.lambdaUpdate(KylinOrderImport.class).eq(KylinOrderImport::getImportId,importId));
//                return "演出数据错误";
                orderOutLineVo.setReason("演出数据错误");
                vos.add(orderOutLineVo);
                failureNum++;
                continue;
            }
            // 获取限购 实名
            int ticketLimit = ticketData.getLimitCount();//普通票种限购
            int ticketMemberLimit = ticketData.getLimitCountMember();//会员票种限购
            int ticketIdCount = ticketData.getIdCount();//实名票种限购
            int performanceLimit = performanceData.getLimitCount();//普通演出限购
            int performanceMemberLimit = 1;//会员演出限购
            int performanceIdCount = performanceData.getIdCount();//实名演出限购
            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()) {
                    orderOutLineVo.setReason("快递票未填写收货地址");
                    vos.add(orderOutLineVo);
                    failureNum++;
                    continue;
                }
            }
            //实名判断
            if (isTrueName == 1 && (enterIdCode.isEmpty() || enterName.isEmpty())) {
                orderOutLineVo.setReason("实名票未填写入场人");
                vos.add(orderOutLineVo);
                failureNum++;
                continue;
            }

            //学生票 判断
            if (isTrueName == 1) {
                if (isStudent == 1) {
                    int age = IDCard.getAgeByIdCard(enterIdCode);
                    if (age > 25) {
                        orderOutLineVo.setReason("年龄不符合");
                        vos.add(orderOutLineVo);
                        failureNum++;
                        continue;
                    }
                }
            }

            //限购判断 如果实名 则身份证维度限购 如果不实名则数量限购
            if (isTrueName == 1) {
                String res1 = orderUtils.judgeOrderLimit(uid, enterIdCode, performancesId, ticketData.getTicketsId(), performanceLimit, performanceMemberLimit, performanceIdCount, ticketLimit, ticketMemberLimit, ticketIdCount, 0, isTrueName);
                if (!res1.equals("")) {
                    orderOutLineVo.setReason(res1);
                    vos.add(orderOutLineVo);
                    failureNum++;
                    continue;
                }
            } else {
                String res1 = orderUtils.judgeOrderLimit(uid, "", performancesId, ticketData.getTicketsId(), performanceLimit, performanceMemberLimit, performanceIdCount, ticketLimit, ticketMemberLimit, ticketIdCount, 0, isTrueName);
                if (!res1.equals("")) {
                    orderOutLineVo.setReason(res1);
                    vos.add(orderOutLineVo);
                    failureNum++;
                    continue;
                }
            }
            try {
                order(number, ticketType.equals("express") ? 1 : 0, adamUserInfoVo, isMember, performanceData, ticketTimesData, ticketData, enterMobile, enterName, enterIdCode, address);
                successNum++;
                orderOutLineVo.setReason("成功");
//                vos.add(orderOutLineVo);
            } catch (Exception e) {
                e.printStackTrace();
                failureNum++;
            }
        }

        KylinOrderImport orderImportFinal = KylinOrderImport.getNew();
        orderImportFinal.setPerformanceId(performancesId);
        orderImportFinal.setStatus(1);
        orderImportFinal.setAllCount(failureNum + successNum);
        orderImportFinal.setErrorCount(failureNum);
        orderImportFinal.setSuccessCount(successNum);
        orderImportFinal.setUpdatedAt(LocalDateTime.now());
        orderImportMapper.update(orderImportFinal, Wrappers.lambdaUpdate(KylinOrderImport.class).eq(KylinOrderImport::getImportId, importId));

        dataUtils.setOrderImportFail(importId, vos);
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
//            throw new BusinessException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public PageInfo<OrderOutLineVo> getImportDetails(String importId) {
        return dataUtils.getOrderImportFail(importId);
    }


    private void order(Integer number, Integer IsExpress, AdamUserInfoVo adamUserInfoVo, boolean isMember,
                       KylinPerformanceVo performanceData, KylinTicketTimesVo ticketTimesVo, KylinTicketVo ticketData,
                       String enterMobile, String enterName, String enterIdCode, String address) {
        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(adamUserInfoVo.getUid());
        orderTickets.setUserName(adamUserInfoVo.getNickname());
        orderTickets.setUserMobile(adamUserInfoVo.getMobile());
        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(adamUserInfoVo.getUid());
            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(adamUserInfoVo.getUid());
            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);
        }
        orderTicketEntitiesMapper.insert(orderTicketEntities);

        // 生成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());

        orderTicketsMapper.insert(orderTickets);
        orderTicketStatusMapper.insert(orderTicketStatus);
        orderTicketRelationsMapper.insert(orderTicketRelations);

        orderUtils.resetOrderListVo(adamUserInfoVo.getUid(), 1, orderTicketVo.getOrderTicketsId(), orderTicketVo);
    }


}
