import { json, type ActionFunctionArgs } from "@remix-run/node";
import { z } from "zod";
import {
  SideMenuSectionIdSchema,
  type SideMenuSectionId,
} from "~/components/navigation/sideMenuTypes";
import {
  updateItemOrder,
  updateSideMenuPreferences,
} from "~/services/dashboardPreferences.server";
import { requireUser } from "~/services/session.server";

// Transforms form data string "true"/"false" to boolean, or undefined if not present
const booleanFromFormData = z
  .enum(["true", "false"])
  .transform((val) => val === "true")
  .optional();

const RequestSchema = z.object({
  isCollapsed: booleanFromFormData,
  sectionId: SideMenuSectionIdSchema.optional(),
  sectionCollapsed: booleanFromFormData,
  // Generic item order fields
  organizationId: z.string().optional(),
  listId: z.string().optional(),
  itemOrder: z.string().optional(), // JSON-encoded string[]
});

export async function action({ request }: ActionFunctionArgs) {
  const user = await requireUser(request);

  const formData = await request.formData();
  const rawData = Object.fromEntries(formData);

  const result = RequestSchema.safeParse(rawData);
  if (!result.success) {
    return json({ success: false, error: "Invalid request data" }, { status: 400 });
  }

  // Handle item order update
  if (result.data.organizationId && result.data.listId && result.data.itemOrder) {
    let parsed: unknown;
    try {
      parsed = JSON.parse(result.data.itemOrder);
    } catch {
      parsed = [];
    }
    const orderResult = z.array(z.string()).safeParse(parsed);
    if (orderResult.success) {
      await updateItemOrder({
        user,
        organizationId: result.data.organizationId,
        listId: result.data.listId,
        order: orderResult.data,
      });
    }
    return json({ success: true });
  }

  // Build sectionCollapsed parameter if both sectionId and sectionCollapsed are provided
  const sectionCollapsed =
    result.data.sectionId !== undefined && result.data.sectionCollapsed !== undefined
      ? {
          sectionId: result.data.sectionId as SideMenuSectionId,
          collapsed: result.data.sectionCollapsed,
        }
      : undefined;

  await updateSideMenuPreferences({
    user,
    isCollapsed: result.data.isCollapsed,
    sectionCollapsed,
  });

  return json({ success: true });
}
