type WorkflowDraftStorage = Pick<Storage, 'getItem' | 'removeItem' | 'setItem'>;

interface WorkflowDraftSnapshot {
  baseContentSignature: string;
  content: Record<string, unknown>;
  updatedAt: number;
  version: 1;
  workflowId: string;
}

interface WriteWorkflowDraftOptions {
  baseContentSignature: string;
  content: unknown;
  workflowId: unknown;
}

const WORKFLOW_DRAFT_PREFIX = 'easyflow:workflow-draft';
const WORKFLOW_DRAFT_VERSION = 1;

function isWorkflowContent(
  content: unknown,
): content is Record<string, unknown> {
  return (
    typeof content === 'object' && content !== null && !Array.isArray(content)
  );
}

function resolveSessionStorage(): null | WorkflowDraftStorage {
  if (typeof window === 'undefined') {
    return null;
  }
  try {
    return window.sessionStorage;
  } catch {
    return null;
  }
}

function getStorageKey(workflowId: unknown) {
  const normalizedId = String(workflowId ?? '').trim();
  return normalizedId ? `${WORKFLOW_DRAFT_PREFIX}:${normalizedId}` : '';
}

function removeStoredDraft(
  storage: null | WorkflowDraftStorage,
  storageKey: string,
) {
  if (!storage || !storageKey) {
    return;
  }
  try {
    storage.removeItem(storageKey);
  } catch {
    // 临时缓存清理失败不应阻断工作流编辑。
  }
}

export function createWorkflowContentSignature(content: unknown) {
  try {
    return JSON.stringify(content ?? null);
  } catch {
    return '';
  }
}

export function readWorkflowDraft(
  workflowId: unknown,
  serverContent: unknown,
  storage: null | WorkflowDraftStorage = resolveSessionStorage(),
) {
  const storageKey = getStorageKey(workflowId);
  if (!storage || !storageKey) {
    return null;
  }

  try {
    const raw = storage.getItem(storageKey);
    if (!raw) {
      return null;
    }
    const snapshot = JSON.parse(raw) as Partial<WorkflowDraftSnapshot>;
    const serverContentSignature =
      createWorkflowContentSignature(serverContent);
    const draftContentSignature = createWorkflowContentSignature(
      snapshot.content,
    );
    const isValid =
      snapshot.version === WORKFLOW_DRAFT_VERSION &&
      snapshot.workflowId === String(workflowId) &&
      snapshot.baseContentSignature === serverContentSignature &&
      isWorkflowContent(snapshot.content) &&
      Boolean(draftContentSignature);

    if (!isValid || draftContentSignature === serverContentSignature) {
      removeStoredDraft(storage, storageKey);
      return null;
    }

    return snapshot as WorkflowDraftSnapshot;
  } catch {
    removeStoredDraft(storage, storageKey);
    return null;
  }
}

export function writeWorkflowDraft(
  options: WriteWorkflowDraftOptions,
  storage: null | WorkflowDraftStorage = resolveSessionStorage(),
) {
  const storageKey = getStorageKey(options.workflowId);
  const contentSignature = createWorkflowContentSignature(options.content);
  if (
    !storage ||
    !storageKey ||
    !contentSignature ||
    !options.baseContentSignature ||
    !isWorkflowContent(options.content)
  ) {
    return false;
  }

  if (contentSignature === options.baseContentSignature) {
    removeStoredDraft(storage, storageKey);
    return true;
  }

  const snapshot: WorkflowDraftSnapshot = {
    baseContentSignature: options.baseContentSignature,
    content: options.content,
    updatedAt: Date.now(),
    version: WORKFLOW_DRAFT_VERSION,
    workflowId: String(options.workflowId),
  };
  try {
    storage.setItem(storageKey, JSON.stringify(snapshot));
    return true;
  } catch {
    return false;
  }
}

export function clearWorkflowDraft(
  workflowId: unknown,
  storage: null | WorkflowDraftStorage = resolveSessionStorage(),
) {
  removeStoredDraft(storage, getStorageKey(workflowId));
}
