package com.kamco.cd.kamcoback.Innopam.utils;

import java.io.File;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import org.geotools.api.data.DataStore;
import org.geotools.api.data.DataStoreFinder;
import org.geotools.api.data.SimpleFeatureSource;
import org.geotools.api.feature.simple.SimpleFeature;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.index.strtree.STRtree;

public class ShpIndexManager {

  private static final String SHP_ROOT = "/shp";
  private static final String SHP_YYYYMM = "202512";
  private static final String PNU_FIELD = "PNU";

  private final Map<String, STRtree> cache = new ConcurrentHashMap<>();

  public STRtree getIndex(String sidoCode) {
    return cache.computeIfAbsent(sidoCode, this::loadIndex);
  }

  private STRtree loadIndex(String sidoCode) {
    try {
      String path = SHP_ROOT + "/LSMD_CONT_LDREG_" + sidoCode + "_" + SHP_YYYYMM + ".shp";

      File shp = new File(path);
      if (!shp.exists()) {
        return null;
      }

      STRtree index = new STRtree(10);

      DataStore store = DataStoreFinder.getDataStore(Map.of("url", shp.toURI().toURL()));

      String typeName = store.getTypeNames()[0];
      SimpleFeatureSource source = store.getFeatureSource(typeName);
      SimpleFeatureCollection col = source.getFeatures();

      try (SimpleFeatureIterator it = col.features()) {
        while (it.hasNext()) {
          SimpleFeature f = it.next();
          Geometry geom = (Geometry) f.getDefaultGeometry();
          String pnu = Objects.toString(f.getAttribute(PNU_FIELD), null);
          if (geom != null && pnu != null) {
            index.insert(geom.getEnvelopeInternal(), new ShpRow(geom, pnu));
          }
        }
      }

      index.build();
      store.dispose();
      return index;

    } catch (Exception e) {
      return null;
    }
  }

  /** SHP 한 row */
  public static class ShpRow {

    public final Geometry geom;
    public final String pnu;

    public ShpRow(Geometry geom, String pnu) {
      this.geom = geom;
      this.pnu = pnu;
    }
  }
}
