import { getDb } from '@/shared/db';
import {
  markRead,
  markAllRepliedRead,
  getReadState,
  type ConversationReadState,
  type ReadSource,
} from '@/entities/conversation-read';

export interface MarkReadOptions {
  /** Mark read through this instant (ISO); defaults to "now". */
  readThrough?: string | null;
  source?: ReadSource;
}

function wrap(err: unknown, op: string): Error {
  return new Error(`read/${op} failed: ${err instanceof Error ? err.message : String(err)}`, {
    cause: err,
  });
}

/**
 * Mark a single conversation (by the lead's handle) read. Logical-read model —
 * nothing is written to Apple's chat.db; the inbox reads this state. Idempotent.
 */
export async function markConversationRead(
  deviceId: string,
  handle: string,
  opts: MarkReadOptions = {},
): Promise<{ handle: string; readThrough: string }> {
  try {
    const { readThrough } = await markRead(getDb(), {
      deviceId,
      handle,
      readThrough: opts.readThrough ?? null,
      source: opts.source ?? 'manual',
    });
    return { handle, readThrough };
  } catch (err) {
    throw wrap(err, 'markConversationRead');
  }
}

/** Mark every replied-to thread read. Returns the handles affected. */
export async function markAllReplied(
  deviceId: string,
): Promise<{ marked: number; handles: readonly string[] }> {
  try {
    const handles = await markAllRepliedRead(getDb(), deviceId);
    return { marked: handles.length, handles };
  } catch (err) {
    throw wrap(err, 'markAllReplied');
  }
}

export async function conversationReadState(
  deviceId: string,
  handle: string,
): Promise<ConversationReadState> {
  try {
    return await getReadState(getDb(), deviceId, handle);
  } catch (err) {
    throw wrap(err, 'conversationReadState');
  }
}
