"use server";

import { revalidatePath } from "next/cache";
import { api } from "../../../convex/_generated/api";
import { a, m } from "@/lib/convex-server";
import { run, ActionError, type ActionResult } from "@/lib/action";
import type { USER_STATUSES } from "@/lib/domain";

export interface WorkerInput {
  fullName: string;
  email: string;
  username?: string | null;
  phone?: string | null;
  emergencyContact?: string | null;
  roleId: string;
  hireDate?: string | null;
  password?: string;
  locale?: "en" | "fr" | "ar";
}
const nul = <T,>(x: T | "" | undefined | null) => (x === "" || x === undefined ? null : x);
const clean = (i: WorkerInput) => ({ fullName: i.fullName, email: i.email, username: nul(i.username), phone: nul(i.phone), emergencyContact: nul(i.emergencyContact), roleId: i.roleId, hireDate: nul(i.hireDate), locale: i.locale ?? "en" });
const rev = (id?: string) => {
  revalidatePath("/workers");
  revalidatePath("/security");
  if (id) revalidatePath(`/workers/${id}`);
};

export async function createWorker(input: WorkerInput): Promise<ActionResult<{ id: string }>> {
  return run(async () => {
    if (!input.password || input.password.length < 8) throw new ActionError("Password must be at least 8 characters.", "VALIDATION");
    const r = await a(api.workers.create, { ...clean(input), password: input.password });
    rev();
    return r;
  });
}

export async function updateWorker(id: string, input: WorkerInput): Promise<ActionResult<undefined>> {
  return run(async () => {
    await m(api.workers.update, { id, ...clean(input) });
    if (input.password) await a(api.workers.resetPassword, { id, password: input.password });
    rev(id);
    return undefined;
  });
}

export async function resetWorkerPassword(id: string, password: string): Promise<ActionResult<undefined>> {
  return run(async () => {
    await a(api.workers.resetPassword, { id, password });
    rev(id);
    return undefined;
  });
}

export async function setWorkerStatus(id: string, status: (typeof USER_STATUSES)[number], reason: string): Promise<ActionResult<undefined>> {
  return run(async () => {
    await m(api.workers.setStatus, { id, status, reason });
    rev(id);
    return undefined;
  });
}

export async function deleteWorker(id: string, reason: string): Promise<ActionResult<undefined>> {
  return run(async () => {
    await m(api.workers.remove, { id, reason });
    rev();
    return undefined;
  });
}

export async function setUserPermissionOverrides(userId: string, overrides: Record<string, boolean | null>, reason?: string): Promise<ActionResult<undefined>> {
  return run(async () => {
    await m(api.workers.setPermissionOverrides, { userId, overrides, reason });
    rev(userId);
    return undefined;
  });
}

export async function saveRole(input: { id?: string; key?: string; name: string; description?: string; permissions: string[] }): Promise<ActionResult<{ id: string }>> {
  return run(async () => {
    const r = await m(api.workers.saveRole, input);
    revalidatePath("/settings/roles");
    rev();
    return r;
  });
}

export async function revokeSession(sessionId: string): Promise<ActionResult<undefined>> {
  return run(async () => {
    await m(api.security.revokeSession, { sessionId });
    rev();
    revalidatePath("/profile");
    return undefined;
  });
}

export async function revokeAllSessions(userId: string, reason?: string): Promise<ActionResult<{ count: number }>> {
  return run(async () => {
    const r = await m(api.security.revokeAllSessions, { userId, reason });
    rev(userId);
    revalidatePath("/profile");
    return r;
  });
}

export async function changeOwnPassword(input: { current: string; next: string }): Promise<ActionResult<undefined>> {
  return run(async () => {
    await a(api.workers.changeOwnPassword, input);
    revalidatePath("/profile");
    return undefined;
  });
}

export async function updateOwnProfile(input: { fullName: string; phone?: string | null; locale: "en" | "fr" | "ar" }): Promise<ActionResult<undefined>> {
  return run(async () => {
    await m(api.workers.updateOwnProfile, { fullName: input.fullName, phone: nul(input.phone), locale: input.locale });
    revalidatePath("/profile");
    revalidatePath("/", "layout");
    return undefined;
  });
}
