package com.skyversation.poiaddr.service.impl;

import com.skyversation.poiaddr.addquery.AddressQueryEngine;
import com.skyversation.poiaddr.addquery.Constant;
import com.skyversation.poiaddr.bean.AddressResult;
import com.skyversation.poiaddr.config.DbConnection;
import com.skyversation.poiaddr.entity.SjArrDzbzhSjWcbryDzxx;
import com.skyversation.poiaddr.util.AddressTools;
import com.skyversation.poiaddr.util.ExcelReaderUtils;
import com.skyversation.poiaddr.util.SerializationUtils;
import com.skyversation.poiaddr.util.status.AddressLevel;
import org.springframework.stereotype.Service;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@Service
public class SjArrDzbzhSjWcbryDzxxServiceImpl {

    public void uploadDataBase() {
        try {
            List<Map<String, Object>> oldDbData = DbConnection.getInstance().runSqlStr("select * FROM sj_zrr_dzbzh_sj_wcbry_dzxx");
//          去重
            Map<String, Map<String, Object>> newRequestData = new HashMap<>();
            for (Map<String, Object> item : oldDbData) {
                if (item.get("id") != null) {
                    newRequestData.put(item.get("id").toString(), item);
                }
            }
            List<Map<String, Object>> dbData = new ArrayList<>();
            for (String id : newRequestData.keySet()) {
                dbData.add(newRequestData.get(id));
            }
//          直接保存数据到xlsx
            ExcelReaderUtils.writeToExcel(dbData, "output/allData.xlsx");
        } catch (Exception e) {
            System.err.println("下载失败！" + e);
        }
    }

    public List<SjArrDzbzhSjWcbryDzxx> getAllData(String reAddr) {
        try {
            List<SjArrDzbzhSjWcbryDzxx> requestData = new ArrayList<>();
            String sqlStr = "select * FROM sj_zrr_dzbzh_sj_wcbry_dzxx";
            if (!reAddr.trim().isEmpty()) {
                sqlStr = sqlStr + " where standardized_address like '%" + reAddr + "%'";
            }
            List<Map<String, Object>> oldDbData = DbConnection.getInstance().runSqlStr(sqlStr);
//          去重
            Map<String, Map<String, Object>> newRequestData = new HashMap<>();
            for (Map<String, Object> item : oldDbData) {
                if (item.get("id") != null) {
                    newRequestData.put(item.get("id").toString(), item);
                }
            }
            List<Map<String, Object>> dbData = new ArrayList<>();
            for (String id : newRequestData.keySet()) {
                dbData.add(newRequestData.get(id));
            }
            for (Map<String, Object> item : dbData) {
                SjArrDzbzhSjWcbryDzxx sjArrDzbzhSjWcbryDzxx = new SjArrDzbzhSjWcbryDzxx();
                if (item.get("id") != null) {
                    sjArrDzbzhSjWcbryDzxx.setId(item.getOrDefault("id", "").toString());
                }
                if (item.get("jc_hjdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setJcHjdz(item.getOrDefault("jc_hjdz", "").toString());
                }
                if (item.get("jc_jzdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setJcJzdz(item.getOrDefault("jc_jzdz", "").toString());
                }
                if (item.get("sk_hjdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setSkHjdz(item.getOrDefault("sk_hjdz", "").toString());
                }
                if (item.get("sk_jzdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setSkJzdz(item.getOrDefault("sk_jzdz", "").toString());
                }
                if (item.get("sqy_hjdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setSqyHjdz(item.getOrDefault("sqy_hjdz", "").toString());
                }
                if (item.get("sqy_jzdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setSqyJzdz(item.getOrDefault("sqy_jzdz", "").toString());
                }
                requestData.add(sjArrDzbzhSjWcbryDzxx);
            }
            return requestData;
        } catch (Exception e) {
            System.err.println("sql运行异常：" + e);
            return null;
        }
    }

    //  分页查询地址表
    public List<SjArrDzbzhSjWcbryDzxx> getAllDataPage(int size) {
        try {
            List<SjArrDzbzhSjWcbryDzxx> requestData = new ArrayList<>();
            String sql = "SELECT * FROM sj_zrr_dzbzh_sj_wcbry_dzxx WHERE update_time is null limit " + size;
            List<Map<String, Object>> oldDbData = DbConnection.getInstance().runSqlStr(sql);
//          去重
            Map<String, Map<String, Object>> newRequestData = new HashMap<>();
            for (Map<String, Object> item : oldDbData) {
                if (item.get("id") != null) {
                    newRequestData.put(item.get("id").toString(), item);
                }
            }
            List<Map<String, Object>> dbData = new ArrayList<>();
            for (String id : newRequestData.keySet()) {
                dbData.add(newRequestData.get(id));
            }
            for (Map<String, Object> item : dbData) {
                SjArrDzbzhSjWcbryDzxx sjArrDzbzhSjWcbryDzxx = new SjArrDzbzhSjWcbryDzxx();
                if (item.get("id") != null) {
                    sjArrDzbzhSjWcbryDzxx.setId(item.getOrDefault("id", "").toString());
                }
                if (item.get("in_the_area") != null) {
                    sjArrDzbzhSjWcbryDzxx.setInTheArea(item.getOrDefault("in_the_area", "").toString());
                }
                if (item.get("result_addr_key") != null) {
                    sjArrDzbzhSjWcbryDzxx.setResultAddrKey(item.getOrDefault("result_addr_key", "").toString());
                }
                if (item.get("level") != null) {
                    sjArrDzbzhSjWcbryDzxx.setLevel(item.getOrDefault("level", "").toString());
                }
                if (item.get("lat") != null) {
                    sjArrDzbzhSjWcbryDzxx.setLat(item.getOrDefault("lat", "").toString());
                }
                if (item.get("lon") != null) {
                    sjArrDzbzhSjWcbryDzxx.setLon(item.getOrDefault("lon", "").toString());
                }
                if (item.get("market") != null) {
                    sjArrDzbzhSjWcbryDzxx.setMarket(item.getOrDefault("market", "").toString());
                }
                if (item.get("twon") != null) {
                    sjArrDzbzhSjWcbryDzxx.setTwon(item.getOrDefault("twon", "").toString());
                }
                if (item.get("administrative_division") != null) {
                    sjArrDzbzhSjWcbryDzxx.setAdministrativeDivision(item.getOrDefault("administrative_division", "").toString());
                }
                if (item.get("standardized_address") != null) {
                    sjArrDzbzhSjWcbryDzxx.setStandardizedAddress(item.getOrDefault("standardized_address", "").toString());
                }
                /*if (item.get("update_time") != null) {
                    sjArrDzbzhSjWcbryDzxx.setUpdateTime(new Date(item.getOrDefault("update_time", "").toString()));
                }*/
                if (item.get("jc_hjdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setJcHjdz(item.getOrDefault("jc_hjdz", "").toString());
                }
                if (item.get("jc_jzdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setJcJzdz(item.getOrDefault("jc_jzdz", "").toString());
                }
                if (item.get("sk_hjdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setSkHjdz(item.getOrDefault("sk_hjdz", "").toString());
                }
                if (item.get("sk_jzdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setSkJzdz(item.getOrDefault("sk_jzdz", "").toString());
                }
                if (item.get("sqy_hjdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setSqyHjdz(item.getOrDefault("sqy_hjdz", "").toString());
                }
                if (item.get("sqy_jzdz") != null) {
                    sjArrDzbzhSjWcbryDzxx.setSqyJzdz(item.getOrDefault("sqy_jzdz", "").toString());
                }
                requestData.add(sjArrDzbzhSjWcbryDzxx);
            }
            return requestData;
        } catch (Exception e) {
            System.err.println("sql运行异常：" + e);
            return null;
        }
    }

    //   批量修改地址表
    public void updateDatas(List<SjArrDzbzhSjWcbryDzxx> sjArrDzbzhSjWcbryDzxxList) {
        String sqls = "update sj_zrr_dzbzh_sj_wcbry_dzxx set lat = ?,lon = ?,level = ?, administrative_division = ?, in_the_area = ?, market = ?" +
                ", result_addr_key = ? , standardized_address = ? , update_time = ?,twon = ? where id = ?";
        try (PreparedStatement preparedStatement = DbConnection.getInstance().connection.prepareStatement(sqls)) {
            for (SjArrDzbzhSjWcbryDzxx entity : sjArrDzbzhSjWcbryDzxxList) {
                if (entity.getId() != null) {
                    if (entity.getLat() == null) {
                        preparedStatement.setNull(1, Types.VARCHAR);
                    } else {
                        preparedStatement.setString(1, entity.getLat());
                    }
                    if (entity.getLon() == null) {
                        preparedStatement.setNull(2, Types.VARCHAR);
                    } else {
                        preparedStatement.setString(2, entity.getLon());
                    }
                    if (entity.getLevel() == null) {
                        preparedStatement.setNull(3, Types.VARCHAR);
                    } else {
                        preparedStatement.setString(3, entity.getLevel());
                    }
                    if (entity.getAdministrativeDivision() == null) {
                        preparedStatement.setNull(4, Types.VARCHAR);
                    } else {
                        preparedStatement.setString(4, entity.getAdministrativeDivision());
                    }
                    if (entity.getInTheArea() == null) {
                        preparedStatement.setNull(5, Types.VARCHAR);
                    } else {
                        preparedStatement.setString(5, entity.getInTheArea());
                    }
                    if (entity.getMarket() == null) {
                        preparedStatement.setNull(6, Types.VARCHAR);
                    } else {
                        preparedStatement.setString(6, entity.getMarket());
                    }
                    if (entity.getResultAddrKey() == null) {
                        preparedStatement.setNull(7, Types.VARCHAR);
                    } else {
                        preparedStatement.setString(7, entity.getResultAddrKey());
                    }
                    if (entity.getStandardizedAddress() == null) {
                        preparedStatement.setNull(8, Types.VARCHAR);
                    } else {
                        preparedStatement.setString(8, entity.getStandardizedAddress());
                    }
                    preparedStatement.setLong(9, entity.getUpdateTime().getTime());
                    if (entity.getTwon() == null) {
                        preparedStatement.setNull(10, Types.VARCHAR);
                    } else {
                        preparedStatement.setString(10, entity.getTwon());
                    }
                    preparedStatement.setString(11, entity.getId());
                    // 将当前的 SQL 语句添加到批量操作中
                    preparedStatement.addBatch();
                }
            }
            // 执行批量操作
            int[] updateCounts = preparedStatement.executeBatch();
            System.out.println("总条数：" + sjArrDzbzhSjWcbryDzxxList.size() + ";更新的记录数: " + updateCounts.length);
        } catch (SQLException throwables) {
            System.err.println("------updateError--------------------------------------" + sqls + "更新异常！");
            throwables.printStackTrace();
            System.err.println("更新异常" + throwables);
        }
    }


    public void uploadAllData(String reAddr,Boolean updateBase) {
        List<SjArrDzbzhSjWcbryDzxx> listData = getAllData(reAddr);
        if (listData != null && listData.size() > 0) {
            if(updateBase){
                updateDatas(runExecutorService(listData));
            }else{
                SerializationUtils.serialize(runExecutorService(listData), "output/testDataBase_all.ser");
            }
//            PageSize++;
//            uploadAllData(PageSize, PageNumber);
//        } else {
            System.out.println("处理完成！");
        }
    }

    /**
     * 首先要得到一个Page<T>对象，然后判断是否还有别的数据，有的话接着请求并返回新的Page<T>对象并迭代处理数据
     * init [0:批量处理；1：初始化]
     */
    public void iterativeProcessing(Integer pageSize, Integer init) {
        System.out.println("<<<<<<<<------iterativeProcessing{pageSize:" + pageSize + "}");
        long startTime = System.currentTimeMillis();
        if (init == 0) {
            List<SjArrDzbzhSjWcbryDzxx> listData = getAllDataPage(pageSize);
            if (listData != null && listData.size() > 0) {
//              批量更新处理后的数据
                updateDatas(runExecutorService(listData));
                long endTime = System.currentTimeMillis();
                System.out.println("处理单批次用时" + (endTime - startTime) / 1000 + "秒！");
                if (listData.size() > 0) {
                    iterativeProcessing(pageSize, init);
                } else {
                    System.out.println("<<<<<<<<------任务处理完成！");
                }
            } else {
                System.out.println("<<<<<<<<------任务处理完成！");
            }
        } else {
            String SqlStr = "update sj_zrr_dzbzh_sj_wcbry_dzxx set lat = null, update_time = null, standardized_address = null, result_addr_key = null, market = null, lon = null, level = null, administrative_division = null, in_the_area = null ,twon = null where in_the_area is not null";
            try {
                int updateDataSum = DbConnection.getInstance().updateSql(SqlStr);
                if (updateDataSum < 1) {
                    System.err.println("------updateError--------------------------------------" + SqlStr + "更新异常！");
                }
                System.out.println("<<<<<<<<------任务处理完成！");
                long endTime = System.currentTimeMillis();
                System.out.println("处理单批次用时" + (endTime - startTime) / 1000 + "秒！");
            } catch (Exception e) {
                System.err.println("更新异常" + e);
            }
        }
    }

    public List<SjArrDzbzhSjWcbryDzxx> runExecutorService(List<SjArrDzbzhSjWcbryDzxx> listData) {
        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        List<Future<?>> futures = new ArrayList<>();
        for (SjArrDzbzhSjWcbryDzxx item : listData) {
            futures.add(executorService.submit(() -> {
                List<String> addrList = new ArrayList<>();
                if (item.getSkHjdz() != null && !item.getSkHjdz().isEmpty() && item.getSkHjdz().length() > 3 && AddressTools.isOtherDistrictThanSongJiang(item.getSkHjdz())) {
                    //  实口户籍地址
                    addrList.add("上海市" + Constant.getArea() + "区" + AddressQueryEngine.addressReplaceAll(item.getSkHjdz()));
                }
                if (item.getSkJzdz() != null && !item.getSkJzdz().isEmpty() && item.getSkJzdz().length() > 3 && AddressTools.isOtherDistrictThanSongJiang(item.getSkJzdz())) {
                    //  实口居住地址
                    addrList.add("上海市" + Constant.getArea() + "区" + AddressQueryEngine.addressReplaceAll(item.getSkJzdz()));
                }
                if (item.getJcHjdz() != null && !item.getJcHjdz().isEmpty() && item.getJcHjdz().length() > 3 && AddressTools.isOtherDistrictThanSongJiang(item.getJcHjdz())) {
                    //  基层户籍地址
                    addrList.add("上海市" + Constant.getArea() + "区" + AddressQueryEngine.addressReplaceAll(item.getJcHjdz()));
                }
                if (item.getJcJzdz() != null && !item.getJcJzdz().isEmpty() && item.getJcJzdz().length() > 3 && AddressTools.isOtherDistrictThanSongJiang(item.getJcJzdz())) {
                    //  基层居住地址
                    addrList.add("上海市" + Constant.getArea() + "区" + AddressQueryEngine.addressReplaceAll(item.getJcJzdz()));
                }
                if (addrList.size() > 0) {
                    //  TODO 开始查询
                    AddressResult addressResult = AddressQueryEngine.getInstance().commonSearchByName(addrList);
                    if (addressResult == null || addressResult.getData() == null || addressResult.getData().size() < 1) {
                        item.setInTheArea("异常");
                        item.setResultAddrKey("未匹配到符合规则的结果");
                    } else {
                        try {
                            for (AddressResult.ContentBean contentBean : addressResult.getData()) {
                                String resultAddrKey = contentBean.getAddress();
                                if (resultAddrKey != null && contentBean.getLon() != null && contentBean.getLat() != null && AddressTools.isOtherDistrictThanSongJiang(resultAddrKey)) {
                                    String lng = contentBean.getLon() + "";
                                    String lat = contentBean.getLat() + "";
                                    item.setInTheArea("是");
                                    if (contentBean.getAdname() != null && !contentBean.getAdname().isEmpty()) {
                                        item.setTwon(contentBean.getAdname());
                                    } else if (contentBean.getTownJson().getString("name") != null) {
                                        item.setTwon(contentBean.getTownJson().getString("name"));
                                    }
                                    if (contentBean.getCityname() != null && !contentBean.getCityname().isEmpty()) {
                                        item.setAdministrativeDivision(contentBean.getCityname());
                                    } else if (contentBean.getAdJson().getString("name") != null) {
                                        item.setAdministrativeDivision(contentBean.getAdJson().getString("name"));
                                    }
                                    item.setLat(lat);
                                    item.setLon(lng);
                                    item.setResultAddrKey(resultAddrKey);
                                    item.setMarket("上海市");
                                    item.setLevel(contentBean.getScore());
                                    //  开始规范化地址（把查询地址的市、区、街镇替换为空，然后把得到的区、街镇拼接上去）（得到区、街镇）
                                    String oldAddress = contentBean.getSearchAddress().replaceAll("上海市", "").replaceAll("松江区", "");
                                    String[] towns = Constant.getTowns();
                                    for (String town : towns) {
                                        oldAddress = oldAddress.replaceAll(town, "");
                                    }
                                    if (contentBean.getCjJson() != null && contentBean.getCjJson().containsKey("所属居委")) {
                                        oldAddress = contentBean.getCjJson().getString("所属居委") + oldAddress;
                                    }
                                    item.setStandardizedAddress("上海市" + item.getAdministrativeDivision() + item.getTwon() + oldAddress);
                                    break;
                                } else {
                                    item.setInTheArea("异常");
                                    item.setResultAddrKey("结果处理异常");
                                }
                            }
                        } catch (Exception e) {
                            item.setInTheArea("异常");
                            System.err.println("查询结果处理异常：" + e);
                        }
                    }
                } else {
                    item.setInTheArea("否");
                }
                item.setUpdateTime(new Date());
            }));
        }

        // 等待所有任务完成
        for (Future<?> future : futures) {
            try {
                future.get();
            } catch (InterruptedException | ExecutionException e) {
                System.err.println("线程异常：" + e);
            }
        }
        // 关闭线程池
        executorService.shutdown();
        return listData;
    }
}
