// app/admin/upload/_components/map/StylePreview.tsx
"use client";

import React, { useEffect, useRef } from "react";
import Map from "ol/Map";
import View from "ol/View";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import TileLayer from "ol/layer/Tile";
import OSM from "ol/source/OSM";
import WKT from "ol/format/WKT";
import Feature from "ol/Feature";

import Style from "ol/style/Style";
import Fill from "ol/style/Fill";
import Stroke from "ol/style/Stroke";
import CircleStyle from "ol/style/Circle";
import { defaults as defaultControls } from 'ol/control';

// Import Geostyler dynamic/client side only
import SldStyleParser from "geostyler-sld-parser";
import OlStyleParser from "geostyler-openlayers-parser";

// ... (Kode helper parseWKT, normalizeKey, createFeatures sama seperti sebelumnya) ...
const wkt = new WKT();

function parseWKT(str: string) {
  try {
    return wkt.readGeometry(str, {
      dataProjection: "EPSG:4326",
      featureProjection: "EPSG:3857",
    });
  } catch (e) {
    return null;
  }
}

function normalizeKey(key: string) {
  return key.replace(/[^a-zA-Z0-9_]/g, "_");
}

function createFeatures(data: any[]) {
  if (!data) return [];
  return data.map((row) => {
    const geometry = parseWKT(row.geometry);
    if (!geometry) return null; // Handle invalid geometry
    
    const feat = new Feature();
    Object.entries(row).forEach(([key, value]) => {
      if (key === "geometry") return;
      feat.set(key, value);
      const normalized = normalizeKey(key).toUpperCase();
      if (normalized !== key) {
        feat.set(normalized, value);
      }
    });
    feat.setGeometry(geometry);
    return feat;
  }).filter((f): f is Feature => f !== null);
}

const defaultStyle = new Style({
  image: new CircleStyle({
    radius: 4,
    fill: new Fill({ color: "#3388ff" }),
    stroke: new Stroke({ color: "#333", width: 1 }),
  }),
  stroke: new Stroke({ color: "#3388ff", width: 2 }),
  fill: new Fill({ color: "rgba(51,136,255,0.5)" }),
});

const SpatialStylePreview = ({ data, styleConfig }: { data: any[], styleConfig: any }) => {
  const mapRef = useRef<HTMLDivElement>(null);
  const mapObj = useRef<Map | null>(null);
  const vectorLayer = useRef<VectorLayer<VectorSource> | null>(null);

  useEffect(() => {
    if (!mapRef.current || !data) return;

    if (mapObj.current) mapObj.current.setTarget(undefined);

    const features = createFeatures(data);
    const vectorSource = new VectorSource({ features });
    
    vectorLayer.current = new VectorLayer({
      source: vectorSource,
      style: defaultStyle,
    });

    mapObj.current = new Map({
      target: mapRef.current,
      controls: defaultControls({ attribution: false, zoom: true }),
      layers: [
        new TileLayer({ source: new OSM() }),
        vectorLayer.current,
      ],
      view: new View({
        center: [12600000, -830000], // Sesuaikan center default Indonesia
        zoom: 5,
      }),
    });
    
    // Auto zoom to extent
    const extent = vectorSource.getExtent();
    if (extent && extent[0] !== Infinity) {
      mapObj.current.getView().fit(extent, { padding: [20, 20, 20, 20] });
    }

    return () => { if (mapObj.current) mapObj.current.setTarget(undefined); };
  }, [data]);

  // Apply SLD Logic
  useEffect(() => {
    if (!vectorLayer.current) return;
    if (!styleConfig || styleConfig.styleType !== "sld") {
      vectorLayer.current.setStyle(defaultStyle);
      return;
    }

    const applySLD = async () => {
      try {
        const sldParser = new SldStyleParser();
        const olParser = new OlStyleParser();
        const sldResult = await sldParser.readStyle(styleConfig.sldContent);
        if (!sldResult.output) throw new Error("Empty style");
        
        const olResult = await olParser.writeStyle(sldResult.output);
        const olStyle = olResult.output;

        if (typeof olStyle === "function") {
          vectorLayer.current?.setStyle((f, r) => olStyle(f, r));
        } else {
          vectorLayer.current?.setStyle(olStyle);
        }
        vectorLayer.current?.getSource()?.changed();
      } catch (err) {
        console.warn("SLD parsing failed", err);
        vectorLayer.current?.setStyle(defaultStyle);
      }
    };
    applySLD();
  }, [styleConfig]);

  return <div ref={mapRef} className="w-full h-full rounded-lg border shadow-sm min-h-[400px]" />;
};

export default SpatialStylePreview;