import { query, mutation } from "./_generated/server";
import { v } from "convex/values";
import * as Users from "./model/users";
import * as Categories from "./model/categories";

export const list = query({
  args: {
    parentId: v.optional(v.id("categories")),
  },
  handler: async (ctx, args) => {
    let items;
    console.log("args in list", args);
    if (args.parentId !== undefined) {
      items = await ctx.db
        .query("categories")
        .withIndex("by_parent", (q) => q.eq("parentId", args.parentId!))
        .collect();
    } else {
      items = await ctx.db.query("categories").collect();
    }
    items.sort((a, b) => a.name.localeCompare(b.name));
    return items;
  },
});

export const getById = query({
  args: { id: v.id("categories") },
  handler: async (ctx, { id }) => {
    return await ctx.db.get(id);
  },
});

export const getBySlug = query({
  args: { slug: v.string() },
  handler: async (ctx, { slug }) => {
    return await ctx.db
      .query("categories")
      .withIndex("by_slug", (q) => q.eq("slug", slug))
      .unique();
  },
});

export const getByPath = query({
  args: {
    categorySlug: v.string(),
    subCategorySlug: v.string(),
  },
  handler: async (ctx, { categorySlug, subCategorySlug }) => {
    const parent = await ctx.db
      .query("categories")
      .withIndex("by_slug", (q) => q.eq("slug", categorySlug))
      .unique();
    if (!parent) return null;
    return await ctx.db
      .query("categories")
      .withIndex("by_parent_slug", (q) =>
        q.eq("parentId", parent._id).eq("slug", subCategorySlug),
      )
      .unique();
  },
});

export const listByTopCategory = query({
  args: { slug: v.string() },
  handler: async (ctx, { slug }) => {
    const items = await ctx.db
      .query("categories")
      .withIndex("by_top_category_slug", (q) =>
        q.eq("topCategorySlug", slug),
      )
      .collect();
    items.sort((a, b) => a.name.localeCompare(b.name));
    return items;
  },
});

export const create = mutation({
  args: {
    name: v.string(),
    slug: v.string(),
    description: v.optional(v.string()),
    parentId: v.optional(v.id("categories")),
    topCategorySlug: v.optional(v.string()),
    seoTitle: v.optional(v.string()),
    seoDescription: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    await Users.requireAdmin(ctx);
    const existing = await ctx.db
      .query("categories")
      .withIndex("by_slug", (q) => q.eq("slug", args.slug))
      .unique();
    if (existing) throw new Error("Category slug already exists");
    return await ctx.db.insert("categories", args);
  },
});

export const update = mutation({
  args: {
    id: v.id("categories"),
    name: v.optional(v.string()),
    slug: v.optional(v.string()),
    description: v.optional(v.string()),
    topCategorySlug: v.optional(v.string()),
    seoTitle: v.optional(v.string()),
    seoDescription: v.optional(v.string()),
  },
  handler: async (ctx, { id, ...updates }) => {
    await Users.requireAdmin(ctx);
    await Categories.getCategoryOrThrow(ctx, id);
    const fields: Record<string, unknown> = {};
    for (const [key, value] of Object.entries(updates)) {
      if (value !== undefined) fields[key] = value;
    }
    if (Object.keys(fields).length > 0) {
      await ctx.db.patch(id, fields);
    }
    return id;
  },
});
