"use client"; import { useCallback } from "react"; import type { Dispatch, SetStateAction } from "react"; import type { Entity } from "@/uhm/types/entities"; import type { Feature, FeatureProperties } from "@/uhm/types/geo"; import { ApiError } from "@/uhm/api/http"; import { buildFeatureEntityPatch } from "@/uhm/lib/editor/entity/entityBinding"; import { buildGeometryMetadataPatch } from "@/uhm/lib/editor/geometry/geometryMetadata"; import { uniqueEntityIds } from "@/uhm/lib/editor/snapshot/editorSnapshot"; import type { GeometryMetaFormState } from "@/uhm/lib/editor/session/sessionTypes"; type EditorDraftApi = { patchFeatureProperties: (id: FeatureProperties["id"], patch: Partial) => void; }; type Options = { editor: EditorDraftApi; selectedFeatures: Feature[]; geometryMetaForm: GeometryMetaFormState; setGeometryMetaForm: Dispatch>; selectedGeometryEntityIds: string[]; setSelectedGeometryEntityIds: Dispatch>; entities: Entity[]; setIsEntitySubmitting: Dispatch>; setEntityFormStatus: Dispatch>; }; export function useFeatureCommands(options: Options) { const { editor, selectedFeatures, geometryMetaForm, setGeometryMetaForm, selectedGeometryEntityIds, setSelectedGeometryEntityIds, entities, setIsEntitySubmitting, setEntityFormStatus, } = options; const applyGeometryMetadata = useCallback(async (): Promise<{ ok: boolean; error?: string }> => { if (!selectedFeatures || selectedFeatures.length === 0) { const msg = "Hãy chọn ít nhất một geometry trước."; setEntityFormStatus(msg); return { ok: false, error: msg }; } if (!geometryMetaForm.time_start.trim() || !geometryMetaForm.time_end.trim()) { const msg = "time_start và time_end là bắt buộc."; setEntityFormStatus(msg); return { ok: false, error: msg }; } let metadata; try { metadata = buildGeometryMetadataPatch(geometryMetaForm); } catch (err) { const msg = err instanceof Error ? err.message : "Thời gian không hợp lệ."; setEntityFormStatus(msg); return { ok: false, error: msg }; } setIsEntitySubmitting(true); setEntityFormStatus(null); try { for (const feature of selectedFeatures) { editor.patchFeatureProperties(feature.properties.id, metadata.patch); } setGeometryMetaForm(metadata.formState); setEntityFormStatus("Đã cập nhật thuộc tính GEO. Commit khi sẵn sàng."); return { ok: true }; } finally { setIsEntitySubmitting(false); } }, [ editor, geometryMetaForm, selectedFeatures, setEntityFormStatus, setGeometryMetaForm, setIsEntitySubmitting, ]); const applyEntitiesToSelectedGeometry = useCallback(async () => { if (!selectedFeatures || selectedFeatures.length === 0) { setEntityFormStatus("Hãy chọn ít nhất một geometry trước."); return; } const entityIds = uniqueEntityIds(selectedGeometryEntityIds); setIsEntitySubmitting(true); setEntityFormStatus(null); try { for (const feature of selectedFeatures) { editor.patchFeatureProperties( feature.properties.id, buildFeatureEntityPatch(feature, entityIds, entities) ); } setSelectedGeometryEntityIds(entityIds); setEntityFormStatus("Đã cập nhật danh sách entity. Commit khi sẵn sàng."); } catch (err) { if (err instanceof ApiError) { setEntityFormStatus(`Lưu thất bại: ${err.body}`); } else { setEntityFormStatus("Lưu thất bại."); } } finally { setIsEntitySubmitting(false); } }, [ editor, entities, selectedFeatures, selectedGeometryEntityIds, setEntityFormStatus, setIsEntitySubmitting, setSelectedGeometryEntityIds, ]); return { applyGeometryMetadata, applyEntitiesToSelectedGeometry, }; }