"use server";

import { z } from "zod";
import { revalidatePath } from "next/cache";
import { initDb } from "@/lib/db";
import { requireClientWorkspace } from "@/lib/auth/require-auth";
import { hashPassword, verifyPassword } from "@/lib/auth/credentials";
import type { ActionResult } from "@/lib/actions/auth";

const updateProfileSchema = z.object({
  name: z.string().min(2, "Name must be at least 2 characters").max(100),
});

const changePasswordSchema = z
  .object({
    currentPassword: z.string().min(1, "Current password is required"),
    newPassword: z
      .string()
      .min(8, "Password must be at least 8 characters")
      .max(128),
    confirmPassword: z.string(),
  })
  .refine((d) => d.newPassword === d.confirmPassword, {
    message: "Passwords do not match",
    path: ["confirmPassword"],
  });

/** Update the logged-in user's display name. */
export async function updateProfile(input: {
  name: string;
}): Promise<ActionResult> {
  const { userId } = await requireClientWorkspace();

  const parsed = updateProfileSchema.safeParse(input);
  if (!parsed.success) {
    return { success: false, error: parsed.error.issues[0]?.message ?? "Invalid input" };
  }

  const { User, AuditLog } = initDb();
  const user = await User.findByPk(userId);
  if (!user) return { success: false, error: "User not found" };

  await user.update({ name: parsed.data.name });

  await AuditLog.create({
    actorUserId: userId,
    workspaceId: user.workspaceId,
    action: "user.profile_updated",
    metadata: {},
  });

  revalidatePath("/app/settings/profile");
  revalidatePath("/app/dashboard");
  return { success: true };
}

/** Change the logged-in user's password after verifying the current one. */
export async function changePassword(input: {
  currentPassword: string;
  newPassword: string;
  confirmPassword: string;
}): Promise<ActionResult> {
  const { userId } = await requireClientWorkspace();

  const parsed = changePasswordSchema.safeParse(input);
  if (!parsed.success) {
    return { success: false, error: parsed.error.issues[0]?.message ?? "Invalid input" };
  }

  const { User } = initDb();
  const user = await User.findByPk(userId);
  if (!user) return { success: false, error: "User not found" };

  if (!user.passwordHash) {
    return { success: false, error: "Password login is not enabled for this account" };
  }

  const valid = await verifyPassword(parsed.data.currentPassword, user.passwordHash);
  if (!valid) {
    return { success: false, error: "Current password is incorrect" };
  }

  if (parsed.data.newPassword === parsed.data.currentPassword) {
    return { success: false, error: "New password must differ from current password" };
  }

  const newHash = await hashPassword(parsed.data.newPassword);
  await user.update({ passwordHash: newHash });

  return { success: true };
}
