package com.liangjian.dataplatform.member.jobUtil;

import com.liangjian.dataplatform.member.entity.po.primary.JobInfo;
import com.liangjian.dataplatform.member.entity.po.primary.TagRule;
import com.liangjian.dataplatform.member.entity.vo.tagrules.SqlAndResult;
import com.liangjian.dataplatform.member.service.IJobInfoService;
import com.liangjian.dataplatform.member.service.ITagRuleService;
import com.liangjian.dataplatform.member.service.ITagRuleSqlService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.time.DateUtils;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class MemberTagJob {

    @Autowired
    private ITagRuleService iTagRuleService;

    @Autowired
    private ITagRuleSqlService iTagRuleSqlService;

    @Autowired
    private IJobInfoService iJobInfoService;

    private static String clickHouseUrl="http://139.159.192.185:8123/?user=default&password=79B084A8D7363488DEBFA5D151CCC9B1";

    @Scheduled(fixedRate = 1000*60*60)
    public void cleanUserAgreement() throws Exception {
        System.out.println("---掃描開啟---");
        int page=0;
        int size=500;
        Date d= DateUtils.addDays(new Date(), 5);//有效期
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" );
        SimpleDateFormat fmt1 = new SimpleDateFormat("HH" );


        RestHighLevelClient client = EsUtils.getEsClient();
        //查询啟用，循环次数大于1的数据/分段獲取
        //Page<TagRuleVo> vos = iTagRuleService.queryByCondition(null,null,null,page, size);
        Page<TagRule> vos = iTagRuleService.queryByTagList(page, size);
        if(vos.getTotalElements()>0){
          for(TagRule tag : vos){//规则任务
              //生成sql
              if(tag.getJobId()!=null && !tag.getJobId().isEmpty()){
                  JobInfo jobInfo = iJobInfoService.queryById(tag.getJobId());

                  String f1= fmt1.format(jobInfo.getStartTime());
                  String f2 = fmt1.format(new Date());
                  if(jobInfo.getActive() && f1.equals(f2) && jobInfo.getRepeatRule()>0){
                      jobInfo.setRepeatRule(jobInfo.getRepeatRule()-1);//次数减
                      iJobInfoService.saveJobInfo(jobInfo);
                      List<SqlAndResult> results = iTagRuleSqlService.getSqlAndResult(tag.getId(),null);
                      Integer objectType=tag.getObject();//用户商品标签
                      //獲取會員，記錄標籤
                      for(SqlAndResult sqlres:results){//sql

                          Map<String,String> sqlMap=sqlres.getResult();


                          String sql=sqlres.getSql();//产出sql
                          boolean flag=true;
                          String selectUrl = clickHouseUrl+"&query=SQLTAG LIMIT PAGEINDEX,SIZEINDEX FORMAT JSON ";
                            while (flag){
                                String url=selectUrl.replaceAll("SQLTAG",sql).replaceAll("PAGEINDEX",String.valueOf(page)).replaceAll("SIZEINDEX",String.valueOf(size));
                                url= url.replaceAll(" ","%20").replaceAll(">","%3E").replaceAll("<","%3C");
                                String result = EsUtils.httpGetClickHouse(url);
                                result=result.replaceAll(" ","");

                                JSONObject json=JSONObject.fromObject(result.replaceAll(" ",""));
                                JSONArray jsonArray= json.getJSONArray("data");
                                if(jsonArray.size()<=0||jsonArray.size()<size){
                                    flag=false;
                                }
                                page+=size;
                                String[] terms = new String[jsonArray.size()];
                                int k = 0;
                                for(int i=0;i<jsonArray.size();i++) {//用户
                                    JSONObject job = jsonArray.getJSONObject(i);
                                    String memKey=null;
                                    for (Object key : job.keySet()) {
                                        if(objectType!=3 && key.equals("AConsigneePhone2")){
                                            memKey= String.valueOf(job.get(key));
                                            break;
                                        }
                                        if(objectType==3 && key.equals("ProductCode")){
                                            memKey= String.valueOf(job.get(key));
                                            break;
                                        }
                                    }
                                    if(memKey!=null){
                                        terms[k] = memKey;
                                        k = k +1;
                                    }

                                }
                                BulkRequest request =new BulkRequest();
                                //request.setRefresh(true);
                                request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
                            try{
                                for(String memKey :terms){//用户
                                    if(memKey!=null){
                                        List<Map<String,Object>> mapList =new ArrayList<Map<String,Object>>();
                                        //添加一條Tag記錄
                                        //獲取標籤信息
                                        String finalMemKey = memKey;
                                        sqlMap.forEach((key, value) -> {
                                            GetRequest requestTag = new GetRequest("mem_tag", "_doc", value);
                                            try {
                                                GetResponse getResponse2 = client.get(requestTag,RequestOptions.DEFAULT);
                                                String id = getResponse2.getId();

                                                Map<String, Object> obj=getResponse2.getSource();
                                                String index = "mem_membertag";//1/2
                                                String type = "_doc";
                                                //Map<String, Object> map = new HashMap<>();
                                                JSONObject map=new JSONObject();
                                                map.put("id",id+"_"+finalMemKey);
                                                map.put("TagName",obj.get("TagName"));
                                                map.put("TagId",obj.get("TagId"));
                                                map.put("TagTypeId",obj.get("TagTypeId"));
                                                map.put("TagTypeName",obj.get("TagTypeName"));
                                                map.put("MemberPhone", finalMemKey);
                                                if(objectType!=3){
                                                    //request.add(new IndexRequest(index, type, String.valueOf(map.remove("id"))).source(map,XContentType.JSON));
                                                    EsUtils.post(map,"http://192.168.50.39:9200/mem_membertag/_doc?id="+id+"_"+finalMemKey);
                                                }
                                                //System.out.println(key + ":" + value);
                                                obj.put("TagCrtTime",fmt.format(new Date()));
                                                obj.put("TagValidEnd",fmt.format(d));
                                                mapList.add(obj);
                                            } catch (ElasticsearchException | IOException e) {
                                            }
                                        });
                                        if(objectType==3){//商品标签
                                            List<Map<String,Object>> mapList1=removeDuplicate(mapList,finalMemKey);
                                            String insertUrl="INSERT INTO ProductTag(id, tagId, TagName, TagValue, TagTypeId, TagTypeName, MemberPhone,TagValidDates, TagValidEnd, create_date) VALUES ";
                                            String insertSql="";
                                            for(Map<String,Object> obj:mapList1){
                                                String selectUrl1 = clickHouseUrl+"&query=SELECT id FROM ProductTag WHERE id='"+obj.get("TagId")+"_"+finalMemKey+"' LIMIT 1 FORMAT JSON ";
                                                selectUrl1= selectUrl1.replaceAll(" ","%20").replaceAll(">","%3E").replaceAll("<","%3C");
                                                String result1 = EsUtils.httpGetClickHouse(selectUrl1);
                                                result1=result1.replaceAll(" ","");
                                                JSONObject json1=JSONObject.fromObject(result1.replaceAll(" ",""));
                                                JSONArray jsonArray1= json1.getJSONArray("data");
                                                if(jsonArray1.size()<=0){
                                                    int TagValidDates=0;
                                                    if(obj.get("TagValidDates")!=null&&!obj.get("TagValidDates").equals("")){
                                                        TagValidDates=Integer.parseInt(String.valueOf(obj.get("TagValidDates")));
                                                    }
                                                    Date d1= DateUtils.addDays(new Date(), TagValidDates);
                                                    insertSql+="('"+obj.get("TagId")+"_"+finalMemKey+"','"+obj.get("TagId")+"','"+obj.get("TagName")+"',";
                                                    insertSql+="'"+obj.get("TagValue")+"','"+obj.get("TagTypeId")+"','"+obj.get("TagTypeName")+"','"+finalMemKey+"',"+TagValidDates+",'"+fmt.format(d1)+"','"+fmt.format(new Date())+"'),";
                                                }
                                            }
                                            if(insertSql!=""){
                                                insertUrl=insertUrl+insertSql.substring(0,insertSql.length()-1);
                                                EsUtils.httpPostClickHouse(clickHouseUrl,insertUrl);
                                            }

                                        }else{//用户标签
                                            //修改用户Tag
                                            try {
                                                SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                                                String id = null;
                                                //sourceBuilder.query(QueryBuilders.termQuery("MemUsualPhone", finalMemKey));
                                                sourceBuilder.query(QueryBuilders.termQuery("MemUsualPhone", finalMemKey))
                                                        .fetchSource("*",null);
                                                SearchRequest searchRequest = new SearchRequest();
                                                searchRequest.indices("mem_memberbase_p");
                                                searchRequest.source(sourceBuilder);
                                                SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
                                                Map<String,String> meMap=new HashMap<>();
                                                SearchHit hi=null;
                                                String tagStr=null;
                                                Map<String,Object> tagMap=new HashMap<>();
                                                for(SearchHit hit:response.getHits()) {
                                                    id = hit.getId();
                                                    tagMap=hit.getSourceAsMap();
                                                }

                                                JSONObject ob=JSONObject.fromObject(tagMap);
                                                //查询用户已有标签
                                                List<Map<String,Object>> m=getEssearch(client,"mem_membertag","MemberPhone.keyword",finalMemKey);
                                                //当前合并
                                                mapList.addAll(m);
                                                List<Map<String,Object>> mapList1=removeDuplicate(mapList,finalMemKey);
                                                ob.put("Tags",mapList1);
                                                String index = "mem_memberbase_p";
                                                String type = "_doc";
                                                request.add(new UpdateRequest(index, type, id).doc(ob.toString(),XContentType.JSON));
                                                request.add(new UpdateRequest("mem_repurchaseinfo", type, id).doc(ob.toString(),XContentType.JSON));
                                                String insertUrl="INSERT INTO memberTagV2(id, tagId, TagName, TagValue, TagTypeId, TagTypeName, MemberPhone,TagValidDates, TagValidEnd, create_date) VALUES ";
                                                String insertSql="";
                                                for(Map<String,Object> obj:mapList1){
                                                    String selectUrl1 = clickHouseUrl+"&query=SELECT id FROM memberTagV2 WHERE id='"+obj.get("TagId")+"_"+finalMemKey+"' LIMIT 1 FORMAT JSON ";
                                                    selectUrl1= selectUrl1.replaceAll(" ","%20").replaceAll(">","%3E").replaceAll("<","%3C");
                                                    String result1 = EsUtils.httpGetClickHouse(selectUrl1);
                                                    result1=result1.replaceAll(" ","");
                                                    JSONObject json1=JSONObject.fromObject(result1.replaceAll(" ",""));
                                                    JSONArray jsonArray1= json1.getJSONArray("data");
                                                    if(jsonArray1.size()<=0){
                                                        int TagValidDates=0;
                                                        if(obj.get("TagValidDates")!=null&&!obj.get("TagValidDates").equals("")){
                                                            TagValidDates=Integer.parseInt(String.valueOf(obj.get("TagValidDates")));
                                                        }
                                                        Date d1= DateUtils.addDays(new Date(), TagValidDates);
                                                        insertSql+="('"+obj.get("TagId")+"_"+finalMemKey+"','"+obj.get("TagId")+"','"+obj.get("TagName")+"',";
                                                        insertSql+="'"+obj.get("TagValue")+"','"+obj.get("TagTypeId")+"','"+obj.get("TagTypeName")+"','"+finalMemKey+"',"+TagValidDates+",'"+fmt.format(d)+"','"+fmt.format(new Date())+"'),";
                                                    }
                                                }
                                                if(insertSql!=""){
                                                    insertUrl=insertUrl+insertSql.substring(0,insertSql.length()-1);
                                                    EsUtils.httpPostClickHouse(clickHouseUrl,insertUrl);
                                                }
                                                //保存用户标签至clickHouses

                                                //request.add(new UpdateRequest(index, type,"18616866645")
                                                //      .doc(XContentType.JSON,);

                                            } catch (ElasticsearchException e) {
                                                if (e.status() == RestStatus.NOT_FOUND) {
                                                    //处理因为索引不存在而抛出的异常情况
                                                }
                                            }
                                        }


                                    }
                                }
                                client.bulk(request,RequestOptions.DEFAULT);

                            } catch (Exception e) {
                            }

                            }
                      }
                    }
              }
          }
        }
        EsUtils.closeClient();
    }


    public static List<Map<String,Object>> getEssearch(RestHighLevelClient client, String ices, String name, String value) throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        String id = null;
        sourceBuilder.query(QueryBuilders.termQuery(name, value))
                .fetchSource("*",null);
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(ices);
        searchRequest.source(sourceBuilder);
        SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
        Map<String,String> meMap=new HashMap<>();
        List<Map<String,Object>> tagMap=new ArrayList<Map<String,Object>>();
        for(SearchHit hit:response.getHits()) {
            tagMap.add(hit.getSourceAsMap());
        }
        return tagMap;
    }

    public static List<Map<String,Object>>  removeDuplicate(List<Map<String,Object>> list,String fmKey)  {
        for  ( int  i  =   0 ; i  <  list.size()  -   1 ; i ++ )  {
            for  ( int  j  =  list.size()  -   1 ; j  >  i; j -- )  {
                if  (String.valueOf((list.get(j).get("TagId"))).equals(String.valueOf(list.get(i).get("TagId"))))  {
                    String tag=String.valueOf((list.get(j).get("TagId")));
                    list.remove(j);
                }
            }
        }
        return list;
    }
}
