package org.jeecg.modules.geoAnalysis.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import org.geotools.data.DataUtilities;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.Transaction;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;

import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;


import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.jeecg.modules.commonQueryConfig.entity.CommonQueryConfig;
import org.jeecg.modules.geoAnalysis.entity.GeoAnalysis;
import org.jeecg.modules.geoAnalysis.entity.ZYFXPZB;
import org.jeecg.modules.geoAnalysis.mapper.GeoAnalysisMapper;
import org.jeecg.modules.geoAnalysis.service.IGeoAnlysisService;
import org.jeecg.modules.util.ZipUtils;

import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKTReader;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.sql.Clob;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @Description: 定位信息表
 * @Author: jeecg-boot
 * @Date: 2022-07-01
 * @Version: V1.0
 */
@Service
@Slf4j
public class GeoAnalysisServiceImpl extends ServiceImpl<GeoAnalysisMapper, GeoAnalysis> implements IGeoAnlysisService {
    @Autowired
    GeoAnalysisMapper geoAnalysisMapper;

    @Override
    public ArrayList<GeoAnalysis> DrawMap(List<ZYFXPZB> zyfxpzb, String shape) {
        ArrayList list = new ArrayList();
        DecimalFormat format = new DecimalFormat("0.0000");
        for (ZYFXPZB zyfxpzb1 : zyfxpzb) {
            HashMap hashMap = new HashMap<>();

            String atableenam =  zyfxpzb1.getATABLEENAME();   //分析表英文名称
            String afieldename = zyfxpzb1.getAFIELDENAME();   //分析表英文字段名称
            //分析表中文名称
            String atablecname = zyfxpzb1.getATABLECNAME();   //分析表中文名称
            String afieldcname = zyfxpzb1.getAFIELDCNAME();   //分析表中文字段名称
            //包装shape
            hashMap.put("shape", shape);
            hashMap.put("table", atableenam);
            hashMap.put("DLMC", afieldename);
            List<HashMap<String, Object>> hashMaps = geoAnalysisMapper.DrawMap(hashMap);
            //遍历处理
            for (HashMap<String, Object> map : hashMaps) {
                GeoAnalysis analysis = new GeoAnalysis();
                org.jeecg.modules.geoAnalysis.entity.Result result = new org.jeecg.modules.geoAnalysis.entity.Result();
                analysis.setType(atablecname);
                //解析
                result.setArea(format.format(new BigDecimal(map.get("area").toString())));
                result.setTypes(map.get(afieldename).toString());
                result.setObjectid(map.get("objectid").toString());
                result.setInfo(map.get("info").toString());
                //增加地块编号
                if (null != map.get("dkbh")) {
                    result.setDkbh(map.get("dkbh").toString());
                }
                result.setAtableenam(atableenam);
                analysis.setResult(result);
                analysis.setAfieldcname(afieldcname);
                list.add(analysis);
            }
        }
        return list;
    }

    @Override
    public ZYFXPZB SelectByTbs(String MTABLENAME, String atableename) {
        return geoAnalysisMapper.SelectByTbs(MTABLENAME, atableename);
    }

    @Override
    public List<ZYFXPZB> SelectByTb(String MTABLENAME) {
        return geoAnalysisMapper.SelectByTb(MTABLENAME);
    }


    @Override
    public ArrayList<GeoAnalysis> DrawMapByShape(List<ZYFXPZB> zyfxpzb, List shape, String table) {
        ArrayList list = new ArrayList();
        DecimalFormat format = new DecimalFormat("0.0000");
        HashMap<String, Object> map = new HashMap<>();
        try {
            /* String[] split = atableename.split(",");*/
            for (ZYFXPZB zyfxpzb1 : zyfxpzb) {
                map.put("DLMC", zyfxpzb1.getAFIELDENAME());
                map.put("table", zyfxpzb1.getATABLEENAME());
                map.put("tables", table);//接入的参数
                map.put("shape", shape);
                List<HashMap<String, Object>> hashMaps = geoAnalysisMapper.DrawMapByShape(map);
                for (HashMap<String, Object> hashMap : hashMaps) {
                    if (hashMap.get(zyfxpzb1.getAFIELDENAME()) != null && hashMap.get("area") != null) {
                        GeoAnalysis analysis = new GeoAnalysis();
                        org.jeecg.modules.geoAnalysis.entity.Result result = new org.jeecg.modules.geoAnalysis.entity.Result();
                        analysis.setType(zyfxpzb1.getATABLECNAME());
                        analysis.setAfieldcname(zyfxpzb1.getAFIELDCNAME());
                        //解析
                        result.setTypes(hashMap.get(zyfxpzb1.getAFIELDENAME()).toString());
                        result.setArea(format.format(new BigDecimal(hashMap.get("area").toString())));
                        result.setObjectid(hashMap.get("objectid").toString());
                        result.setInfo(hashMap.get("info").toString());
                        result.setAtableenam(zyfxpzb1.getATABLEENAME());
                        analysis.setResult(result);
                        list.add(analysis);
                    }
                }
            }
//            if (table.equals("GD_DKXX")) {
//                HashMap<String, Object> maps = new HashMap<>();
//                maps.put("shape", shape);
//                HashMap<String, Object> gdxmjbxx = geoAnalysisMapper.SelectGdxmjbxx(maps);
//                list.add(gdxmjbxx);
//
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(list);

        return list;
    }

    @Override
    public HashMap<String, Object> SelectDetails(HashMap map) {
        return geoAnalysisMapper.SelectDetails(map);
    }

    @Override
    public ArrayList<CommonQueryConfig> SelectByTable(String TABLEALIAS) {
        return geoAnalysisMapper.SelectByTable(TABLEALIAS);
    }

    @Override
    public Boolean exportShps(HttpServletResponse response, String id) {
        List<Map<String, Object>> list = geoAnalysisMapper.exportShp(id);
        boolean b = exportShp(response, list);
        return b;
    }

    /**
     * 导出Shp
     */

    public static boolean exportShp(HttpServletResponse response, List<Map<String, Object>> list) {

        boolean flag = false;

        FileOutputStream fileOutputStream = null;

        String id = UUID.randomUUID().toString();

        String tempPath = "D:" + "/temp/" + id + "/";

        String shpFilePath = tempPath + id + ".shp";//临时文件

        String zippath = "D:" + "/temp/" + id + ".zip";//压缩包,把xls文件压缩到zip中，在浏览器下载

        File dir = new File(tempPath);

        if (!dir.exists()) {//每目录就新建

            dir.mkdirs();

        }

//把生成的文件压缩为.zip的

        File zipfile = new File(zippath);

        File shpFile = new File(shpFilePath);

        try {


//定义属性

            final SimpleFeatureType TYPE = DataUtilities.createType("Location",

                    "the_geom:MultiPolygon," + // <- the geometry attribute: Point type

                            "DKMC:String"

            );

            /* SimpleFeatureCollection collection = FeatureCollections.newCollection();*/
            List<SimpleFeature> features = new ArrayList<>();
            SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);

            for (Map<String, Object> row : list) {
                if (row.get("GEOM") instanceof Clob) {
                    Clob clob = (Clob) row.get("GEOM");
                    try {
                        row.put("GEOM", clob.getSubString((long) 1, (int) clob.length()));
                    } catch (SQLException throwables) {
                        throwables.printStackTrace();
                    }
                }
                String wkt = row.get("GEOM").toString();
//WKT转Geometry
                WKTReader wktReader = new WKTReader();
                Geometry geometry = null;
                try {
                    geometry = wktReader.read(wkt);

//geometry.setSRID(4326);
                } catch (Exception e) {

// TODO Auto-generated catch block
                    e.printStackTrace();
                }
                featureBuilder.add(geometry);
                System.out.println("78888888888888888888888" + row.get("DKMC"));
                featureBuilder.add(row.get("DKMC"));

                SimpleFeature feature = featureBuilder.buildFeature(null);
                features.add(feature);

/*feature = featureBuilder.buildFeature(null, obj);

collection.add(feature);*/

            }
            SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, features);


            ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();

            Map<String, Serializable> params = new HashMap<String, Serializable>();

            params.put("url", shpFile.toURI().toURL());

            params.put("create spatial index", Boolean.TRUE);

            ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);

            newDataStore.createSchema(TYPE);
            newDataStore.setCharset(Charset.forName("GBK"));
            newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84);


            Transaction transaction = new DefaultTransaction("create");

            String typeName = newDataStore.getTypeNames()[0];

            SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);


            if (featureSource instanceof SimpleFeatureStore) {

                SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;

                featureStore.setTransaction(transaction);

                try {

                    featureStore.addFeatures(collection);

                    transaction.commit();

                } catch (Exception problem) {

                    problem.printStackTrace();

                    transaction.rollback();

                } finally {

                    transaction.close();

                }
            }
            FileOutputStream fos1 = new FileOutputStream(zipfile);

            ZipUtils.toZip(tempPath, fos1, true);
// 读到流中

            InputStream inStream = new FileInputStream(zippath);//文件的存放路径
// 设置输出的格式
            response.reset();
            response.setContentType("bin");

            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipfile.getName(), "UTF-8"));

            ServletOutputStream outputStream = response.getOutputStream();

// 循环取出流中的数据
            byte[] b = new byte[1024];
            int len;
            while ((len = inStream.read(b)) > 0) {
                outputStream.write(b, 0, len);
            }
            inStream.close();
            outputStream.flush();
            outputStream.close();
            flag = true;

        } catch (Exception e) {

            log.error("【shp导出失败】" + e.getMessage());

        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (Exception e) {
                    log.error("【shp导出流关闭失败】" + e.getMessage());
                }
            }
            File filedir = new File(tempPath);
            if (filedir.exists() && filedir.isDirectory()) {
                File[] files = filedir.listFiles();
                for (File f : files) {
                    if (f.exists()) {
                        f.delete();
                    }
                }
                filedir.delete();
            }
            if (zipfile.exists()) {
                zipfile.delete();
            }
        }
        return flag;

    }


}
