/*
 * Copyright (c) 2023-2025 Datalayer, Inc.
 * Distributed under the terms of the Modified BSD License.
 */
/**
 * Hook for fetching and managing projects.
 *
 * Projects are backed by the Spacer service as spaces with type_s="project".
 * Projects persist forever — only agents can terminate.
 *
 * Free tier limits: max 3 projects per user.
 *
 * @module hooks/useProjects
 */
import { useMemo, useCallback } from 'react';
import { useCache } from './useCache.js';
/** The space type value used to identify project spaces in Solr */
export const PROJECT_SPACE_VARIANT = 'project';
/**
 * Hook to fetch user's projects (spaces with type "project").
 *
 * Uses the spacer service's spaces endpoint filtered by type.
 */
export function useProjects() {
    const { useUserSpaces } = useCache();
    const { data: allSpaces, ...rest } = useUserSpaces();
    // Filter to only project-type spaces
    const projects = useMemo(() => {
        if (!allSpaces)
            return [];
        return allSpaces
            .filter((space) => space.variant === PROJECT_SPACE_VARIANT ||
            space.type_s === PROJECT_SPACE_VARIANT)
            .map((space) => ({
            uid: space.uid,
            id: space.id ?? space.uid,
            handle: space.handle ?? space.handle_s,
            name: space.name ?? space.name_t,
            description: space.description ?? space.description_t ?? '',
            createdAt: space.created_at ? new Date(space.created_at) : new Date(),
            isPublic: space.public ?? space.public_b ?? false,
            attachedAgentPodName: space.attached_agent_pod_name_s || undefined,
            attachedAgentSpecId: space.attached_agent_spec_id_s || undefined,
        }));
    }, [allSpaces]);
    return { data: projects, ...rest };
}
/**
 * Hook to fetch a single project by UID.
 */
export function useProject(uid) {
    const { useSpace } = useCache();
    // useSpace requires a string – pass empty string when uid is undefined
    // (the query is disabled when spaceId is falsy inside useCache)
    const { data: space, ...rest } = useSpace(uid ?? '');
    const project = useMemo(() => {
        if (!space)
            return undefined;
        const s = space;
        return {
            uid: s.uid,
            id: s.id ?? s.uid,
            handle: s.handle ?? s.handle_s,
            name: s.name ?? s.name_t,
            description: s.description ?? s.description_t ?? '',
            createdAt: s.created_at ? new Date(s.created_at) : new Date(),
            isPublic: s.public ?? s.public_b ?? false,
            attachedAgentPodName: s.attached_agent_pod_name_s || undefined,
            attachedAgentSpecId: s.attached_agent_spec_id_s || undefined,
        };
    }, [space]);
    return { data: project, ...rest };
}
/**
 * Hook to create a new project.
 * Creates a space with type "project" via the spacer service.
 */
export function useCreateProject() {
    const { useCreateSpace } = useCache();
    const createSpaceMutation = useCreateSpace();
    const createProject = useCallback(async (request) => {
        const spaceHandle = request.name
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '');
        return createSpaceMutation.mutateAsync({
            space: {
                name: request.name,
                description: request.description || '',
                handle: spaceHandle || `project-${Date.now()}`,
                variant: PROJECT_SPACE_VARIANT,
                public: false,
            },
        });
    }, [createSpaceMutation]);
    return {
        ...createSpaceMutation,
        createProject,
    };
}
/**
 * Hook to update a project (e.g. persist the attached agent pod name).
 * Uses the spacer PUT endpoint via useUpdateSpace.
 */
export function useUpdateProject() {
    const { useUpdateSpace } = useCache();
    const updateSpaceMutation = useUpdateSpace();
    /** Assign an agent runtime to the project */
    const assignAgent = useCallback(async (project, agentPodName, agentSpecId) => {
        return updateSpaceMutation.mutateAsync({
            id: project.id,
            name: project.name,
            description: project.description,
            attached_agent_pod_name_s: agentPodName,
            attached_agent_spec_id_s: agentSpecId || '',
        });
    }, [updateSpaceMutation]);
    /** Rename a project */
    const renameProject = useCallback(async (project, newName) => {
        return updateSpaceMutation.mutateAsync({
            id: project.id,
            name: newName,
            description: project.description,
        });
    }, [updateSpaceMutation]);
    /** Remove the agent assignment from the project */
    const unassignAgent = useCallback(async (project) => {
        return updateSpaceMutation.mutateAsync({
            id: project.id,
            name: project.name,
            description: project.description,
            attached_agent_pod_name_s: '',
            attached_agent_spec_id_s: '',
        });
    }, [updateSpaceMutation]);
    return {
        ...updateSpaceMutation,
        assignAgent,
        unassignAgent,
        renameProject,
    };
}
/**
 * Hook to refresh the projects list.
 */
export function useRefreshProjects() {
    const { useRefreshUserSpaces } = useCache();
    return useRefreshUserSpaces();
}
/**
 * Hook to delete a project (space) and all its contents.
 */
export function useDeleteProject() {
    const { useDeleteSpace } = useCache();
    return useDeleteSpace();
}
/**
 * Hook to fetch the default notebook and document UIDs for a project.
 *
 * This calls the spacer `GET /spaces/:uid/default-items` endpoint which
 * returns the UID of the first notebook and first document in the space.
 */
export function useProjectDefaultItems(projectUid) {
    const { useSpaceDefaultItems } = useCache();
    return useSpaceDefaultItems(projectUid);
}
