import type { FeatureCollection, Geometry } from "geojson"; export const ARTIFACT_PANE_MIN_WIDTH = 600; export const ARTIFACT_MAP_SPLIT_MIN_WIDTH = ARTIFACT_PANE_MIN_WIDTH * 2 + 1; export const CONDITION_PANE_MIN_WIDTH = 880; export const CONDITION_MAP_SPLIT_MIN_WIDTH = ARTIFACT_PANE_MIN_WIDTH + CONDITION_PANE_MIN_WIDTH + 1; export type ArtifactType = "diagnosis" | "simulation" | "metric_analysis"; export type ArtifactLifecycle = "draft" | "reviewed" | "published" | "archived"; export type ArtifactViewMode = "map_split" | "focus"; export type ArtifactRequestedView = ArtifactViewMode | "map_only"; export type ArtifactMapRelation = "required" | "optional" | "none"; export type WorkbenchSurfaceMode = "default" | ArtifactRequestedView; export type AnalysisMetric = { label: string; value: string; detail: string; tone: "neutral" | "info" | "success" | "warning" | "danger"; }; export type AnalysisChartSeries = { name: string; values: number[]; color: string; type?: "line" | "bar"; }; export type AnalysisBlock = | { id: string; kind: "metric-grid"; title: string; span: 12; metrics: AnalysisMetric[]; } | { id: string; kind: "chart"; title: string; description: string; span: 5 | 7 | 12; chartType: "line" | "bar"; categories: string[]; unit: string; series: AnalysisChartSeries[]; } | { id: string; kind: "process-flow"; title: string; description: string; span: 5 | 7 | 12; nodes: Array<{ id: string; label: string; detail: string; status: "complete" | "active" | "pending"; }>; } | { id: string; kind: "data-table"; title: string; description: string; span: 5 | 7 | 12; columns: Array<{ key: string; label: string; numeric?: boolean }>; rows: Array>; } | { id: string; kind: "narrative"; title: string; span: 5 | 7 | 12; paragraphs: string[]; }; export type AnalysisArtifactAction = { id: string; label: string; description: string; tone: "primary" | "neutral" | "warning"; }; export type AnalysisArtifact = { id: string; origin?: "agent" | "backend" | "demo"; type: ArtifactType; lifecycle: ArtifactLifecycle; revision: number; title: string; subtitle: string; summary: string; scope: string; confidence: string; generatedAt: string; analyticalTimeRange: { start: string; end: string }; preferredView: ArtifactViewMode; mapRelation: ArtifactMapRelation; spatialOverlay?: FeatureCollection; blocks: AnalysisBlock[]; sources: string[]; limitations: string[]; actions: AnalysisArtifactAction[]; }; export type ArtifactWorkspaceState = { pendingArtifact: AnalysisArtifact | null; activeArtifact: AnalysisArtifact | null; requestedView: ArtifactRequestedView; }; export function createInitialArtifactWorkspaceState(): ArtifactWorkspaceState { return { pendingArtifact: null, activeArtifact: null, requestedView: "map_split" }; } export function previewAnalysisArtifact( state: ArtifactWorkspaceState, artifact: AnalysisArtifact ): ArtifactWorkspaceState { return { ...state, pendingArtifact: artifact }; } export function openPendingArtifact(state: ArtifactWorkspaceState): ArtifactWorkspaceState { if (!state.pendingArtifact) return state; return { pendingArtifact: null, activeArtifact: state.pendingArtifact, requestedView: getPreferredArtifactView(state.pendingArtifact) }; } export function openAnalysisArtifact( _state: ArtifactWorkspaceState, artifact: AnalysisArtifact ): ArtifactWorkspaceState { return { pendingArtifact: null, activeArtifact: artifact, requestedView: getPreferredArtifactView(artifact) }; } export function collapseActiveArtifact(state: ArtifactWorkspaceState): ArtifactWorkspaceState { if (!state.activeArtifact) return state; return { ...state, pendingArtifact: state.activeArtifact, activeArtifact: null }; } export function destroyPendingArtifact(state: ArtifactWorkspaceState): ArtifactWorkspaceState { return state.pendingArtifact ? { ...state, pendingArtifact: null } : state; } export function destroyActiveArtifact(state: ArtifactWorkspaceState): ArtifactWorkspaceState { return state.activeArtifact ? { ...state, activeArtifact: null, requestedView: "map_split" } : state; } export function requestArtifactView( state: ArtifactWorkspaceState, view: ArtifactRequestedView ): ArtifactWorkspaceState { if (!state.activeArtifact) return state; return { ...state, requestedView: view }; } export function resolveWorkbenchSurfaceMode( state: ArtifactWorkspaceState, businessWorkspaceWidth: number ): WorkbenchSurfaceMode { const artifact = state.activeArtifact; if (!artifact) return "default"; if (state.requestedView === "map_only") return "map_only"; if (state.requestedView === "focus") return "focus"; return businessWorkspaceWidth >= ARTIFACT_MAP_SPLIT_MIN_WIDTH ? "map_split" : "focus"; } function getPreferredArtifactView(artifact: AnalysisArtifact): ArtifactViewMode { return artifact.mapRelation === "none" ? "focus" : artifact.preferredView; }