package com.gree.mall.manager.logic.workorder;

import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.es.OrderBaseEs;
import com.gree.mall.manager.bean.workorder.OrderBaseCountBean;
import com.gree.mall.manager.bean.workorder.OrderCount7DayBean;
import com.gree.mall.manager.commonmapper.workorder.OrderBaseCMapper;
import com.gree.mall.manager.enums.OrderStatusEnum;
import com.gree.mall.manager.enums.workorder.OrderBaseStatusEnum;
import com.gree.mall.manager.enums.workorder.OrderTypeEnum;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.PgOrderBase;
import com.gree.mall.manager.plus.service.PgOrderBaseService;
import io.swagger.models.auth.In;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilter;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

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

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderBaseCountLogic {

    private final OrderBaseCMapper orderBaseCMapper;
    private final PgOrderBaseService pgOrderBaseService;
    private final CommonLogic commonLogic;
    private final ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 首页工单统计
     * @return
     */
    public OrderBaseCountBean baseCountBean(){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        OrderBaseCountBean orderBaseCountBean = orderBaseCMapper
                .countOrderBaseIndex(adminUser.getCompanyWechatId(), adminUser.getAdminWebsitIds(),adminUser.getType());

/*
        List<PgOrderBase> pgOrderBaseList = pgOrderBaseService.lambdaQuery()
                .select(PgOrderBase::getOrderType, PgOrderBase::getOrderTypeText, PgOrderBase::getCreateTime, PgOrderBase::getId
                        , PgOrderBase::getOrderStatus,PgOrderBase::getAppointmentTime)
                .between(PgOrderBase::getCreateTime, DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -30)), new Date())
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),PgOrderBase::getCompanyWechatId,adminUser.getCompanyWechatId())
                .and(CollectionUtils.isNotEmpty(adminUser.getAdminWebsitIds()),
                        v -> v.in(PgOrderBase::getWebsitId,adminUser.getAdminWebsitIds()).or()
                                .in(PgOrderBase::getCreateWebsitId,adminUser.getAdminWebsitIds()))
                .list();
*/

/*
        List<PgOrderBase> pgOrderBaseListOver = pgOrderBaseService.lambdaQuery()
                .select(PgOrderBase::getOrderType, PgOrderBase::getOrderTypeText, PgOrderBase::getCreateTime, PgOrderBase::getId
                        , PgOrderBase::getOrderStatus,PgOrderBase::getAppointmentTime,PgOrderBase::getOverDate,PgOrderBase::getOverTime)
                .between(PgOrderBase::getOverTime, DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -8)), new Date())
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),PgOrderBase::getCompanyWechatId,adminUser.getCompanyWechatId())
                .and(CollectionUtils.isNotEmpty(adminUser.getAdminWebsitIds()),
                        v -> v.in(PgOrderBase::getWebsitId,adminUser.getAdminWebsitIds()).or().in(PgOrderBase::getCreateWebsitId,adminUser.getAdminWebsitIds()))
                .list();
*/

        Map<String,List<Long>> qtddqs = new HashMap<>();

        List<Long> xzgdList = new ArrayList<>();
        List<Long> wgdList = new ArrayList<>();
        List<Long> jxzList = new ArrayList<>();
        List<Long> qtsmList = new ArrayList<>();

        List<String> orderStatus = new ArrayList<>
                ();

        orderStatus.add("YWG");
        orderStatus.add("GCSZX");
        orderStatus.add("WDWG");
        orderStatus.add("YWGO");
        orderStatus.add("YJS");
        orderStatus.add("LRCD");

        List<String> orderStatusQx = new ArrayList<>();
        orderStatusQx.add("YQX");
        orderStatusQx.add("FWZT");
        orderStatusQx.add("YCGB");
        orderStatusQx.add("FWQX");
        orderStatusQx.add("FL");

        for (int i = 6; i >= 0; i--) {
            Integer day = i*-1;
       /*     Long xzgd = pgOrderBaseList.stream().filter(item -> item.getCreateTime().before(DateUtil.endOfDay(DateUtil.offsetDay(new Date(), (day)))) &&
                    item.getCreateTime().after(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), (day))))
            ).count();
*/
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(adminUser.getAdminWebsitIds())) {
                List<QueryBuilder> should = queryBuilder.should();
                should.add(QueryBuilders.termsQuery("create_websit_id", adminUser.getAdminWebsitIds()));
                should.add(QueryBuilders.termsQuery("websit_id", adminUser.getAdminWebsitIds()));
            }
            //新增工单
            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(queryBuilder)
                    .withPageable(PageRequest.of(1, 1))
                    .addAggregation(this.getAggs(AggregationBuilders.filter("xzgd", QueryBuilders.boolQuery()
                            .must(QueryBuilders.rangeQuery("create_time")
                                    .gte(DateUtil.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), (day))),"yyyy-MM-dd HH:mm:ss"))
                                    .lte(DateUtil.format(DateUtil.endOfDay(DateUtil.offsetDay(new Date(), (day))),"yyyy-MM-dd HH:mm:ss")))
                    )))
                    .build();
            SearchHits response = elasticsearchRestTemplate.search(searchQuery, OrderBaseEs.class);

            xzgdList.add(this.getWorkerOrderCountResult(response.getAggregations(),"xzgd"));

    /*        Long wgd = pgOrderBaseListOver.stream().filter(item -> item.getOverTime().before(DateUtil.endOfDay(DateUtil.offsetDay(new Date(), (day)))) &&
                            item.getOverTime().after(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), (day))))
                            && orderStatus.contains(item.getOrderStatus())      ).count();*/


            //完工单
            NativeSearchQuery searchQueryWGD = new NativeSearchQueryBuilder()
                    .withQuery(queryBuilder)
                    .withPageable(PageRequest.of(1, 1))
                    .addAggregation(this.getAggs(AggregationBuilders.filter("wgd", QueryBuilders.boolQuery()
                            .must(QueryBuilders.termsQuery("order_status",orderStatus))
                            .must(QueryBuilders.rangeQuery("over_time")
                                    .gte(DateUtil.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), (day))),"yyyy-MM-dd HH:mm:ss"))
                                    .lte(DateUtil.format(DateUtil.endOfDay(DateUtil.offsetDay(new Date(), (day))),"yyyy-MM-dd HH:mm:ss")))
                    )))
                    .build();
            SearchHits responseWGD = elasticsearchRestTemplate.search(searchQueryWGD, OrderBaseEs.class);
            wgdList.add(this.getWorkerOrderCountResult(responseWGD.getAggregations(),"wgd"));



/*            Long jxz = pgOrderBaseList.stream().filter(item -> item.getCreateTime().before(DateUtil.endOfDay(DateUtil.offsetDay(new Date(), (day)))) &&
                    item.getCreateTime().after(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), (day))))
                    && !orderStatus.contains(item.getOrderStatus())
                    && !orderStatusQx.contains(item.getOrderStatus())
            ).count();*/


            //待商户派工
            NativeSearchQuery searchQueryJXZ= new NativeSearchQueryBuilder()
                    .withQuery(queryBuilder)
                    .withPageable(PageRequest.of(1, 1))
                    .addAggregation(this.getAggs(AggregationBuilders.filter("jxz", QueryBuilders.boolQuery()
                            .mustNot(QueryBuilders.termsQuery("order_status",orderStatus))
                            .mustNot(QueryBuilders.termsQuery("order_status",orderStatusQx))
                            .must(QueryBuilders.rangeQuery("create_time")
                                    .gte(DateUtil.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), (day))),"yyyy-MM-dd HH:mm:ss"))
                                    .lte(DateUtil.format(DateUtil.endOfDay(DateUtil.offsetDay(new Date(), (day))),"yyyy-MM-dd HH:mm:ss")))
                    )))
                    .build();
            SearchHits responseJXZ = elasticsearchRestTemplate.search(searchQueryJXZ, OrderBaseEs.class);


            jxzList.add(this.getWorkerOrderCountResult(responseJXZ.getAggregations(),"jxz"));



        }

        qtddqs.put("新增工单",xzgdList);
        qtddqs.put("完工工单",wgdList);
        qtddqs.put("进行中",jxzList);

        orderBaseCountBean.setQtddqs(qtddqs);

        for (int i = 0; i < 7; i++) {
            Integer day = i;

            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(adminUser.getAdminWebsitIds())) {
                List<QueryBuilder> should = queryBuilder.should();
                should.add(QueryBuilders.termsQuery("create_websit_id", adminUser.getAdminWebsitIds()));
                should.add(QueryBuilders.termsQuery("websit_id", adminUser.getAdminWebsitIds()));
            }

/*            Long qtsm = pgOrderBaseList.stream().filter(item -> item.getAppointmentTime() != null && item.getAppointmentTime().before(DateUtil.endOfDay(DateUtil.offsetDay(new Date(), (day)))) &&
                    item.getAppointmentTime().after(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), (day))))

            ).count();*/

            //七天上门
            NativeSearchQuery searchQueryQTSM= new NativeSearchQueryBuilder()
                    .withQuery(queryBuilder)
                    .withPageable(PageRequest.of(1, 1))
                    .addAggregation(this.getAggs(AggregationBuilders.filter("qtsm", QueryBuilders.boolQuery()
                            .must(QueryBuilders.rangeQuery("appointment_time")
                                    .gte(DateUtil.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), (day))),"yyyy-MM-dd HH:mm:ss"))
                                    .lte(DateUtil.format(DateUtil.endOfDay(DateUtil.offsetDay(new Date(), (day))),"yyyy-MM-dd HH:mm:ss"))))))
                    .build();
            SearchHits responseQTSM = elasticsearchRestTemplate.search(searchQueryQTSM, OrderBaseEs.class);


            qtsmList.add(this.getWorkerOrderCountResult(responseQTSM.getAggregations(),"qtsm"));

        }



        orderBaseCountBean.setQtsm(qtsmList);

        List<String> collect = new ArrayList<>();

        collect.add(OrderTypeEnum.INSTALL.getRemark());
        collect.add(OrderTypeEnum.REPAIR.getRemark());

        Map<String,List<Long>> wglxfb = new HashMap<>();
        for (String orderTypeText : collect) {

            List<Long> list = new ArrayList<>();
            for (int i = 0; i < 30; i++) {
                Integer day = i*-1;

       /*         Long num = pgOrderBaseList.stream().filter(item -> item.getCreateTime().before(DateUtil.endOfDay(DateUtil.offsetDay(new Date(), (day)))) &&
                        item.getCreateTime().after(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), (day))))
                        && item.getOrderTypeText().equals(orderTypeText)
                ).count();*/

                BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

                if (CollectionUtils.isNotEmpty(adminUser.getAdminWebsitIds())) {
                    List<QueryBuilder> should = queryBuilder.should();
                    should.add(QueryBuilders.termsQuery("create_websit_id", adminUser.getAdminWebsitIds()));
                    should.add(QueryBuilders.termsQuery("websit_id", adminUser.getAdminWebsitIds()));
                }

                //工单类型
                NativeSearchQuery searchQueryGDLX= new NativeSearchQueryBuilder()
                        .withQuery(queryBuilder)
                        .withPageable(PageRequest.of(1, 1))
                        .addAggregation(this.getAggs(AggregationBuilders.filter("gdlx", QueryBuilders.boolQuery()
                                .must(QueryBuilders.termsQuery("order_type_text",orderTypeText))
                                .must(QueryBuilders.rangeQuery("create_time")
                                        .gte(DateUtil.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), (day))),"yyyy-MM-dd HH:mm:ss"))
                                        .lte(DateUtil.format(DateUtil.endOfDay(DateUtil.offsetDay(new Date(), (day))),"yyyy-MM-dd HH:mm:ss"))))))
                        .build();
                SearchHits responseGDLX = elasticsearchRestTemplate.search(searchQueryGDLX, OrderBaseEs.class);


                list.add(this.getWorkerOrderCountResult(responseGDLX.getAggregations(),"gdlx"));
            }

            Collections.reverse(list);

            wglxfb.put(orderTypeText,list);

        }


        orderBaseCountBean.setWglxfb(wglxfb);

        return orderBaseCountBean;
    }


    public AbstractAggregationBuilder<?> getAggs(FilterAggregationBuilder filter) {
        return filter.subAggregation(AggregationBuilders.sum("total_mac_sum").field("total_num"))
                .subAggregation(AggregationBuilders.terms("order_type_group").field("order_type")
                        .subAggregation(AggregationBuilders.sum("mac_sum").field("total_num")));
    }

    public long getWorkerOrderCountResult(Aggregations aggregations, String name) {
        StringBuffer sb = new StringBuffer();
        ParsedFilter parsedFilter = aggregations.get(name);
        //总服务单数
        long totalOrderNums = parsedFilter.getDocCount();

        return totalOrderNums;
    }

    /**
     * 统计近7天的订单趋势和需上门数量
     * @return
     */
//    public OrderCount7DayBean last7DayCount(){
//        AdminUserCom adminUser = commonLogic.getAdminUser();
//        OrderCount7DayBean orderCount7DayBean = new OrderCount7DayBean();
//
//        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
//        //最近7天的日期
//        orderCount7DayBean.setDates(
//            Lists.newArrayList(
//                    sdf.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(),0))),
//                    sdf.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(),1))),
//                    sdf.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(),2))),
//                    sdf.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(),3))),
//                    sdf.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(),4))),
//                    sdf.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(),5))),
//                    sdf.format(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(),6))))
//        );
//
//        //最近7天的制单时间 key = time,total
//        List<Map<String,Long>> countList1 = orderBaseCMapper.countLast7Day1(adminUser.getCompanyWechatId(), adminUser.getAdminWebsitIds());
//        List<Map<String,Long>> countList2 = orderBaseCMapper.countLast7Day1(adminUser.getCompanyWechatId(), adminUser.getAdminWebsitIds());
//
//        return orderCount7DayBean;
//    }

    /**
     * 未来7天需上门数量
     * @return
     */
//    public OrderCount7DayBean feature7DayCount(){
//        AdminUserCom adminUser = commonLogic.getAdminUser();
//        OrderCount7DayBean orderCount7DayBean = new OrderCount7DayBean();
//
//        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
//        return orderCount7DayBean;
//    }

}
