import { canEditMasterCode } from "@/lib/roles";

const CODE_DIGITS = 5;

function padSequence(sequence: number) {
  return String(sequence).padStart(CODE_DIGITS, "0");
}

export function isValidPrefixedCode(code: string, prefix: string) {
  return new RegExp(`^${prefix}[0-9]{${CODE_DIGITS}}$`).test(code);
}

export function normalizePrefixedCode(code: string) {
  return code.trim().toUpperCase();
}

export async function generateMasterCode(params: {
  prefix: string;
  countExisting: () => Promise<number>;
  exists: (code: string) => Promise<boolean>;
}) {
  let sequence = (await params.countExisting()) + 1;

  while (true) {
    const nextCode = `${params.prefix}${padSequence(sequence)}`;
    if (!(await params.exists(nextCode))) {
      return nextCode;
    }
    sequence += 1;
  }
}

export async function resolveMasterCode(params: {
  role: string;
  prefix: string;
  requestedCode?: string | null;
  existingCode?: string | null;
  countExisting: () => Promise<number>;
  exists: (code: string) => Promise<boolean>;
}) {
  if (canEditMasterCode(params.role)) {
    const requestedCode = params.requestedCode?.trim();
    if (requestedCode) {
      const normalizedCode = normalizePrefixedCode(requestedCode);
      if (!isValidPrefixedCode(normalizedCode, params.prefix)) {
        return {
          ok: false as const,
          message: `Kode harus berformat ${params.prefix}00000`
        };
      }
      return {
        ok: true as const,
        code: normalizedCode
      };
    }
  }

  if (params.existingCode) {
    return {
      ok: true as const,
      code: params.existingCode
    };
  }

  return {
    ok: true as const,
    code: await generateMasterCode(params)
  };
}
