// NSPD (НСПД) types — Issue #202
// Shapes derived from backend/app/services/site_finder/quarter_dump_lookup.py
// and backend/app/schemas/parcel.py

export interface NspdZoning {
  zone_code: string | null;
  zone_name: string | null;
  source?: string;
  raw_props?: Record<string, unknown>;
  // Real ПЗЗ regulation (PR #1847, synth #1891) — optional + nullable so the
  // cockpit stays backward-compatible until the field flows, then auto-lights-up.
  // NB: max_far / max_height_m / max_building_pct are NUMERIC columns, so they
  // arrive on the wire as STRINGS ("2.4", "12", "80") from the
  // ekb-geoportal-urbancard regulation columns — typed `string | number` so
  // consumers must coerce (see coerceFloat in nspd-regulation.ts) before maths.
  max_far?: string | number | null; // КСИТ (предельный коэф. плотности застройки)
  max_height_m?: string | number | null; // предельная высота, м
  max_floors?: number | null; // предельная этажность
  max_building_pct?: string | number | null; // коэф. застройки (процент пятна)
  min_parcel_area_m2?: number | null; // мин. площадь участка, м²
  regulation_zone_index?: string | null; // human zone index, e.g. "ПК-1"
  regulation_source?: string | null; // источник регламента (ekb-geoportal-urbancard)
  // #1891 — authoritative permitted-use (ВРИ) list of the zone, used by the gate
  // and surfaced read-only in the Раздел 1 регламент-блок (#1962).
  main_vri?: string[] | null;
}

export interface NspdZouitOverlap {
  group_key: string; // e.g. "engineering", "okn", "natural", "protected", "other"
  layer: string; // e.g. "zouit_engineering"; для cad_zouit fallback = type_zone
  subcategory: string | number | null;
  name: string | null;
  // cad_zouit fallback path (quarter_dump_lookup._get_cad_zouit_overlaps) — плоские
  // поля поверх raw_props. type_zone = категория зоны (охранная зона тепла / СЗЗ / …),
  // source = "cad_zouit". В nspd-dump path обоих может не быть → optional.
  type_zone?: string | null;
  category_name?: string | null;
  // #1957 — рег. номер границы охранной зоны (cad_zouit fallback path), напр.
  // "66:41-6.4380". Optional: nspd-dump path может не отдавать поле.
  reg_numb_border?: string | null;
  // #1957 — доля площади участка под зоной (0..1). Optional + graceful.
  coverage_pct?: number | null;
  source?: string;
  // #255 — geometry охранной зоны для map-слоя. ST_AsGeoJSON(geom::geometry) →
  // строка GeoJSON (Polygon/MultiPolygon). Optional + graceful: backend пока может
  // не отдавать поле (см. ZouitLayer — overlap без geom_geojson просто не рисуется).
  geom_geojson?: string | null;
  raw_props?: Record<string, unknown>;
}

export interface NspdEngineeringNearby {
  name: string | null;
  type: string | null;
  distance_m: number | null;
  raw_props?: Record<string, unknown>;
}

export interface NspdDumpMeta {
  available: boolean;
  fetched_at_utc: string | null; // ISO datetime
  stale: boolean;
  harvest_triggered: boolean;
  total_features: number | null;
  // Issue #234: typical harvest duration. Используется UI для countdown +
  // auto-stop re-poll после ETA*1.5. null когда dump уже available или harvest
  // не запущен (lock уже взят другим запросом).
  harvest_eta_seconds?: number | null;
}

// Risk zones (issue #94 TIER 3) — from /analyze nspd_risk_zones field

export interface RiskZone {
  layer: string; // e.g. "risk_flooding", "risk_landslide"
  subtype: string | null; // human-readable label from NSPD properties or mapping
  geom_wkt: string | null;
  intersection_area_sqm: number | null;
}

// Opportunity parcels (issue #94 TIER 4)

export interface OpportunityParcel {
  layer:
    | "auction_parcels"
    | "scheme_parcels"
    | "free_parcels"
    | "future_parcels"
    | "oopt";
  cad_num: string | null;
  distance_m: number | null;
  geom_wkt: string | null;
}

// Red lines (issue #94 TIER 4 + #54 Generative foundation)

export interface RedLine {
  geom_wkt: string | null;
  intersection_length_m: number | null; // null if only nearby, not intersecting
  distance_m: number | null; // null if intersecting
}

// Connection-points endpoint shapes (/api/v1/parcels/{cad}/connection-points)

export interface EngineeringStructure {
  name: string | null;
  type: string | null;
  cad_num: string | null;
  /**
   * #2111 — назначение / класс сооружения (напр. «1.1. Сооружения
   * электроэнергетики»). Backend нуллит поле, когда оно дублирует type → в попапе
   * рендерим только при наличии. Optional + nullable: nspd-dump path может не отдавать.
   */
  purpose?: string | null;
  distance_to_boundary_m: number;
  geometry_geojson: Record<string, unknown>;
  readable_address: string | null;
  /** Год / протяжённость / собственность из НСПД-дампа одной строкой. */
  characteristics?: string | null;
  raw_props: Record<string, unknown>;
  source: string;
}

export interface ZouitEngineeringOverlap {
  reg_numb_border: string | null;
  type_zone: string | null;
  subcategory: number | null;
  intersects_parcel: boolean;
  geometry_geojson: Record<string, unknown>;
  raw_props: Record<string, unknown>;
  source: string;
}

export interface ConnectionPointsSummary {
  nearest_structure_distance_m: number | null;
  in_protection_zone: boolean;
  protection_zones_intersecting: number;
  total_structures_in_radius: number;
}

export interface ConnectionPointsResponse {
  engineering_structures: EngineeringStructure[];
  zouit_engineering_overlaps: ZouitEngineeringOverlap[];
  summary: ConnectionPointsSummary;
  dump_available: boolean;
  dump_fetched_at: string | null;
}
