const DRAFT_STORAGE_PREFIX = 'humand:web:composer-draft:v1';
const DEFAULT_DRAFT_TTL_MS = 7 * 24 * 60 * 60 * 1000;

type DraftScope = 'feed' | 'groups';

type ComposerDraftPayload = {
  bodyHtml: string;
  updatedAt: number;
};

type BuildPostDraftKeyParams = {
  scope: DraftScope;
  instanceId: number | string;
  userId: number | string;
  groupId?: number | string | null;
};

type BuildCommentDraftKeyParams = {
  scope: DraftScope;
  postId: number | string;
  userId: number | string;
  parentId?: number | string | null;
  groupId?: number | string | null;
};

type BuildConversationDraftKeyParams = {
  userId: number | string;
  conversationId: string;
};

const hasWindowStorage = () =>
  typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';

const trim = (value: string) => value.trim();

const getStorageKey = (suffix: string) => `${DRAFT_STORAGE_PREFIX}:${suffix}`;

const isExpired = (updatedAt: number, ttlMs: number) =>
  Number.isFinite(updatedAt) && Date.now() - updatedAt > ttlMs;

const parseDraft = (raw: string | null): ComposerDraftPayload | null => {
  if (!raw) {
    return null;
  }

  try {
    const parsed = JSON.parse(raw) as ComposerDraftPayload;
    if (
      !parsed ||
      typeof parsed.bodyHtml !== 'string' ||
      typeof parsed.updatedAt !== 'number'
    ) {
      return null;
    }
    return parsed;
  } catch {
    return null;
  }
};

export const buildPostDraftKey = ({
  scope,
  instanceId,
  userId,
  groupId,
}: BuildPostDraftKeyParams) => {
  const groupSegment =
    scope === 'groups' ? `:group:${groupId ?? 'unknown'}` : '';

  return getStorageKey(
    `post:${scope}${groupSegment}:instance:${instanceId}:user:${userId}`,
  );
};

export const buildConversationDraftKey = ({
  userId,
  conversationId,
}: BuildConversationDraftKeyParams) =>
  getStorageKey(`conversation:user:${userId}:id:${conversationId}`);

export const buildCommentDraftKey = ({
  scope,
  postId,
  userId,
  parentId = null,
  groupId,
}: BuildCommentDraftKeyParams) => {
  const groupSegment =
    scope === 'groups' ? `:group:${groupId ?? 'unknown'}` : '';
  const normalizedParentId = parentId ?? 'root';

  return getStorageKey(
    `comment:${scope}${groupSegment}:post:${postId}:parent:${normalizedParentId}:user:${userId}`,
  );
};

export const readComposerDraft = (
  key: string,
  options?: { ttlMs?: number },
): string => {
  if (!hasWindowStorage()) {
    return '';
  }

  const ttlMs = options?.ttlMs ?? DEFAULT_DRAFT_TTL_MS;
  const raw = window.localStorage.getItem(key);
  const parsed = parseDraft(raw);

  if (!parsed) {
    if (raw !== null) {
      window.localStorage.removeItem(key);
    }
    return '';
  }

  if (isExpired(parsed.updatedAt, ttlMs)) {
    window.localStorage.removeItem(key);
    return '';
  }

  return parsed.bodyHtml;
};

export const writeComposerDraft = (key: string, bodyHtml: string) => {
  if (!hasWindowStorage()) {
    return;
  }

  const normalized = trim(bodyHtml);
  if (!normalized) {
    window.localStorage.removeItem(key);
    return;
  }

  const payload: ComposerDraftPayload = {
    bodyHtml,
    updatedAt: Date.now(),
  };

  try {
    window.localStorage.setItem(key, JSON.stringify(payload));
  } catch {
    // Best effort persistence.
  }
};

export const clearComposerDraft = (key: string) => {
  if (!hasWindowStorage()) {
    return;
  }

  window.localStorage.removeItem(key);
};

const removeKeysByPrefix = (prefix: string): void => {
  Object.keys(window.localStorage)
    .filter(key => key.startsWith(prefix))
    .forEach(key => {
      window.localStorage.removeItem(key);
    });
};

export const clearLocalStorageDrafts = ({
  cleanConversations = true,
  cleanPosts = false,
  cleanComments = false,
}: {
  cleanConversations?: boolean;
  cleanPosts?: boolean;
  cleanComments?: boolean;
} = {}): void => {
  if (!hasWindowStorage()) {
    return;
  }

  if (cleanConversations) {
    removeKeysByPrefix(getStorageKey('conversation:'));
  }

  if (cleanPosts) {
    removeKeysByPrefix(getStorageKey('post:'));
  }

  if (cleanComments) {
    removeKeysByPrefix(getStorageKey('comment:'));
  }
};
