import { db, eq, and, asc, isNotNull } from "@haushaltsApp/db";
import { shoppingItems } from "@haushaltsApp/db/schema";
import type { ShoppingItem } from "@haushaltsApp/shared/schemas/shopping.schema";

export async function getShoppingItems(householdId: string): Promise<ShoppingItem[]> {
  const rows = await db
    .select()
    .from(shoppingItems)
    .where(eq(shoppingItems.householdId, householdId))
    .orderBy(asc(shoppingItems.sortOrder), asc(shoppingItems.createdAt));

  return rows.map(mapRow);
}

export async function addShoppingItem(
  householdId: string,
  userId: string,
  label: string,
  quantity?: string,
): Promise<ShoppingItem> {
  const [row] = await db
    .insert(shoppingItems)
    .values({ householdId, label, quantity: quantity ?? null, addedBy: userId })
    .returning();
  return mapRow(row!);
}

export async function checkShoppingItem(
  id: string,
  householdId: string,
  userId: string,
): Promise<ShoppingItem | null> {
  const checkedAt = new Date().toISOString();
  const [row] = await db
    .update(shoppingItems)
    .set({ checkedBy: userId, checkedAt })
    .where(and(eq(shoppingItems.id, id), eq(shoppingItems.householdId, householdId)))
    .returning();
  return row ? mapRow(row) : null;
}

export async function uncheckShoppingItem(
  id: string,
  householdId: string,
): Promise<ShoppingItem | null> {
  const [row] = await db
    .update(shoppingItems)
    .set({ checkedBy: null, checkedAt: null })
    .where(and(eq(shoppingItems.id, id), eq(shoppingItems.householdId, householdId)))
    .returning();
  return row ? mapRow(row) : null;
}

export async function deleteShoppingItem(id: string, householdId: string): Promise<boolean> {
  const result = await db
    .delete(shoppingItems)
    .where(and(eq(shoppingItems.id, id), eq(shoppingItems.householdId, householdId)));
  return (result.rowCount ?? 0) > 0;
}

export async function clearCheckedItems(householdId: string): Promise<void> {
  await db
    .delete(shoppingItems)
    .where(and(eq(shoppingItems.householdId, householdId), isNotNull(shoppingItems.checkedBy)));
}

function mapRow(row: typeof shoppingItems.$inferSelect): ShoppingItem {
  return {
    id: row.id,
    householdId: row.householdId,
    label: row.label,
    quantity: row.quantity,
    addedBy: row.addedBy,
    checkedBy: row.checkedBy,
    checkedAt: row.checkedAt,
    sortOrder: row.sortOrder,
    createdAt: row.createdAt,
  };
}
