import { beforeEach, describe, expect, it, vi } from 'vitest';

import {
  clearWorkflowDraft,
  createWorkflowContentSignature,
  readWorkflowDraft,
  writeWorkflowDraft,
} from '../workflowDraftCache';

const workflowId = 'workflow-1';
const serverContent = {
  edges: [],
  nodes: [{ id: 'start' }],
};
const draftContent = {
  edges: [],
  nodes: [{ id: 'start' }, { id: 'llm' }],
};

describe('workflowDraftCache', () => {
  beforeEach(() => {
    sessionStorage.clear();
  });

  it('按工作流保存并恢复当前浏览器标签页中的草稿', () => {
    expect(
      writeWorkflowDraft({
        baseContentSignature: createWorkflowContentSignature(serverContent),
        content: draftContent,
        workflowId,
      }),
    ).toBe(true);

    expect(readWorkflowDraft(workflowId, serverContent)?.content).toEqual(
      draftContent,
    );
    expect(readWorkflowDraft('workflow-2', serverContent)).toBeNull();
  });

  it('内容回到服务端版本时自动移除草稿', () => {
    writeWorkflowDraft({
      baseContentSignature: createWorkflowContentSignature(serverContent),
      content: draftContent,
      workflowId,
    });

    expect(
      writeWorkflowDraft({
        baseContentSignature: createWorkflowContentSignature(serverContent),
        content: serverContent,
        workflowId,
      }),
    ).toBe(true);
    expect(readWorkflowDraft(workflowId, serverContent)).toBeNull();
  });

  it('服务端内容已更新时丢弃旧草稿，避免覆盖新版本', () => {
    writeWorkflowDraft({
      baseContentSignature: createWorkflowContentSignature(serverContent),
      content: draftContent,
      workflowId,
    });

    const updatedServerContent = {
      edges: [{ id: 'edge-1' }],
      nodes: [{ id: 'start' }, { id: 'end' }],
    };
    expect(readWorkflowDraft(workflowId, updatedServerContent)).toBeNull();
    expect(readWorkflowDraft(workflowId, serverContent)).toBeNull();
  });

  it('保存期间产生的新编辑可基于已保存版本继续缓存', () => {
    const newerDraftContent = {
      edges: [{ id: 'edge-1' }],
      nodes: [...draftContent.nodes, { id: 'end' }],
    };

    writeWorkflowDraft({
      baseContentSignature: createWorkflowContentSignature(serverContent),
      content: draftContent,
      workflowId,
    });
    expect(
      writeWorkflowDraft({
        baseContentSignature: createWorkflowContentSignature(draftContent),
        content: newerDraftContent,
        workflowId,
      }),
    ).toBe(true);

    expect(readWorkflowDraft(workflowId, draftContent)?.content).toEqual(
      newerDraftContent,
    );
  });

  it('缓存不可写时返回失败且不抛出异常', () => {
    const storage = {
      getItem: vi.fn(() => null),
      removeItem: vi.fn(),
      setItem: vi.fn(() => {
        throw new Error('quota exceeded');
      }),
    };

    expect(
      writeWorkflowDraft(
        {
          baseContentSignature: createWorkflowContentSignature(serverContent),
          content: draftContent,
          workflowId,
        },
        storage,
      ),
    ).toBe(false);
  });

  it('忽略结构异常的缓存内容', () => {
    sessionStorage.setItem(
      `easyflow:workflow-draft:${workflowId}`,
      JSON.stringify({
        baseContentSignature: createWorkflowContentSignature(serverContent),
        content: 'invalid',
        updatedAt: Date.now(),
        version: 1,
        workflowId,
      }),
    );

    expect(readWorkflowDraft(workflowId, serverContent)).toBeNull();
  });

  it('可显式清理已保存草稿', () => {
    writeWorkflowDraft({
      baseContentSignature: createWorkflowContentSignature(serverContent),
      content: draftContent,
      workflowId,
    });

    clearWorkflowDraft(workflowId);

    expect(readWorkflowDraft(workflowId, serverContent)).toBeNull();
  });
});
