-- =============================================================================
-- PostGIS native geometry setup for GisFeature
-- Run once via POST /api/eterra/setup-postgis (idempotent — safe to re-run)
--
-- What this does:
--   1. Ensures PostGIS extension
--   2. Adds native geometry column (geom) if missing
--   3. Creates trigger to auto-convert GeoJSON → native on INSERT/UPDATE
--   4. Backfills existing features that have JSON geometry but no native geom
--   5. Creates GiST spatial index for fast spatial queries
--   6. Creates QGIS-friendly views with clean column names
-- =============================================================================

-- 1. Ensure PostGIS extension
CREATE EXTENSION IF NOT EXISTS postgis;

-- 2. Add native geometry column (idempotent)
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.columns
    WHERE table_name = 'GisFeature' AND column_name = 'geom'
  ) THEN
    ALTER TABLE "GisFeature" ADD COLUMN geom geometry(Geometry, 3844);
  END IF;
END $$;

-- 3. Trigger function: auto-convert GeoJSON (geometry JSON column) → native PostGIS (geom)
CREATE OR REPLACE FUNCTION gis_feature_sync_geom()
RETURNS TRIGGER AS $$
BEGIN
  IF NEW.geometry IS NOT NULL THEN
    BEGIN
      NEW.geom := ST_SetSRID(ST_GeomFromGeoJSON(NEW.geometry::text), 3844);
    EXCEPTION WHEN OTHERS THEN
      -- Invalid GeoJSON → leave geom NULL rather than fail the write
      NEW.geom := NULL;
    END;
  ELSE
    NEW.geom := NULL;
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- 4. Attach trigger (drop + recreate for idempotency)
DROP TRIGGER IF EXISTS trg_gis_feature_sync_geom ON "GisFeature";
CREATE TRIGGER trg_gis_feature_sync_geom
  BEFORE INSERT OR UPDATE OF geometry ON "GisFeature"
  FOR EACH ROW
  EXECUTE FUNCTION gis_feature_sync_geom();

-- 5. Backfill: convert existing JSON geometries to native
UPDATE "GisFeature"
SET geom = ST_SetSRID(ST_GeomFromGeoJSON(geometry::text), 3844)
WHERE geometry IS NOT NULL AND geom IS NULL;

-- 6. GiST spatial index for fast bounding-box / intersection queries
CREATE INDEX IF NOT EXISTS gis_feature_geom_idx
  ON "GisFeature" USING GIST (geom);

-- B-tree index on layerId for view filtering (LIKE 'TERENURI%', 'CLADIRI%')
CREATE INDEX IF NOT EXISTS gis_feature_layer_id_idx
  ON "GisFeature" ("layerId");

-- =============================================================================
-- 7. QGIS-friendly views
--    - Clean snake_case column names
--    - Only rows with valid geometry
--    - One master view + per-category views
-- =============================================================================

-- Master view: all features
CREATE OR REPLACE VIEW gis_features AS
SELECT
  id,
  "layerId"      AS layer_id,
  siruta,
  "objectId"     AS object_id,
  "inspireId"    AS inspire_id,
  "cadastralRef" AS cadastral_ref,
  "areaValue"    AS area_value,
  "isActive"     AS is_active,
  attributes,
  enrichment,
  "enrichedAt"   AS enriched_at,
  "projectId"    AS project_id,
  "createdAt"    AS created_at,
  "updatedAt"    AS updated_at,
  geom
FROM "GisFeature"
WHERE geom IS NOT NULL;

-- Terenuri (parcels)
CREATE OR REPLACE VIEW gis_terenuri AS
SELECT * FROM gis_features
WHERE layer_id LIKE 'TERENURI%' OR layer_id LIKE 'CADGEN_LAND%';

-- Clădiri (buildings)
CREATE OR REPLACE VIEW gis_cladiri AS
SELECT * FROM gis_features
WHERE layer_id LIKE 'CLADIRI%' OR layer_id LIKE 'CADGEN_BUILDING%';

-- Documentații (expertize, zone interes, recepții)
CREATE OR REPLACE VIEW gis_documentatii AS
SELECT * FROM gis_features
WHERE layer_id LIKE 'EXPERTIZA%'
   OR layer_id LIKE 'ZONE_INTERES%'
   OR layer_id LIKE 'RECEPTII%';

-- Administrativ (limite UAT, intravilan, arii speciale)
CREATE OR REPLACE VIEW gis_administrativ AS
SELECT * FROM gis_features
WHERE layer_id LIKE 'LIMITE%'
   OR layer_id LIKE 'SPECIAL_AREAS%';

-- =============================================================================
-- Done! QGIS connection: PostgreSQL → 10.10.10.166:5432 / architools_db
-- Add layers from views: gis_terenuri, gis_cladiri, gis_documentatii, etc.
-- SRID: 3844 (Stereo70)
-- =============================================================================
