/**
 * POST /api/eterra/setup-postgis
 *
 * One-time (idempotent) setup: adds native PostGIS geometry column,
 * trigger for auto-conversion, spatial index, and QGIS-friendly views.
 *
 * Safe to call multiple times — all operations use IF NOT EXISTS / CREATE OR REPLACE.
 */
import { prisma } from "@/core/storage/prisma";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

export async function POST() {
  try {
    // Execute the setup SQL statements individually
    // (Prisma $executeRawUnsafe doesn't support multi-statement SQL)

    // 1. Ensure PostGIS extension
    await prisma.$executeRawUnsafe(`CREATE EXTENSION IF NOT EXISTS postgis`);

    // 2. Add native geometry column if missing
    await prisma.$executeRawUnsafe(`
      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
    await prisma.$executeRawUnsafe(`
      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
            NEW.geom := NULL;
          END;
        ELSE
          NEW.geom := NULL;
        END IF;
        RETURN NEW;
      END;
      $$ LANGUAGE plpgsql
    `);

    // 4. Trigger
    await prisma.$executeRawUnsafe(
      `DROP TRIGGER IF EXISTS trg_gis_feature_sync_geom ON "GisFeature"`,
    );
    await prisma.$executeRawUnsafe(`
      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 existing features
    const backfilled: { count: bigint }[] = await prisma.$queryRawUnsafe(`
      WITH updated AS (
        UPDATE "GisFeature"
        SET geom = ST_SetSRID(ST_GeomFromGeoJSON(geometry::text), 3844)
        WHERE geometry IS NOT NULL AND geom IS NULL
        RETURNING id
      )
      SELECT count(*) FROM updated
    `);
    const backfilledCount = Number(backfilled[0]?.count ?? 0);

    // 6. Spatial index
    await prisma.$executeRawUnsafe(`
      CREATE INDEX IF NOT EXISTS gis_feature_geom_idx
        ON "GisFeature" USING GIST (geom)
    `);

    // 7. QGIS-friendly views
    await prisma.$executeRawUnsafe(`
      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
    `);

    await prisma.$executeRawUnsafe(`
      CREATE OR REPLACE VIEW gis_terenuri AS
      SELECT * FROM gis_features
      WHERE layer_id LIKE 'TERENURI%' OR layer_id LIKE 'CADGEN_LAND%'
    `);

    await prisma.$executeRawUnsafe(`
      CREATE OR REPLACE VIEW gis_cladiri AS
      SELECT * FROM gis_features
      WHERE layer_id LIKE 'CLADIRI%' OR layer_id LIKE 'CADGEN_BUILDING%'
    `);

    await prisma.$executeRawUnsafe(`
      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%'
    `);

    await prisma.$executeRawUnsafe(`
      CREATE OR REPLACE VIEW gis_administrativ AS
      SELECT * FROM gis_features
      WHERE layer_id LIKE 'LIMITE%'
         OR layer_id LIKE 'SPECIAL_AREAS%'
    `);

    // Count total features with native geometry
    const total: { count: bigint }[] = await prisma.$queryRawUnsafe(`
      SELECT count(*) FROM "GisFeature" WHERE geom IS NOT NULL
    `);
    const totalWithGeom = Number(total[0]?.count ?? 0);

    return Response.json({
      success: true,
      message: "PostGIS setup complet",
      details: {
        backfilledFeatures: backfilledCount,
        totalFeaturesWithGeom: totalWithGeom,
        trigger: "gis_feature_sync_geom (BEFORE INSERT OR UPDATE OF geometry)",
        index: "gis_feature_geom_idx (GiST)",
        views: [
          "gis_features (master)",
          "gis_terenuri",
          "gis_cladiri",
          "gis_documentatii",
          "gis_administrativ",
        ],
        qgisConnection: {
          host: "10.10.10.166",
          port: 5432,
          database: "architools_db",
          user: "architools_user",
          srid: 3844,
          note: "Adaugă layere din view-uri: gis_terenuri, gis_cladiri, etc.",
        },
      },
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : "Eroare server";
    console.error("[setup-postgis] Error:", error);
    return Response.json({ success: false, error: message }, { status: 500 });
  }
}
