"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<FeatureProperties>) => void;
};

type Options = {
    editor: EditorDraftApi;
    selectedFeatures: Feature[];
    geometryMetaForm: GeometryMetaFormState;
    setGeometryMetaForm: Dispatch<SetStateAction<GeometryMetaFormState>>;
    selectedGeometryEntityIds: string[];
    setSelectedGeometryEntityIds: Dispatch<SetStateAction<string[]>>;
    entities: Entity[];
    setIsEntitySubmitting: Dispatch<SetStateAction<boolean>>;
    setEntityFormStatus: Dispatch<SetStateAction<string | null>>;
};

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,
    };
}
