import { database, collections } from '@/database';
import { Q } from '@nozbe/watermelondb';
import { recordTombstonesInBatch } from '@/database/tombstones';
import { tagsFromString, tagsToString, parseTaskTags } from '@/types';

export async function createCategory(name: string, color: string): Promise<void> {
  await database.write(async () => {
    const existing = await collections.categories.query().fetch();
    const nextOrder = existing.reduce((max, c) => Math.max(max, c.order), -1) + 1;
    const now = new Date();
    await collections.categories.create((c) => {
      c.name = name;
      c.color = color;
      c.order = nextOrder;
      c.createdAt = now;
      c.updatedAt = now;
    });
  });
}

export async function updateCategory(categoryId: string, name: string, color: string): Promise<void> {
  await database.write(async () => {
    const category = await collections.categories.find(categoryId);
    await category.update((c) => {
      c.name = name;
      c.color = color;
      c.updatedAt = new Date();
    });
  });
}

export async function deleteCategory(categoryId: string): Promise<void> {
  await database.write(async () => {
    const others = (await collections.categories.query().fetch()).filter((c) => c.id !== categoryId);
    const fallback = others[0];

    const tasks = await collections.tasks.query(Q.where('category_id', categoryId)).fetch();
    for (const task of tasks) {
      await task.update((t) => {
        const tags = parseTaskTags(t.tags, t.categoryId).filter((id) => id !== categoryId);
        t.categoryId = fallback?.id ?? tags[0] ?? '';
        t.tags = tagsToString(tags);
        t.updatedAt = new Date();
      });
    }

    const tagReferencedTasks = await collections.tasks.query(Q.where('tags', Q.like(`%,${categoryId},%`))).fetch();
    for (const task of tagReferencedTasks) {
      const tags = parseTaskTags(task.tags, task.categoryId).filter((id) => id !== categoryId);
      await task.update((t) => {
        t.tags = tagsToString(tags);
        t.updatedAt = new Date();
      });
    }

    const category = await collections.categories.find(categoryId);
    await category.destroyPermanently();
    await recordTombstonesInBatch('categories', [categoryId]);
  });
}
