/**
 * Tracker items repository — cloud-agnostic via @bytelyst/datastore.
 */

import type { FilterMap } from '@bytelyst/datastore';
import { getCollection } from '../../lib/datastore.js';
import type { TrackerItemDoc, ListItemsQuery } from './types.js';

function collection() {
  return getCollection<TrackerItemDoc>('tracker_items', '/id');
}

export async function list(
  query: ListItemsQuery
): Promise<{ items: TrackerItemDoc[]; total: number }> {
  const filter: FilterMap = {};

  if (query.productId) filter.productId = query.productId;
  if (query.type) filter.type = query.type;
  if (query.status) filter.status = query.status;
  if (query.priority) filter.priority = query.priority;
  if (query.assignee) filter.assignee = query.assignee;
  if (query.visibility) filter.visibility = query.visibility;

  // Fetch all matching docs — label and q filtering done in-memory
  const sortField = query.sortBy === 'priority' ? 'priorityOrder' : query.sortBy;
  const sortDir = query.sortOrder === 'desc' ? -1 : 1;

  let allDocs = await collection().findMany({
    filter,
    sort: { [sortField]: sortDir },
  });

  // In-memory label filter (ARRAY_CONTAINS)
  if (query.label) {
    const label = query.label;
    allDocs = allDocs.filter(d => d.labels?.includes(label));
  }

  // In-memory text search
  if (query.q) {
    const q = query.q.toLowerCase();
    allDocs = allDocs.filter(
      d => d.title?.toLowerCase().includes(q) || d.description?.toLowerCase().includes(q)
    );
  }

  const total = allDocs.length;
  const items = allDocs.slice(query.offset, query.offset + query.limit);

  return { items, total };
}

export async function getById(id: string): Promise<TrackerItemDoc | null> {
  try {
    return await collection().findById(id, id);
  } catch {
    return null;
  }
}

export async function create(doc: TrackerItemDoc): Promise<TrackerItemDoc> {
  return collection().create(doc);
}

export async function update(
  id: string,
  updates: Partial<TrackerItemDoc>
): Promise<TrackerItemDoc | null> {
  try {
    return await collection().update(id, id, { ...updates, updatedAt: new Date().toISOString() });
  } catch {
    return null;
  }
}

export async function remove(id: string): Promise<boolean> {
  try {
    await collection().delete(id, id);
    return true;
  } catch {
    return false;
  }
}

export async function incrementCommentCount(id: string, delta: number): Promise<void> {
  const item = await getById(id);
  if (item) {
    await update(id, { commentCount: Math.max(0, item.commentCount + delta) });
  }
}

export async function updateVoteCount(id: string, voteCount: number): Promise<void> {
  await update(id, { voteCount });
}
