import { z } from 'zod';

export const createUserSchema = z
  .object({
    email: z.string().email(),
    name: z.string().min(1).max(200),
    /** Optional at creation: omit it to email the user a set-password link
     *  instead (see `sendSetupEmail`). Required when `sendSetupEmail` is
     *  explicitly false. */
    password: z.string().min(12).optional(),
    /** When true (the default when no password is supplied), the account is
     *  provisioned and the new user is emailed a link to set their own
     *  password. When false, `password` must be supplied inline. */
    sendSetupEmail: z.boolean().optional(),
    displayName: z.string().min(1).max(200),
    /** Optional sign-in username. Shape/uniqueness/reserved checks run in the
     *  service (mirrors the self-service /api/v1/me path). Omit for email-only. */
    username: z.string().optional(),
    firstName: z.string().min(1).max(200).nullable().optional(),
    lastName: z.string().min(1).max(200).nullable().optional(),
    phone: z.string().optional(),
    roleId: z.string().uuid(),
    residentialAccess: z.boolean().optional().default(false),
  })
  .refine((d) => d.sendSetupEmail !== false || (d.password?.length ?? 0) >= 12, {
    message: 'A password (min 12 characters) is required when not sending a setup email',
    path: ['password'],
  });

export type CreateUserInput = z.infer<typeof createUserSchema>;

export const updateUserSchema = z.object({
  displayName: z.string().min(1).max(200).optional(),
  firstName: z.string().min(1).max(200).nullable().optional(),
  lastName: z.string().min(1).max(200).nullable().optional(),
  fullName: z.string().min(1).max(400).optional(),
  /** Admin-initiated email change. When changed, the original address
   *  receives an automated heads-up email (see notifyEmailChange). */
  email: z.string().email().optional(),
  /** Set true alongside `email` to send the "your admin changed your
   *  sign-in email" notification to the prior address. UI sets this when
   *  the admin confirms the warning dialog. */
  notifyEmailChange: z.boolean().optional(),
  /** Optional signing-identity override — the address used to represent this
   *  user in signing contexts (EOI signer slot, signing notifications,
   *  "awaiting my signature" hub tab). NEVER a login credential. Empty string
   *  clears it; a non-empty value must be a valid email. The service lowercases
   *  the value and maps '' → null. */
  signingEmail: z.union([z.literal(''), z.string().email()]).optional(),
  phone: z.string().nullable().optional(),
  isActive: z.boolean().optional(),
  roleId: z.string().uuid().optional(),
  residentialAccess: z.boolean().optional(),
});

export type UpdateUserInput = z.infer<typeof updateUserSchema>;

export const resetPasswordSchema = z.object({
  newPassword: z.string().min(12),
});

export type ResetPasswordInput = z.infer<typeof resetPasswordSchema>;
