import { create } from 'zustand';

const DEFAULT_TEMPLATE_ID = 'builtin.studio.example';

async function resolveStudioApiConfig() {
  let profileId = null;
  let apiConfig = {};
  try {
    const { default: useApiConfigStore } = await import('../SideBarLeft/ApiConfigSlice');
    const apiState = useApiConfigStore.getState();
    profileId = apiState.currentProfile?.id || null;
    const mainLLM = apiState.currentProfile?.apis?.mainLLM;
    if (mainLLM) {
      apiConfig = {
        api_url: mainLLM.apiUrl || '',
        model: mainLLM.model || '',
      };
    }
  } catch {
    /* optional store */
  }
  return { profileId, apiConfig };
}

async function consumeStudioStreamResponse(res, set, signal) {
  const reader = res.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';
  let finalRun = null;

  const abortHandler = () => {
    reader.cancel().catch(() => {});
  };
  signal?.addEventListener('abort', abortHandler);

  try {
    while (true) {
      if (signal?.aborted) {
        throw new DOMException('Aborted', 'AbortError');
      }
      const { done, value } = await reader.read();
      if (done) break;
      buffer += decoder.decode(value, { stream: true });
      const lines = buffer.split('\n');
      buffer = lines.pop() || '';
      for (const line of lines) {
        if (!line.trim()) continue;
        const event = JSON.parse(line);
        if (event.type === 'thinking_delta') {
          set({ runStreamingThinking: event.content || '' });
        } else if (event.type === 'complete') {
          finalRun = event.run;
        } else if (event.type === 'error') {
          throw new Error(event.detail || '流式处理失败');
        }
      }
    }

    if (buffer.trim()) {
      const event = JSON.parse(buffer);
      if (event.type === 'complete') {
        finalRun = event.run;
      } else if (event.type === 'error') {
        throw new Error(event.detail || '流式处理失败');
      } else if (event.type === 'thinking_delta') {
        set({ runStreamingThinking: event.content || '' });
      }
    }

    if (!finalRun) {
      throw new Error('流式响应未完成');
    }
    return finalRun;
  } finally {
    signal?.removeEventListener('abort', abortHandler);
  }
}

async function parseStudioErrorResponse(res) {
  let detail = await res.text();
  try {
    const parsed = JSON.parse(detail);
    detail = parsed.detail || detail;
  } catch {
    /* keep raw text */
  }
  return detail;
}

let runAbortController = null;

function beginRunRequest(set) {
  if (runAbortController) {
    runAbortController.abort();
  }
  runAbortController = new AbortController();
  set({ runMessaging: true, runStreamingThinking: null, runError: null });
  return runAbortController;
}

function finishRunRequest(set, patch = {}) {
  runAbortController = null;
  set({ runMessaging: false, runStreamingThinking: null, ...patch });
}

function isRunAbortError(error) {
  return error?.name === 'AbortError' || error?.message === 'Aborted';
}

function migrateScoringInNode(node) {
  const scoring = node.config?.scoring;
  if (!scoring || scoring.dimensions?.length) return node;
  if (!scoring.rubric) return node;
  return {
    ...node,
    config: {
      ...node.config,
      scoring: {
        ...scoring,
        dimensions: [
          {
            id: 'default',
            name: '综合质量',
            criteria: scoring.rubric,
          },
        ],
        rubric: undefined,
      },
    },
  };
}

function migratePipeline(pipeline) {
  if (!pipeline) return pipeline;
  return {
    ...pipeline,
    nodes: (pipeline.nodes || []).map(migrateScoringInNode),
  };
}

const useStudioStore = create((set, get) => ({
  projects: [],
  workflowTemplates: [],
  workflowVariables: { builtIn: [], dynamic: [] },
  currentProjectId: null,
  meta: null,
  pipeline: null,
  skillTemplates: [],
  selectedNodeId: null,
  loading: false,
  saving: false,
  error: null,
  saveMessage: null,

  // Studio run (R0)
  runProjectId: null,
  runs: [],
  currentRunId: null,
  currentRun: null,
  runLoading: false,
  runCreating: false,
  runAdvancing: false,
  runMessaging: false,
  runStreamingThinking: null,
  runError: null,
  runSessionEntered: false,

  bindingEditorOpen: false,
  bindingEditorHighlightUid: null,
  bindingEditorInitialTab: 'character',
  bindingEditorSaveNotice: '',

  setSelectedNodeId: (id) => set({ selectedNodeId: id }),
  clearSaveMessage: () => set({ saveMessage: null, error: null }),

  setMetaLocal: (patch) => {
    const { meta } = get();
    if (!meta) return;
    set({ meta: { ...meta, ...patch } });
  },

  setPipelineLocal: (pipeline) => set({ pipeline: migratePipeline(pipeline) }),

  updateNode: (nodeId, patch) => {
    const { pipeline } = get();
    if (!pipeline) return;
    const nodes = pipeline.nodes.map((n) =>
      n.id === nodeId ? { ...n, ...patch } : n
    );
    set({ pipeline: { ...pipeline, nodes } });
  },

  updateNodeConfig: (nodeId, configPatch) => {
    const { pipeline } = get();
    if (!pipeline) return;
    const nodes = pipeline.nodes.map((n) =>
      n.id === nodeId
        ? { ...n, config: { ...(n.config || {}), ...configPatch } }
        : n
    );
    set({ pipeline: { ...pipeline, nodes } });
  },

  reorderNodes: (fromIndex, toIndex) => {
    const { pipeline } = get();
    if (!pipeline || fromIndex === toIndex) return;
    const nodes = [...pipeline.nodes];
    const [moved] = nodes.splice(fromIndex, 1);
    nodes.splice(toIndex, 0, moved);
    set({ pipeline: { ...pipeline, nodes } });
  },

  addNode: (skillId, displayName) => {
    const { pipeline, skillTemplates } = get();
    if (!pipeline) return;
    const tpl = skillTemplates.find((t) => t.skillId === skillId);
    const id = `node-${Date.now()}`;
    const base = {
      id,
      skillId,
      displayName: displayName || tpl?.displayName || skillId,
      enabled: true,
      config: {},
      displayParams: tpl?.displayParams ? [...tpl.displayParams] : [],
      inputs: [],
    };
    if (tpl?.configDefaults) {
      base.config = JSON.parse(JSON.stringify(tpl.configDefaults));
    }
    if (skillId === 'studio.worldbook_entry') {
      base.loopUntilSatisfied = false;
    }
    const nodes = [...pipeline.nodes, base];
    set({
      pipeline: { ...pipeline, nodes },
      selectedNodeId: id,
    });
  },

  removeNode: (nodeId) => {
    const { pipeline, selectedNodeId } = get();
    if (!pipeline) return;
    const nodes = pipeline.nodes.filter((n) => n.id !== nodeId);
    set({
      pipeline: { ...pipeline, nodes },
      selectedNodeId:
        selectedNodeId === nodeId
          ? nodes[0]?.id ?? null
          : selectedNodeId,
    });
  },

  fetchProjects: async () => {
    set({ loading: true, error: null });
    try {
      const res = await fetch('/api/studio/projects');
      if (!res.ok) throw new Error(await res.text());
      const projects = await res.json();
      set({ projects, loading: false });
      return projects;
    } catch (e) {
      set({ loading: false, error: e.message || '加载项目列表失败' });
      return [];
    }
  },

  fetchWorkflowTemplates: async () => {
    try {
      const res = await fetch('/api/studio/templates');
      if (!res.ok) throw new Error(await res.text());
      const templates = await res.json();
      set({ workflowTemplates: templates });
      return templates;
    } catch (e) {
      set({ error: e.message || '加载工作流模板失败' });
      return [];
    }
  },

  fetchWorkflowVariables: async (projectId) => {
    try {
      const qs = projectId
        ? `?projectId=${encodeURIComponent(projectId)}`
        : '';
      const res = await fetch(`/api/studio/variables${qs}`);
      if (!res.ok) throw new Error(await res.text());
      const data = await res.json();
      set({ workflowVariables: data });
      return data;
    } catch (e) {
      set({ error: e.message || '加载工作流变量失败' });
      return { builtIn: [], dynamic: [] };
    }
  },

  fetchSkillTemplates: async () => {
    try {
      const res = await fetch('/api/studio/skill-templates');
      if (!res.ok) throw new Error(await res.text());
      const tplData = await res.json();
      set({ skillTemplates: tplData.templates || [] });
    } catch (e) {
      set({ error: e.message || '加载技能模板失败' });
    }
  },

  fetchProject: async (projectId) => {
    set({ loading: true, error: null });
    try {
      const res = await fetch(`/api/studio/projects/${encodeURIComponent(projectId)}`);
      if (!res.ok) throw new Error(await res.text());
      const data = await res.json();
      const pipeline = migratePipeline(data.pipeline);
      set({
        currentProjectId: data.meta.id,
        meta: data.meta,
        pipeline,
        selectedNodeId: pipeline?.nodes?.[0]?.id ?? null,
        loading: false,
      });
      await get().fetchWorkflowVariables(projectId);
      return { ...data, pipeline };
    } catch (e) {
      set({ loading: false, error: e.message || '加载项目失败' });
      return null;
    }
  },

  savePipeline: async () => {
    const { currentProjectId, pipeline } = get();
    if (!currentProjectId || !pipeline) return false;
    set({ saving: true, error: null, saveMessage: null });
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(currentProjectId)}/pipeline`,
        {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(pipeline),
        }
      );
      if (!res.ok) throw new Error(await res.text());
      const data = await res.json();
      set({
        meta: data.meta,
        pipeline: migratePipeline(data.pipeline),
        saving: false,
        saveMessage: '已保存到本地',
      });
      return true;
    } catch (e) {
      set({
        saving: false,
        error: e.message || '保存失败',
      });
      return false;
    }
  },

  createProject: async (name, templateId = DEFAULT_TEMPLATE_ID) => {
    set({ loading: true, error: null });
    try {
      const res = await fetch('/api/studio/projects', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name, template_id: templateId }),
      });
      if (!res.ok) throw new Error(await res.text());
      const data = await res.json();
      await get().fetchProjects();
      const pipeline = migratePipeline(data.pipeline);
      set({
        currentProjectId: data.meta.id,
        meta: data.meta,
        pipeline,
        selectedNodeId: pipeline?.nodes?.[0]?.id ?? null,
        loading: false,
      });
      await get().fetchWorkflowVariables(data.meta.id);
      return data;
    } catch (e) {
      set({ loading: false, error: e.message || '创建项目失败' });
      return null;
    }
  },

  updateProjectMeta: async (projectId, { name, description } = {}) => {
    if (!projectId) return null;
    set({ saving: true, error: null, saveMessage: null });
    try {
      const body = {};
      if (name !== undefined) body.name = name;
      if (description !== undefined) body.description = description;
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(projectId)}`,
        {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(body),
        }
      );
      if (!res.ok) throw new Error(await res.text());
      const data = await res.json();
      const pipeline = migratePipeline(data.pipeline);
      set({
        meta: data.meta,
        pipeline,
        saving: false,
        saveMessage: '项目信息已保存',
      });
      await get().fetchProjects();
      return data;
    } catch (e) {
      set({
        saving: false,
        error: e.message || '保存项目信息失败',
      });
      return null;
    }
  },

  renameProject: async (projectId, newName) => {
    const trimmed = (newName || '').trim();
    if (!projectId || !trimmed) return null;
    return get().updateProjectMeta(projectId, { name: trimmed });
  },

  deleteProject: async (projectId) => {
    if (!projectId) return false;
    set({ loading: true, error: null, saveMessage: null });
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(projectId)}`,
        { method: 'DELETE' }
      );
      if (!res.ok) throw new Error(await res.text());
      const projects = await get().fetchProjects();
      const nextId = projects[0]?.id ?? null;
      if (nextId) {
        await get().fetchProject(nextId);
      } else {
        set({
          currentProjectId: null,
          meta: null,
          pipeline: null,
          selectedNodeId: null,
        });
      }
      if (get().runProjectId === projectId) {
        set({ runProjectId: nextId, runs: [], currentRunId: null, currentRun: null });
      }
      set({ loading: false, saveMessage: '项目已删除' });
      return true;
    } catch (e) {
      set({ loading: false, error: e.message || '删除项目失败' });
      return false;
    }
  },

  initStudio: async () => {
    await Promise.all([
      get().fetchSkillTemplates(),
      get().fetchWorkflowTemplates(),
      get().fetchProjects(),
    ]);
    const projects = get().projects;
    const id =
      get().currentProjectId ||
      projects[0]?.id ||
      'default';
    if (id) {
      await get().fetchProject(id);
    }
  },

  setRunProjectId: (projectId) => {
    set({
      runProjectId: projectId,
      currentRunId: null,
      currentRun: null,
      runs: [],
      runSessionEntered: false,
    });
  },

  setRunSessionEntered: (entered) => set({ runSessionEntered: !!entered }),

  openBindingEditor: ({ highlightUid = null, tab = 'character', notice = '' } = {}) =>
    set({
      bindingEditorOpen: true,
      bindingEditorHighlightUid: highlightUid,
      bindingEditorInitialTab: tab,
      bindingEditorSaveNotice: notice,
    }),

  closeBindingEditor: () =>
    set({
      bindingEditorOpen: false,
      bindingEditorHighlightUid: null,
      bindingEditorSaveNotice: '',
    }),

  clearBindingEditorNotice: () => set({ bindingEditorSaveNotice: '' }),

  fetchRuns: async (projectId) => {
    if (!projectId) return [];
    set({ runLoading: true, runError: null });
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(projectId)}/runs`
      );
      if (!res.ok) throw new Error(await res.text());
      const runs = await res.json();
      set({ runs, runLoading: false });
      return runs;
    } catch (e) {
      set({
        runLoading: false,
        runError: e.message || '加载运行列表失败',
      });
      return [];
    }
  },

  fetchRun: async (projectId, runId) => {
    if (!projectId || !runId) return null;
    set({ runLoading: true, runError: null });
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(projectId)}/runs/${encodeURIComponent(runId)}`
      );
      if (!res.ok) throw new Error(await res.text());
      const run = await res.json();
      set({
        currentRunId: runId,
        currentRun: run,
        runLoading: false,
        runSessionEntered: false,
      });
      return run;
    } catch (e) {
      set({
        runLoading: false,
        runError: e.message || '加载运行详情失败',
      });
      return null;
    }
  },

  createRun: async (projectId) => {
    if (!projectId) return null;
    set({ runCreating: true, runError: null });
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(projectId)}/runs`,
        { method: 'POST' }
      );
      if (!res.ok) throw new Error(await res.text());
      const run = await res.json();
      await get().fetchRuns(projectId);
      set({
        currentRunId: run.id,
        currentRun: run,
        runCreating: false,
        runSessionEntered: false,
      });
      return run;
    } catch (e) {
      set({
        runCreating: false,
        runError: e.message || '创建运行失败',
      });
      return null;
    }
  },

  selectRun: async (runId) => {
    const projectId = get().runProjectId;
    if (!projectId || !runId) return null;
    return get().fetchRun(projectId, runId);
  },

  advanceRun: async (displayParams, { saveMode = 'advance' } = {}) => {
    const { runProjectId, currentRunId } = get();
    if (!runProjectId || !currentRunId) return null;
    set({ runAdvancing: true, runError: null });
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(runProjectId)}/runs/${encodeURIComponent(currentRunId)}/advance`,
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ displayParams, saveMode }),
        }
      );
      if (!res.ok) {
        let detail = await res.text();
        try {
          const parsed = JSON.parse(detail);
          detail = parsed.detail || detail;
        } catch {
          /* keep raw text */
        }
        throw new Error(detail || '推进运行失败');
      }
      const run = await res.json();
      set({
        currentRun: run,
        runAdvancing: false,
      });
      await get().fetchRuns(runProjectId);
      return run;
    } catch (e) {
      set({
        runAdvancing: false,
        runError: e.message || '推进运行失败',
      });
      return null;
    }
  },

  switchRunNode: async (nodeId) => {
    const { runProjectId, currentRunId } = get();
    if (!runProjectId || !currentRunId || !nodeId) return null;
    set({ runLoading: true, runError: null });
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(runProjectId)}/runs/${encodeURIComponent(currentRunId)}/switch-node`,
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ nodeId }),
        }
      );
      if (!res.ok) {
        let detail = await res.text();
        try {
          const parsed = JSON.parse(detail);
          detail = parsed.detail || detail;
        } catch {
          /* keep raw */
        }
        throw new Error(detail || '切换节点失败');
      }
      const run = await res.json();
      set({ currentRun: run, runLoading: false });
      return run;
    } catch (e) {
      set({
        runLoading: false,
        runError: e.message || '切换节点失败',
      });
      return null;
    }
  },

  saveWorldbookRun: async (saveMode) => {
    const { runProjectId, currentRunId } = get();
    if (!runProjectId || !currentRunId) return null;
    const mode = saveMode === 'overwrite' ? 'overwrite' : 'incremental';
    set({ runAdvancing: true, runError: null });
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(runProjectId)}/runs/${encodeURIComponent(currentRunId)}/save`,
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ mode }),
        }
      );
      if (!res.ok) {
        let detail = await res.text();
        try {
          const parsed = JSON.parse(detail);
          detail = parsed.detail || detail;
        } catch {
          /* keep raw text */
        }
        throw new Error(detail || '保存失败');
      }
      const run = await res.json();
      const nodeState = run.nodeStates?.find((n) => n.nodeId === run.currentNodeId);
      const writtenUid = nodeState?.lastDraft?.writtenEntryUid || null;
      const notice =
        mode === 'overwrite'
          ? '已覆盖保存到世界书'
          : '已增量保存到世界书';
      set({
        currentRun: run,
        runAdvancing: false,
        bindingEditorOpen: true,
        bindingEditorHighlightUid: writtenUid,
        bindingEditorInitialTab: 'worldbook',
        bindingEditorSaveNotice: notice,
      });
      await get().fetchRuns(runProjectId);
      return { run, writtenUid };
    } catch (e) {
      set({
        runAdvancing: false,
        runError: e.message || '保存失败',
      });
      return null;
    }
  },

  sendRunMessage: async (content, { stream = false } = {}) => {
    const { runProjectId, currentRunId } = get();
    if (!runProjectId || !currentRunId) return null;
    const controller = beginRunRequest(set);
    try {
      const { profileId, apiConfig } = await resolveStudioApiConfig();

      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(runProjectId)}/runs/${encodeURIComponent(currentRunId)}/message`,
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            content,
            stream,
            profileId,
            apiConfig,
          }),
          signal: controller.signal,
        }
      );

      if (!res.ok) {
        throw new Error((await parseStudioErrorResponse(res)) || '发送消息失败');
      }

      if (stream && res.body) {
        const finalRun = await consumeStudioStreamResponse(res, set, controller.signal);
        finishRunRequest(set, { currentRun: finalRun });
        return finalRun;
      }

      const run = await res.json();
      finishRunRequest(set, { currentRun: run });
      return run;
    } catch (e) {
      if (isRunAbortError(e)) {
        finishRunRequest(set);
        return null;
      }
      finishRunRequest(set, { runError: e.message || '发送消息失败' });
      return null;
    }
  },

  interruptRun: () => {
    if (runAbortController) {
      runAbortController.abort();
      runAbortController = null;
    }
    set({ runMessaging: false, runStreamingThinking: null });
  },

  undoRun: async () => {
    const { runProjectId, currentRunId } = get();
    if (!runProjectId || !currentRunId) return null;
    const controller = beginRunRequest(set);
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(runProjectId)}/runs/${encodeURIComponent(currentRunId)}/undo`,
        { method: 'POST', signal: controller.signal }
      );
      if (!res.ok) {
        throw new Error((await parseStudioErrorResponse(res)) || '回退失败');
      }
      const run = await res.json();
      finishRunRequest(set, { currentRun: run });
      return run;
    } catch (e) {
      if (isRunAbortError(e)) {
        finishRunRequest(set);
        return null;
      }
      finishRunRequest(set, { runError: e.message || '回退失败' });
      return null;
    }
  },

  rerollRun: async ({ stream = false } = {}) => {
    const { runProjectId, currentRunId } = get();
    if (!runProjectId || !currentRunId) return null;
    const controller = beginRunRequest(set);
    try {
      const { profileId, apiConfig } = await resolveStudioApiConfig();

      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(runProjectId)}/runs/${encodeURIComponent(currentRunId)}/reroll`,
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            stream,
            profileId,
            apiConfig,
          }),
          signal: controller.signal,
        }
      );

      if (!res.ok) {
        throw new Error((await parseStudioErrorResponse(res)) || '重 roll 失败');
      }

      if (stream && res.body) {
        const finalRun = await consumeStudioStreamResponse(res, set, controller.signal);
        finishRunRequest(set, { currentRun: finalRun });
        return finalRun;
      }

      const run = await res.json();
      finishRunRequest(set, { currentRun: run });
      return run;
    } catch (e) {
      if (isRunAbortError(e)) {
        finishRunRequest(set);
        return null;
      }
      finishRunRequest(set, { runError: e.message || '重 roll 失败' });
      return null;
    }
  },

  deleteRun: async (runId) => {
    const projectId = get().runProjectId;
    if (!projectId || !runId) return false;
    set({ runLoading: true, runError: null });
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(projectId)}/runs/${encodeURIComponent(runId)}`,
        { method: 'DELETE' }
      );
      if (!res.ok) throw new Error(await res.text());
      const runs = await get().fetchRuns(projectId);
      const { currentRunId } = get();
      if (currentRunId === runId) {
        const nextId = runs[0]?.id ?? null;
        if (nextId) {
          await get().fetchRun(projectId, nextId);
        } else {
          set({ currentRunId: null, currentRun: null, runLoading: false });
        }
      } else {
        set({ runLoading: false });
      }
      return true;
    } catch (e) {
      set({
        runLoading: false,
        runError: e.message || '删除运行失败',
      });
      return false;
    }
  },

  renameRun: async (runId, title) => {
    const projectId = get().runProjectId;
    if (!projectId || !runId) return null;
    set({ runError: null });
    try {
      const res = await fetch(
        `/api/studio/projects/${encodeURIComponent(projectId)}/runs/${encodeURIComponent(runId)}`,
        {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ title }),
        }
      );
      if (!res.ok) {
        let detail = await res.text();
        try {
          const parsed = JSON.parse(detail);
          detail = parsed.detail || detail;
        } catch {
          /* keep raw text */
        }
        throw new Error(detail || '重命名失败');
      }
      const run = await res.json();
      if (get().currentRunId === runId) {
        set({ currentRun: run });
      }
      await get().fetchRuns(projectId);
      return run;
    } catch (e) {
      set({ runError: e.message || '重命名失败' });
      return null;
    }
  },

  initStudioRun: async () => {
    await Promise.all([
      get().fetchProjects(),
      get().fetchSkillTemplates(),
    ]);
    const projects = get().projects;
    const projectId =
      get().runProjectId ||
      get().currentProjectId ||
      projects[0]?.id ||
      'default';
    set({ runProjectId: projectId });
    await get().fetchWorkflowVariables(projectId);
    const runs = await get().fetchRuns(projectId);
    const runId = get().currentRunId || runs[0]?.id || null;
    if (runId) {
      await get().fetchRun(projectId, runId);
    }
  },
}));

export default useStudioStore;
