import { getContainer } from '../../lib/cosmos.js';
import { NotFoundError, ConflictError } from '../../lib/errors.js';
import type { ExtractionTaskDoc, CreateTask, UpdateTask } from './types.js';

const CONTAINER_ID = 'extraction_tasks';

function container() {
  return getContainer(CONTAINER_ID);
}

/**
 * List all extraction tasks for a given productId.
 */
export async function listTasks(productId: string): Promise<ExtractionTaskDoc[]> {
  const { resources } = await container()
    .items.query<ExtractionTaskDoc>(
      {
        query: 'SELECT * FROM c WHERE c.productId = @productId ORDER BY c.builtIn DESC, c.name ASC',
        parameters: [{ name: '@productId', value: productId }],
      },
      { partitionKey: productId }
    )
    .fetchAll();

  return resources;
}

/**
 * Get a single task by ID.
 */
export async function getTask(id: string, productId: string): Promise<ExtractionTaskDoc> {
  const { resource } = await container().item(id, productId).read<ExtractionTaskDoc>();
  if (!resource) {
    throw new NotFoundError(`Task '${id}' not found`);
  }
  return resource;
}

/**
 * Create a new custom task.
 */
export async function createTask(input: CreateTask, productId: string): Promise<ExtractionTaskDoc> {
  const now = new Date().toISOString();
  const doc: ExtractionTaskDoc = {
    ...input,
    productId,
    builtIn: false,
    createdAt: now,
    updatedAt: now,
  };

  try {
    const { resource } = await container().items.create(doc);
    return resource as ExtractionTaskDoc;
  } catch (err: unknown) {
    if (err && typeof err === 'object' && 'code' in err && err.code === 409) {
      throw new ConflictError(`Task '${input.id}' already exists`);
    }
    throw err;
  }
}

/**
 * Update an existing custom task.
 */
export async function updateTask(
  id: string,
  productId: string,
  updates: UpdateTask
): Promise<ExtractionTaskDoc> {
  const existing = await getTask(id, productId);

  const updated: ExtractionTaskDoc = {
    ...existing,
    ...updates,
    updatedAt: new Date().toISOString(),
  };

  const { resource } = await container().item(id, productId).replace(updated);
  return resource as ExtractionTaskDoc;
}

/**
 * Delete a custom task (built-in tasks cannot be deleted).
 */
export async function deleteTask(id: string, productId: string): Promise<void> {
  const existing = await getTask(id, productId);
  if (existing.builtIn) {
    throw new ConflictError(`Cannot delete built-in task '${id}'`);
  }
  await container().item(id, productId).delete();
}

/**
 * Upsert a task (used for seeding built-in tasks).
 */
export async function upsertTask(doc: ExtractionTaskDoc): Promise<ExtractionTaskDoc> {
  const { resource } = await container().items.upsert(doc);
  return resource as unknown as ExtractionTaskDoc;
}
