"use server";

/**
 * تیم و دسترسی‌ها (فقط مدیر عامل): افزودن عضو، تعیین بخش‌های قابل دسترسی، تعریف/بازنشانی رمز و حذف دسترسی.
 * و تغییر رمز خودِ هر عضو.
 */
import { revalidatePath } from "next/cache";
import { z } from "zod";
import { db } from "@/lib/db";
import { SECTION_KEYS } from "@/lib/admin-sections";
import { mobileSchema } from "@/validation/common";
import { hashPassword, isStrongPassword, PASSWORD_RULE, verifyPassword } from "@/server/auth/password";
import { requireStaff } from "./guard";

type Result = { ok: true } | { ok: false; error: string };

const memberSchema = z.object({
  id: z.string().max(40).optional(),
  phone: mobileSchema,
  name: z.string().trim().min(2, "نام را وارد کنید").max(60).refine((s) => !/[<>]/.test(s), "کاراکتر غیرمجاز"),
  role: z.enum(["ADMIN", "STAFF"]),
  permissions: z.array(z.enum(SECTION_KEYS as [string, ...string[]])).max(20),
  password: z.string().max(128).optional(),
});

export type MemberInput = z.input<typeof memberSchema>;

export async function saveMemberAction(input: MemberInput): Promise<Result> {
  const me = await requireStaff("team");
  const parsed = memberSchema.safeParse(input);
  if (!parsed.success) return { ok: false, error: parsed.error.issues[0].message };
  const { id, phone, name, role, permissions, password } = parsed.data;
  if (password && !isStrongPassword(password)) return { ok: false, error: PASSWORD_RULE };

  const existing = id ? await db.user.findUnique({ where: { id } }) : await db.user.findUnique({ where: { phone } });
  if (existing?.role === "OWNER") return { ok: false, error: "دسترسی مدیر عامل از این‌جا قابل تغییر نیست" };
  if (existing?.id === me.id) return { ok: false, error: "دسترسی خودتان را نمی‌توانید تغییر دهید" };
  if (id && existing && existing.phone !== phone) {
    const clash = await db.user.findUnique({ where: { phone } });
    if (clash) return { ok: false, error: "این شماره متعلق به کاربر دیگری است" };
  }
  const isNewStaff = !existing || existing.role === "CUSTOMER";
  if (isNewStaff && !password) return { ok: false, error: "برای عضو جدید رمز اولیه تعریف کنید" };

  const data = {
    phone,
    name,
    role,
    permissions,
    ...(password ? { passwordHash: await hashPassword(password), failedLogins: 0, lockedUntil: null } : {}),
  };
  const user = existing ? await db.user.update({ where: { id: existing.id }, data }) : await db.user.create({ data });
  // با تعریف رمز جدید، نشست‌های قبلی پنل این عضو بسته می‌شوند
  if (password && existing) await db.session.deleteMany({ where: { userId: user.id, adminAuth: true } });
  revalidatePath("/admin/team");
  return { ok: true };
}

/** حذف دسترسی پنل: عضو به مشتری عادی تبدیل می‌شود (سفارش‌ها و اطلاعاتش می‌ماند) */
export async function removeMemberAction(id: string): Promise<Result> {
  const me = await requireStaff("team");
  const user = await db.user.findUnique({ where: { id: z.string().max(40).parse(id) } });
  if (!user) return { ok: false, error: "کاربر پیدا نشد" };
  if (user.role === "OWNER" || user.id === me.id) return { ok: false, error: "این حساب قابل حذف نیست" };
  await db.user.update({ where: { id }, data: { role: "CUSTOMER", permissions: [], passwordHash: null, failedLogins: 0, lockedUntil: null } });
  await db.session.deleteMany({ where: { userId: id, adminAuth: true } });
  revalidatePath("/admin/team");
  return { ok: true };
}

/** هر عضو تیم رمز خودش را عوض می‌کند (با رمز فعلی) */
export async function changeOwnPasswordAction(input: { current: string; next: string }): Promise<Result> {
  const me = await requireStaff();
  const user = await db.user.findUnique({ where: { id: me.id } });
  if (!user || !(await verifyPassword(String(input.current ?? "").slice(0, 128), user.passwordHash))) return { ok: false, error: "رمز فعلی اشتباه است" };
  if (!isStrongPassword(input.next ?? "")) return { ok: false, error: PASSWORD_RULE };
  await db.user.update({ where: { id: me.id }, data: { passwordHash: await hashPassword(input.next) } });
  return { ok: true };
}
