import { Prisma, VacationType } from "@capakraken/db";
import { AllocationStatus, PermissionKey, SystemRole, toIsoDateOrNull } from "@capakraken/shared";
import type { WeekdayAvailability } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { ZodError } from "zod";
export { fmtEur } from "../../lib/format-utils.js";
import type { TRPCContext } from "../../trpc.js";
import type { ToolContext } from "./shared.js";
import { createProjectCaller, createResourceCaller } from "./callers.js";

// ─── Helpers ────────────────────────────────────────────────────────────────

export const fmtDate = toIsoDateOrNull;

export class AssistantVisibleError extends Error {
  constructor(message: string) {
    super(message);
    this.name = "AssistantVisibleError";
  }
}

// Signatures of raw Prisma / database errors that must never reach the LLM.
// We'd rather surface a generic "Invalid input" than leak column names, FK
// relation paths, or the offending value from a unique-constraint failure
// (which can include user PII on a second write attempt).
const PRISMA_LEAK_SIGNATURES = [
  /Invalid\s+`prisma\./i,
  /Unique constraint failed on the fields?:/i,
  /Foreign key constraint failed on the field/i,
  /An operation failed because it depends on one or more records/i,
  /The column\s+`[^`]+`\s+does not exist/i,
  /relation\s+"[^"]+"\s+does not exist/i,
  /duplicate key value violates unique constraint/i,
  /null value in column\s+"/i,
  /violates (?:check|not-null|foreign key) constraint/i,
];

const SAFE_ERROR_FALLBACK = "Invalid input";
const MAX_ASSISTANT_ERROR_LENGTH = 500;

/**
 * Sanitises a TRPCError / downstream error message before it's handed back
 * to the LLM. Hand-written BAD_REQUEST / CONFLICT messages in routers are
 * user-safe, but a subset of error paths pass raw Prisma text straight
 * through — that would leak schema details (column names, relation paths,
 * offending values) into chat context and, transitively, into audit JSONB.
 *
 * Strategy: regex-detect Prisma-flavoured signatures and replace with a
 * generic fallback. Also hard-cap length as a belt-and-suspenders defence
 * against stack-trace-like payloads.
 */
export function sanitizeAssistantErrorMessage(message: string): string {
  if (!message) return SAFE_ERROR_FALLBACK;
  if (message.length > MAX_ASSISTANT_ERROR_LENGTH) return SAFE_ERROR_FALLBACK;
  if (PRISMA_LEAK_SIGNATURES.some((re) => re.test(message))) return SAFE_ERROR_FALLBACK;
  return message;
}

export function assertPermission(ctx: ToolContext, perm: PermissionKey): void {
  if (!ctx.permissions.has(perm)) {
    throw new AssistantVisibleError(
      `Permission denied: you need the "${perm}" permission to perform this action.`,
    );
  }
}

export function assertAdminRole(ctx: ToolContext): void {
  if (ctx.userRole !== SystemRole.ADMIN) {
    throw new AssistantVisibleError("Admin role required to perform this action.");
  }
}

export function formatHolidayCalendarEntry(entry: {
  id: string;
  date: Date;
  name: string;
  isRecurringAnnual?: boolean | null;
  source?: string | null;
}) {
  return {
    id: entry.id,
    date: toIsoDateOrNull(entry.date),
    name: entry.name,
    isRecurringAnnual: entry.isRecurringAnnual ?? false,
    source: entry.source ?? null,
  };
}

export function formatHolidayCalendar(calendar: {
  id: string;
  name: string;
  scopeType: string;
  stateCode?: string | null;
  isActive?: boolean | null;
  priority?: number | null;
  country?: { id: string; code: string; name: string } | null;
  metroCity?: { id: string; name: string } | null;
  _count?: { entries?: number | null } | null;
  entries?: Array<{
    id: string;
    date: Date;
    name: string;
    isRecurringAnnual?: boolean | null;
    source?: string | null;
  }> | null;
}) {
  const entries = calendar.entries?.map(formatHolidayCalendarEntry) ?? [];

  return {
    id: calendar.id,
    name: calendar.name,
    scopeType: calendar.scopeType,
    stateCode: calendar.stateCode ?? null,
    isActive: calendar.isActive ?? true,
    priority: calendar.priority ?? 0,
    country: calendar.country
      ? {
          id: calendar.country.id,
          code: calendar.country.code,
          name: calendar.country.name,
        }
      : null,
    metroCity: calendar.metroCity
      ? {
          id: calendar.metroCity.id,
          name: calendar.metroCity.name,
        }
      : null,
    entryCount: calendar._count?.entries ?? entries.length,
    entries,
  };
}

export function formatCountry(country: {
  id: string;
  code: string;
  name: string;
  dailyWorkingHours: number;
  scheduleRules?: Prisma.JsonValue | null;
  isActive?: boolean | null;
  metroCities?: Array<{ id: string; name: string }> | null;
  _count?: { resources?: number | null } | null;
}) {
  return {
    id: country.id,
    code: country.code,
    name: country.name,
    dailyWorkingHours: country.dailyWorkingHours,
    scheduleRules: country.scheduleRules ?? null,
    isActive: country.isActive ?? true,
    resourceCount: country._count?.resources ?? null,
    metroCities: (country.metroCities ?? []).map((city) => ({
      id: city.id,
      name: city.name,
    })),
    cities: (country.metroCities ?? []).map((city) => city.name),
  };
}

export function createUtcDate(year: number, monthIndex: number, day: number): Date {
  return new Date(Date.UTC(year, monthIndex, day));
}

export function resolveHolidayPeriod(input: {
  year?: number;
  periodStart?: string;
  periodEnd?: string;
}): {
  year: number | null;
  periodStart: Date;
  periodEnd: Date;
} {
  if (input.periodStart || input.periodEnd) {
    if (!input.periodStart || !input.periodEnd) {
      throw new AssistantVisibleError(
        "periodStart and periodEnd must both be provided when using a custom holiday range.",
      );
    }

    const periodStart = new Date(`${input.periodStart}T00:00:00.000Z`);
    const periodEnd = new Date(`${input.periodEnd}T00:00:00.000Z`);
    if (Number.isNaN(periodStart.getTime())) {
      throw new AssistantVisibleError(`Invalid periodStart: ${input.periodStart}`);
    }
    if (Number.isNaN(periodEnd.getTime())) {
      throw new AssistantVisibleError(`Invalid periodEnd: ${input.periodEnd}`);
    }
    if (periodEnd < periodStart) {
      throw new AssistantVisibleError("periodEnd must be on or after periodStart.");
    }

    return { year: null, periodStart, periodEnd };
  }

  const year = input.year ?? new Date().getUTCFullYear();
  return {
    year,
    periodStart: createUtcDate(year, 0, 1),
    periodEnd: createUtcDate(year, 11, 31),
  };
}

export const ASSISTANT_VACATION_REQUEST_TYPES = [
  VacationType.ANNUAL,
  VacationType.SICK,
  VacationType.OTHER,
] as const;

export function parseAssistantVacationRequestType(input: string): VacationType {
  const normalized = input.trim().toUpperCase();
  if (normalized === VacationType.PUBLIC_HOLIDAY) {
    throw new AssistantVisibleError(
      "PUBLIC_HOLIDAY requests cannot be created manually. Manage public holidays through holiday calendars instead.",
    );
  }

  if ((ASSISTANT_VACATION_REQUEST_TYPES as readonly string[]).includes(normalized)) {
    return normalized as VacationType;
  }

  throw new AssistantVisibleError(
    `Invalid vacation type: ${input}. Valid types: ${ASSISTANT_VACATION_REQUEST_TYPES.join(", ")}.`,
  );
}

export function parseIsoDate(value: string, fieldName: string): Date {
  const parsed = new Date(`${value}T00:00:00.000Z`);
  if (Number.isNaN(parsed.getTime())) {
    throw new AssistantVisibleError(`Invalid ${fieldName}: ${value}`);
  }
  return parsed;
}

export function parseOptionalIsoDate(
  value: string | undefined,
  fieldName: string,
): Date | undefined {
  return value ? parseIsoDate(value, fieldName) : undefined;
}

export function parseDateTime(value: string, fieldName: string): Date {
  const parsed = new Date(value);
  if (Number.isNaN(parsed.getTime())) {
    throw new AssistantVisibleError(`Invalid ${fieldName}: ${value}`);
  }
  return parsed;
}

export function parseOptionalDateTime(
  value: string | undefined,
  fieldName: string,
): Date | undefined {
  return value ? parseDateTime(value, fieldName) : undefined;
}

export function toDate(value: Date | string): Date {
  return value instanceof Date ? value : new Date(value);
}

export type AssistantToolErrorResult = { error: string };
export type AssistantIndexedFieldErrorResult = AssistantToolErrorResult & {
  field: string;
  index: number;
};
export type BatchQuickAssignmentInput = {
  resourceId: string;
  projectId: string;
  startDate: Date;
  endDate: Date;
  hoursPerDay?: number;
  role?: string;
  status?: AllocationStatus;
};

export function toAssistantNotFoundError(
  error: unknown,
  message: string,
): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    return { error: message };
  }
  return null;
}

export function toAssistantAllocationNotFoundError(
  error: unknown,
): AssistantToolErrorResult | null {
  if (error instanceof TRPCError) {
    if (error.code === "NOT_FOUND") {
      return { error: "Allocation not found with the given criteria." };
    }
    if (error.message === "Record not found" || error.message.includes("Assignment not found")) {
      return { error: "Allocation not found with the given criteria." };
    }
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (prismaError?.code === "P2025") {
    return { error: "Allocation not found with the given criteria." };
  }

  return null;
}

export function toAssistantProjectNotFoundError(
  error: unknown,
  identifier: string,
): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(error, `Project not found: ${identifier}`);
}

export function toAssistantTimelineMutationError(
  error: unknown,
  context: "updateInline" | "applyShift" | "quickAssign" | "batchShift",
): AssistantToolErrorResult | null {
  if (error instanceof TRPCError) {
    if (error.code === "NOT_FOUND") {
      if (error.message.includes("Resource not found")) {
        return { error: "Resource not found with the given criteria." };
      }
      if (error.message.includes("Project not found")) {
        return { error: "Project not found with the given criteria." };
      }
      if (error.message.includes("Demand requirement not found")) {
        return { error: "Demand requirement not found with the given criteria." };
      }
      if (error.message.includes("No allocations found")) {
        return { error: "Allocation not found with the given criteria." };
      }
    }

    if (error.code === "BAD_REQUEST" || error.code === "CONFLICT") {
      return { error: sanitizeAssistantErrorMessage(error.message) };
    }
  }

  const allocationNotFound = toAssistantAllocationNotFoundError(error);
  if (allocationNotFound && (context === "updateInline" || context === "batchShift")) {
    return allocationNotFound;
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  if (errorText.includes("resource")) {
    return { error: "Resource not found with the given criteria." };
  }
  if (errorText.includes("project")) {
    return { error: "Project not found with the given criteria." };
  }
  if (errorText.includes("demand")) {
    return { error: "Demand requirement not found with the given criteria." };
  }
  if (prismaError.code === "P2025" && (context === "updateInline" || context === "batchShift")) {
    return { error: "Allocation not found with the given criteria." };
  }

  return null;
}

export function toAssistantVacationNotFoundError(error: unknown): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(error, "Vacation not found with the given criteria.");
}

export function toAssistantVacationMutationError(
  error: unknown,
  action: "approve" | "reject" | "cancel",
): AssistantToolErrorResult | null {
  const notFound = toAssistantVacationNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    if (action === "approve") {
      return { error: "Vacation cannot be approved in its current status." };
    }
    if (action === "reject") {
      return { error: "Vacation cannot be rejected in its current status." };
    }
    return { error: "Vacation cannot be cancelled in its current status." };
  }

  return null;
}

export function toAssistantProjectCreationError(
  error: unknown,
  shortCode: string,
): AssistantToolErrorResult | null {
  if (error instanceof TRPCError) {
    if (error.code === "CONFLICT") {
      return { error: `A project with short code "${shortCode}" already exists.` };
    }

    if (error.code === "NOT_FOUND") {
      if (error.message.includes("Blueprint")) {
        return { error: "Blueprint not found with the given criteria." };
      }
      if (error.message.includes("Client")) {
        return { error: "Client not found with the given criteria." };
      }
    }

    if (error.code === "BAD_REQUEST" || error.code === "UNPROCESSABLE_CONTENT") {
      return { error: sanitizeAssistantErrorMessage(error.message) };
    }
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code !== "P2003" && prismaError.code !== "P2025") {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  if (errorText.includes("blueprint")) {
    return { error: "Blueprint not found with the given criteria." };
  }
  if (errorText.includes("client")) {
    return { error: "Client not found with the given criteria." };
  }

  return null;
}

export function toAssistantDemandNotFoundError(error: unknown): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(error, "Demand not found with the given criteria.");
}

export function toAssistantDemandFillError(error: unknown): AssistantToolErrorResult | null {
  const notFound = toAssistantDemandNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    return { error: "Demand cannot be filled in its current status." };
  }

  return null;
}

export function toAssistantEstimateNotFoundError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    if (error.message.includes("version")) {
      return { error: "Estimate version not found with the given criteria." };
    }
    return { error: "Estimate not found with the given criteria." };
  }

  return null;
}

export function toAssistantEstimateReadError(
  error: unknown,
  context: "weeklyPhasing" | "commercialTerms",
): AssistantToolErrorResult | null {
  const notFound = toAssistantEstimateNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  if (
    context === "weeklyPhasing" &&
    error instanceof TRPCError &&
    error.code === "PRECONDITION_FAILED" &&
    error.message === "Estimate has no versions"
  ) {
    return { error: "Estimate version not found with the given criteria." };
  }

  return null;
}

export function toAssistantHolidayCalendarNotFoundError(
  error: unknown,
  identifier?: string,
): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(
    error,
    identifier
      ? `Holiday calendar not found: ${identifier}`
      : "Holiday calendar not found with the given criteria.",
  );
}

export function toAssistantHolidayCalendarMutationError(
  error: unknown,
): AssistantToolErrorResult | null {
  const notFound = toAssistantHolidayCalendarNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    return { error: "Holiday calendar scope is invalid." };
  }

  if (error instanceof TRPCError && error.code === "CONFLICT") {
    return { error: "A holiday calendar for this scope already exists." };
  }

  return null;
}

export function toAssistantHolidayEntryNotFoundError(
  error: unknown,
): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(
    error,
    "Holiday calendar entry not found with the given criteria.",
  );
}

export function toAssistantHolidayEntryMutationError(
  error: unknown,
): AssistantToolErrorResult | null {
  const calendarNotFound = toAssistantHolidayCalendarNotFoundError(error);
  if (calendarNotFound) {
    return calendarNotFound;
  }

  const entryNotFound = toAssistantHolidayEntryNotFoundError(error);
  if (entryNotFound) {
    return entryNotFound;
  }

  if (error instanceof TRPCError && error.code === "CONFLICT") {
    return { error: "A holiday entry for this calendar and date already exists." };
  }

  return null;
}

export function toAssistantRoleNotFoundError(error: unknown): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(error, "Role not found with the given criteria.");
}

export function toAssistantRoleMutationError(
  error: unknown,
  action: "create" | "update" | "delete",
): AssistantToolErrorResult | null {
  const notFound = toAssistantRoleNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  if (error instanceof TRPCError && error.code === "CONFLICT") {
    return { error: "A role with this name already exists." };
  }

  if (action === "delete" && error instanceof TRPCError && error.code === "PRECONDITION_FAILED") {
    return { error: "Role cannot be deleted while it is still assigned. Deactivate it instead." };
  }

  return null;
}

export function toAssistantClientMutationError(
  error: unknown,
  action: "create" | "update" | "delete" = "update",
): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    if (error.message.includes("Parent client")) {
      return { error: "Parent client not found with the given criteria." };
    }
    return { error: "Client not found with the given criteria." };
  }

  if (error instanceof TRPCError && error.code === "CONFLICT") {
    return { error: "A client with this code already exists." };
  }

  if (action === "delete" && error instanceof TRPCError && error.code === "PRECONDITION_FAILED") {
    if (error.message.includes("project")) {
      return {
        error: "Client cannot be deleted while it still has projects. Deactivate it instead.",
      };
    }
    if (error.message.includes("child client")) {
      return {
        error:
          "Client cannot be deleted while it still has child clients. Remove or reassign them first.",
      };
    }
  }

  return null;
}

export function toAssistantOrgUnitNotFoundError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    if (error.message.includes("Parent org unit")) {
      return { error: "Parent org unit not found with the given criteria." };
    }
    return { error: "Org unit not found with the given criteria." };
  }

  return null;
}

export function toAssistantOrgUnitMutationError(error: unknown): AssistantToolErrorResult | null {
  const notFound = toAssistantOrgUnitNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    if (error.message.includes("must be greater than parent level")) {
      return { error: "Org unit level must be greater than the parent org unit level." };
    }
  }

  return null;
}

export function toAssistantCountryNotFoundError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    return { error: "Country not found with the given criteria." };
  }

  return null;
}

export function toAssistantCountryMutationError(error: unknown): AssistantToolErrorResult | null {
  const notFound = toAssistantCountryNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  if (error instanceof TRPCError && error.code === "CONFLICT") {
    return { error: "A country with this code already exists." };
  }

  return null;
}

export function toAssistantResourceCreationError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError) {
    if (error.code === "CONFLICT") {
      return { error: "A resource with this EID or email already exists." };
    }

    if (error.code === "BAD_REQUEST" || error.code === "UNPROCESSABLE_CONTENT") {
      return { error: sanitizeAssistantErrorMessage(error.message) };
    }

    if (error.code === "NOT_FOUND") {
      if (error.message.includes("Role")) {
        return { error: "Role not found with the given criteria." };
      }
      if (error.message.includes("Country")) {
        return { error: "Country not found with the given criteria." };
      }
      if (error.message.includes("Org unit")) {
        return { error: "Org unit not found with the given criteria." };
      }
    }
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code !== "P2003" && prismaError.code !== "P2025") {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  if (errorText.includes("role")) {
    return { error: "Role not found with the given criteria." };
  }
  if (errorText.includes("country")) {
    return { error: "Country not found with the given criteria." };
  }
  if (
    errorText.includes("orgunit") ||
    errorText.includes("org_unit") ||
    errorText.includes("org unit")
  ) {
    return { error: "Org unit not found with the given criteria." };
  }

  return { error: "The selected role, country, or org unit no longer exists." };
}

export function toAssistantResourceMutationError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    return { error: "Resource not found with the given criteria." };
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code === "P2025") {
    return { error: "Resource not found with the given criteria." };
  }

  if (prismaError.code !== "P2003") {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  if (errorText.includes("role")) {
    return { error: "Role not found with the given criteria." };
  }
  if (errorText.includes("country")) {
    return { error: "Country not found with the given criteria." };
  }
  if (
    errorText.includes("orgunit") ||
    errorText.includes("org_unit") ||
    errorText.includes("org unit")
  ) {
    return { error: "Org unit not found with the given criteria." };
  }

  return { error: "Resource not found with the given criteria." };
}

export function toAssistantProjectMutationError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    return { error: "Project not found with the given criteria." };
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code === "P2025") {
    return { error: "Project not found with the given criteria." };
  }

  if (prismaError.code !== "P2003") {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  if (errorText.includes("blueprint")) {
    return { error: "Blueprint not found with the given criteria." };
  }
  if (errorText.includes("client")) {
    return { error: "Client not found with the given criteria." };
  }

  return { error: "Project not found with the given criteria." };
}

export function toAssistantMetroCityMutationError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    if (error.message.includes("Country")) {
      return { error: "Country not found with the given criteria." };
    }
    return { error: "Metro city not found with the given criteria." };
  }

  if (error instanceof TRPCError && error.code === "PRECONDITION_FAILED") {
    return { error: "Metro city cannot be deleted while it is still assigned to resources." };
  }

  return null;
}

export function toAssistantDemandCreationError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    if (error.message.includes("Role")) {
      return { error: "Role not found with the given criteria." };
    }
    return { error: "Project not found with the given criteria." };
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code !== "P2003" && prismaError.code !== "P2025") {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  if (errorText.includes("role")) {
    return { error: "Role not found with the given criteria." };
  }
  if (errorText.includes("project")) {
    return { error: "Project not found with the given criteria." };
  }

  return null;
}

export function toAssistantVacationCreationError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError) {
    if (error.code === "FORBIDDEN") {
      return { error: "You can only create vacation requests for your own resource." };
    }

    if (error.code === "BAD_REQUEST") {
      return { error: sanitizeAssistantErrorMessage(error.message) };
    }
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code === "P2025") {
    return { error: "Resource not found with the given criteria." };
  }

  if (prismaError.code !== "P2003") {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  if (errorText.includes("resource")) {
    return { error: "Resource not found with the given criteria." };
  }

  return { error: "Resource not found with the given criteria." };
}

export function toAssistantEntitlementMutationError(
  error: unknown,
): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    return { error: "Resource not found with the given criteria." };
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code === "P2025") {
    return { error: "Resource not found with the given criteria." };
  }

  if (prismaError.code !== "P2003") {
    return null;
  }

  return { error: "Resource not found with the given criteria." };
}

export function toAssistantEstimateCreationError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    return { error: "Project not found with the given criteria." };
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code !== "P2003" && prismaError.code !== "P2025") {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  if (errorText.includes("project")) {
    return { error: "Project not found with the given criteria." };
  }
  if (errorText.includes("role")) {
    return { error: "Role not found with the given criteria." };
  }
  if (errorText.includes("resource")) {
    return { error: "Resource not found with the given criteria." };
  }
  if (
    errorText.includes("scopeitem") ||
    errorText.includes("scope_item") ||
    errorText.includes("scope item")
  ) {
    return { error: "Estimate scope item not found with the given criteria." };
  }

  return {
    error: "One of the referenced project, role, resource, or scope items no longer exists.",
  };
}

export function toAssistantEstimateMutationError(
  error: unknown,
  action:
    | "clone"
    | "updateDraft"
    | "submitVersion"
    | "approveVersion"
    | "createRevision"
    | "createExport"
    | "createPlanningHandoff"
    | "generateWeeklyPhasing"
    | "updateCommercialTerms",
): AssistantToolErrorResult | null {
  if (error instanceof TRPCError) {
    if (error.code === "NOT_FOUND") {
      if (error.message.includes("Linked project")) {
        return { error: "Project not found with the given criteria." };
      }
      if (action === "clone" && error.message === "Source estimate has no versions") {
        return { error: "Source estimate has no versions and cannot be cloned." };
      }
      if (error.message.includes("version") || error.message.includes("versions")) {
        return { error: "Estimate version not found with the given criteria." };
      }
      return { error: "Estimate not found with the given criteria." };
    }

    if (error.code === "PRECONDITION_FAILED") {
      switch (error.message) {
        case "Estimate has no working version":
          return { error: "Estimate has no working version." };
        case "Only working versions can be submitted":
          return { error: "Only working versions can be submitted." };
        case "Estimate has no submitted version":
          return { error: "Estimate has no submitted version." };
        case "Only submitted versions can be approved":
          return { error: "Only submitted versions can be approved." };
        case "Estimate already has a working version":
          return { error: "Estimate already has a working version." };
        case "Estimate has no locked version to revise":
          return { error: "Estimate has no locked version to revise." };
        case "Source version must be locked before creating a revision":
          return { error: "Source version must be locked before creating a revision." };
        case "Estimate has no approved version":
          return { error: "Estimate has no approved version." };
        case "Only approved versions can be handed off to planning":
          return { error: "Only approved versions can be handed off to planning." };
        case "Estimate must be linked to a project before planning handoff":
          return { error: "Estimate must be linked to a project before planning handoff." };
        case "Planning handoff already exists for this approved version":
          return { error: "Planning handoff already exists for this approved version." };
        case "Linked project has an invalid date range":
          return { error: "The linked project has an invalid date range for planning handoff." };
        case "Commercial terms can only be edited on working versions":
          return { error: "Commercial terms can only be edited on working versions." };
        default:
          if (error.message.startsWith("Project window has no working days for demand line")) {
            return {
              error: "The linked project window has no working days for at least one demand line.",
            };
          }
      }
    }

    if (error.code === "BAD_REQUEST" && action === "updateCommercialTerms") {
      return { error: "Commercial terms input is invalid." };
    }
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code === "P2003") {
    const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
    if (errorText.includes("project")) {
      return { error: "Project not found with the given criteria." };
    }
    if (errorText.includes("role")) {
      return { error: "Role not found with the given criteria." };
    }
    if (errorText.includes("resource")) {
      return { error: "Resource not found with the given criteria." };
    }
    if (
      errorText.includes("scopeitem") ||
      errorText.includes("scope_item") ||
      errorText.includes("scope item")
    ) {
      return { error: "Estimate scope item not found with the given criteria." };
    }
    return {
      error: "One of the referenced project, role, resource, or scope items no longer exists.",
    };
  }

  if (prismaError.code === "P2025") {
    const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
    if (
      errorText.includes("estimatedemandline") ||
      errorText.includes("estimate_demand_line") ||
      errorText.includes("estimate demand line")
    ) {
      return { error: "Estimate demand line not found with the given criteria." };
    }
    if (
      errorText.includes("estimateversion") ||
      errorText.includes("estimate_version") ||
      errorText.includes("estimate version")
    ) {
      return { error: "Estimate version not found with the given criteria." };
    }
    if (errorText.includes("estimate")) {
      return { error: "Estimate not found with the given criteria." };
    }
    switch (action) {
      case "generateWeeklyPhasing":
        return { error: "Estimate demand line not found with the given criteria." };
      case "updateCommercialTerms":
      case "submitVersion":
      case "approveVersion":
      case "createRevision":
      case "createExport":
        return { error: "Estimate version not found with the given criteria." };
      default:
        return { error: "Estimate not found with the given criteria." };
    }
  }

  return null;
}

export function toAssistantUserMutationError(
  error: unknown,
  action: "create" | "update" | "password" = "update",
): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "CONFLICT" && action === "create") {
    return { error: "User with this email already exists." };
  }

  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    return { error: "User not found with the given criteria." };
  }

  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    const validationIssues = getTrpcValidationIssues(error);
    for (const issue of validationIssues) {
      const field = issue.path[0];
      if (field === "password" && issue.code === "too_small") {
        return { error: "Password must be at least 12 characters." };
      }

      if (field === "name" && issue.code === "too_small") {
        return { error: "Name is required." };
      }

      if (field === "name" && issue.code === "too_big") {
        return { error: "Name must be at most 200 characters." };
      }
    }

    if (error.message.includes("Password must be at least 12 characters")) {
      return { error: "Password must be at least 12 characters." };
    }

    if (error.message.includes("Name is required")) {
      return { error: "Name is required." };
    }
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (prismaError?.code === "P2025") {
    return { error: "User not found with the given criteria." };
  }

  return null;
}

export function getTrpcValidationIssues(error: TRPCError): Array<{
  code?: string;
  path: string[];
}> {
  if (error.cause instanceof ZodError) {
    return error.cause.issues.map((issue) => ({
      code: issue.code,
      path: issue.path.map((segment) => String(segment)),
    }));
  }

  try {
    const parsed = JSON.parse(error.message);
    if (!Array.isArray(parsed)) {
      return [];
    }

    return parsed
      .filter(
        (issue): issue is { code?: unknown; path?: unknown } =>
          issue !== null && typeof issue === "object",
      )
      .map((issue) =>
        typeof issue.code === "string"
          ? {
              code: issue.code,
              path: Array.isArray(issue.path) ? issue.path.map((segment) => String(segment)) : [],
            }
          : {
              path: Array.isArray(issue.path) ? issue.path.map((segment) => String(segment)) : [],
            },
      );
  } catch {
    return [];
  }
}

export function toAssistantUserResourceLinkError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "CONFLICT") {
    if (error.message.includes("already linked")) {
      return { error: "Resource is already linked to another user." };
    }
    if (error.message.includes("changed during update")) {
      return { error: "Resource link changed during update. Please retry." };
    }
  }

  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    if (error.message.includes("Resource")) {
      return { error: "Resource not found with the given criteria." };
    }
    return { error: "User not found with the given criteria." };
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  const pointsToUser =
    errorText.includes("userid") || errorText.includes("user_id") || errorText.includes(" user ");
  const pointsToResource =
    errorText.includes("resourceid") ||
    errorText.includes("resource_id") ||
    errorText.includes(" resource ");

  if (prismaError.code === "P2025") {
    return { error: "Resource not found with the given criteria." };
  }

  if (prismaError.code === "P2003") {
    if (pointsToUser) {
      return { error: "User not found with the given criteria." };
    }
    if (pointsToResource || errorText.includes("resource")) {
      return { error: "Resource not found with the given criteria." };
    }
    return { error: "User not found with the given criteria." };
  }

  return null;
}

export function toAssistantTotpEnableError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    if (error.message.includes("No TOTP secret generated")) {
      return { error: "No TOTP secret generated. Call generate_totp_secret first." };
    }
    if (error.message.includes("already enabled")) {
      return { error: "TOTP is already enabled." };
    }
    if (error.message.includes("Invalid TOTP token")) {
      return { error: "Invalid TOTP token." };
    }
  }

  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    return { error: "User not found with the given criteria." };
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (prismaError?.code === "P2025") {
    return { error: "User not found with the given criteria." };
  }

  return null;
}

export function toAssistantWebhookNotFoundError(error: unknown): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(error, "Webhook not found with the given criteria.");
}

export function toAssistantWebhookMutationError(
  error: unknown,
  action: "create" | "update" = "update",
): AssistantToolErrorResult | null {
  const notFound = toAssistantWebhookNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    return {
      error: action === "create" ? "Webhook input is invalid." : "Webhook update input is invalid.",
    };
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (prismaError?.code === "P2025") {
    return { error: "Webhook not found with the given criteria." };
  }

  return null;
}

export function toAssistantAuditLogEntryNotFoundError(
  error: unknown,
): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(error, "Audit log entry not found with the given criteria.");
}

export function toAssistantTaskNotFoundError(error: unknown): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(error, "Task not found with the given criteria.");
}

export function toAssistantTaskActionError(error: unknown): AssistantToolErrorResult | null {
  const notFound = toAssistantTaskNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  if (error instanceof TRPCError && error.code === "PRECONDITION_FAILED") {
    if (error.message.includes("no executable action")) {
      return { error: "Task has no executable action." };
    }
    if (error.message.includes("already completed")) {
      return { error: "Task is already completed." };
    }
    if (error.message.includes("dismissed")) {
      return { error: "Task has been dismissed and cannot be executed." };
    }
  }

  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    if (
      error.message.includes("Invalid taskAction format") ||
      error.message.includes("Unknown action")
    ) {
      return { error: "Task action is invalid and cannot be executed." };
    }
    if (error.message === "Vacation not found") {
      return { error: "Vacation not found with the given criteria." };
    }
    if (error.message.startsWith("Vacation is ") && error.message.includes(", not PENDING")) {
      return {
        error: "Vacation is not pending and cannot be approved or rejected via this task action.",
      };
    }
    if (error.message === "Assignment not found") {
      return { error: "Assignment not found with the given criteria." };
    }
    if (error.message === "Assignment is already CONFIRMED") {
      return { error: "Assignment is already confirmed." };
    }
    return { error: sanitizeAssistantErrorMessage(error.message) };
  }

  if (error instanceof TRPCError && error.code === "FORBIDDEN") {
    return { error: "You do not have permission to execute this task action." };
  }

  return null;
}

export function toAssistantTaskAssignmentError(error: unknown): AssistantToolErrorResult | null {
  const notFound = toAssistantTaskNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (prismaError && (prismaError.code === "P2003" || prismaError.code === "P2025")) {
    const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
    if (errorText.includes("assignee")) {
      return { error: "Assignee user not found with the given criteria." };
    }
  }

  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    return { error: "Only tasks and approvals can be assigned." };
  }

  return null;
}

export function toAssistantBroadcastNotFoundError(error: unknown): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(error, "Broadcast not found with the given criteria.");
}

export function toAssistantDispoImportBatchNotFoundError(
  error: unknown,
): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(error, "Import batch not found with the given criteria.");
}

export function toAssistantReminderNotFoundError(error: unknown): AssistantToolErrorResult | null {
  return toAssistantNotFoundError(error, "Reminder not found with the given criteria.");
}

export function toAssistantNotificationNotFoundError(
  error: unknown,
): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    return { error: "Notification not found with the given criteria." };
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (prismaError?.code === "P2025") {
    return { error: "Notification not found with the given criteria." };
  }

  return null;
}

export function toAssistantNotificationReadError(error: unknown): AssistantToolErrorResult | null {
  return toAssistantNotificationNotFoundError(error);
}

export function toAssistantNotificationDeletionError(
  error: unknown,
): AssistantToolErrorResult | null {
  const notFound = toAssistantNotificationNotFoundError(error);
  if (notFound) {
    return notFound;
  }

  if (error instanceof TRPCError && error.code === "FORBIDDEN") {
    return { error: "Tasks created by other users cannot be deleted." };
  }

  return null;
}

export function toAssistantReminderCreationError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    return { error: "Reminder input is invalid." };
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code !== "P2003" && prismaError.code !== "P2025") {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  if (errorText.includes("user")) {
    return { error: "Authenticated user not found with the given criteria." };
  }

  return null;
}

export function toAssistantCommentResolveError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "NOT_FOUND") {
    return { error: "Comment not found with the given criteria." };
  }

  if (error instanceof TRPCError && error.code === "FORBIDDEN") {
    return { error: "Only the comment author or an admin can resolve comments." };
  }

  return null;
}

export function toAssistantCommentCreationError(error: unknown): AssistantToolErrorResult | null {
  if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
    if (error.message.includes("at least 1 character")) {
      return { error: "Comment body is required." };
    }

    if (error.message.includes("at most 10000")) {
      return { error: "Comment body must be at most 10000 characters." };
    }
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code !== "P2003" && prismaError.code !== "P2025") {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();
  if (errorText.includes("author") || errorText.includes("sender")) {
    return { error: "Comment author not found with the given criteria." };
  }

  if (errorText.includes("user") || errorText.includes("recipient")) {
    return { error: "Mentioned user not found with the given criteria." };
  }

  return null;
}

export function getPrismaRequestErrorMetadata(error: unknown): {
  code: string;
  message: string;
  metaText: string;
} | null {
  const collectMetaStrings = (value: unknown): string[] => {
    if (typeof value === "string") {
      return [value];
    }
    if (Array.isArray(value)) {
      return value.flatMap((entry) => collectMetaStrings(entry));
    }
    if (value && typeof value === "object") {
      return Object.values(value).flatMap((entry) => collectMetaStrings(entry));
    }
    return [];
  };

  const queue: unknown[] = [error];
  const visited = new Set<unknown>();

  while (queue.length > 0) {
    const current = queue.shift();
    if (current === undefined || current === null || visited.has(current)) {
      continue;
    }
    visited.add(current);

    if (current instanceof Prisma.PrismaClientKnownRequestError) {
      const metaText = Object.values(current.meta ?? {})
        .flatMap((value) => collectMetaStrings(value))
        .join(" ");
      return {
        code: current.code,
        message: current.message,
        metaText,
      };
    }

    if (typeof current !== "object") {
      continue;
    }

    const candidate = current as {
      code?: unknown;
      message?: unknown;
      meta?: Record<string, unknown>;
      cause?: unknown;
    };

    if (typeof candidate.code === "string" && /^P\d{4}$/.test(candidate.code)) {
      const metaText = Object.values(candidate.meta ?? {})
        .flatMap((value) => collectMetaStrings(value))
        .join(" ");

      return {
        code: candidate.code,
        message: typeof candidate.message === "string" ? candidate.message : "",
        metaText,
      };
    }

    if ("cause" in candidate) {
      queue.push(candidate.cause);
    }
  }

  return null;
}

export function getTrpcErrorMetadata(error: unknown): {
  code: string;
  message: string;
} | null {
  const queue: unknown[] = [error];
  const visited = new Set<unknown>();

  while (queue.length > 0) {
    const current = queue.shift();
    if (current === undefined || current === null || visited.has(current)) {
      continue;
    }
    visited.add(current);

    if (current instanceof TRPCError) {
      return {
        code: current.code,
        message: current.message,
      };
    }

    if (typeof current !== "object") {
      continue;
    }

    const candidate = current as {
      code?: unknown;
      message?: unknown;
      cause?: unknown;
      data?: { code?: unknown };
      shape?: { code?: unknown; message?: unknown; data?: { cause?: unknown } };
    };

    const candidateCode =
      typeof candidate.code === "string"
        ? candidate.code
        : typeof candidate.data?.code === "string"
          ? candidate.data.code
          : typeof candidate.shape?.code === "string"
            ? candidate.shape.code
            : null;
    const candidateMessage =
      typeof candidate.message === "string"
        ? candidate.message
        : typeof candidate.shape?.message === "string"
          ? candidate.shape.message
          : "";

    if (candidateCode && /^[A-Z_]+$/.test(candidateCode)) {
      return {
        code: candidateCode,
        message: candidateMessage,
      };
    }

    if ("cause" in candidate) {
      queue.push(candidate.cause);
    }
    if (candidate.shape?.data?.cause) {
      queue.push(candidate.shape.data.cause);
    }
  }

  return null;
}

export function toAssistantNotificationCreationError(
  error: unknown,
  context: "notification" | "task" | "broadcast",
): AssistantToolErrorResult | null {
  const trpcError = getTrpcErrorMetadata(error);

  if (
    context === "broadcast" &&
    trpcError?.code === "BAD_REQUEST" &&
    trpcError.message === "No recipients matched the broadcast target."
  ) {
    return { error: "No recipients matched the broadcast target." };
  }

  if (
    context === "broadcast" &&
    trpcError?.code === "BAD_REQUEST" &&
    trpcError.message === "Scheduled broadcasts with task metadata are not supported yet."
  ) {
    return { error: "Scheduled broadcasts with task metadata are not supported yet." };
  }

  if (trpcError?.code === "NOT_FOUND") {
    if (trpcError.message.includes("broadcast")) {
      return { error: "Broadcast not found with the given criteria." };
    }
    if (trpcError.message.includes("Sender user not found")) {
      return { error: "Sender user not found with the given criteria." };
    }
    if (trpcError.message.includes("Assignee user not found")) {
      return { error: "Assignee user not found with the given criteria." };
    }
    if (trpcError.message.includes("recipient")) {
      return context === "broadcast"
        ? { error: "Broadcast recipient user not found with the given criteria." }
        : context === "task"
          ? { error: "Task recipient user not found with the given criteria." }
          : { error: "Notification recipient user not found with the given criteria." };
    }
  }

  const prismaError = getPrismaRequestErrorMetadata(error);
  if (!prismaError) {
    return null;
  }

  if (prismaError.code !== "P2003" && prismaError.code !== "P2025") {
    return null;
  }

  const errorText = `${prismaError.message} ${prismaError.metaText}`.toLowerCase();

  if (errorText.includes("assignee")) {
    return { error: "Assignee user not found with the given criteria." };
  }

  if (errorText.includes("sender")) {
    return { error: "Sender user not found with the given criteria." };
  }

  if (
    context === "broadcast" &&
    (errorText.includes("notificationbroadcast") || errorText.includes("broadcast"))
  ) {
    return { error: "Broadcast not found with the given criteria." };
  }

  if (context === "broadcast" && prismaError.code === "P2025") {
    return { error: "Broadcast not found with the given criteria." };
  }

  if (context === "task") {
    return { error: "Task recipient user not found with the given criteria." };
  }

  if (context === "broadcast") {
    return { error: "Broadcast recipient user not found with the given criteria." };
  }

  return { error: "Notification recipient user not found with the given criteria." };
}

export function normalizeAssistantExecutionError(error: unknown): AssistantToolErrorResult {
  if (error instanceof AssistantVisibleError) {
    return { error: error.message };
  }

  const trpcError = getTrpcErrorMetadata(error);
  if (trpcError) {
    if (trpcError.code === "INTERNAL_SERVER_ERROR") {
      return {
        error: "The tool could not complete due to an internal error.",
      };
    }

    if (trpcError.code === "UNAUTHORIZED") {
      return {
        error: "Authentication is required to use this tool.",
      };
    }

    if (trpcError.code === "FORBIDDEN") {
      return {
        error: "You do not have permission to perform this action.",
      };
    }

    return { error: "The tool could not complete due to a request error." };
  }

  if (error instanceof Error) {
    return { error: "The tool could not complete due to an unexpected error." };
  }

  return { error: "The tool could not complete due to an unexpected error." };
}

export function isAssistantToolErrorResult(value: unknown): value is AssistantToolErrorResult {
  return value !== null && typeof value === "object" && "error" in value;
}

export function toAssistantIndexedFieldError(
  index: number,
  field: string,
  message: string,
): AssistantIndexedFieldErrorResult {
  return {
    error: `assignments[${index}].${field}: ${message}`,
    field: `assignments[${index}].${field}`,
    index,
  };
}

export async function resolveEntityOrAssistantError<T>(
  resolve: () => Promise<T>,
  notFoundMessage: string,
): Promise<T | AssistantToolErrorResult> {
  try {
    return await resolve();
  } catch (error) {
    const mapped = toAssistantNotFoundError(error, notFoundMessage);
    if (mapped) {
      return mapped;
    }
    if (error instanceof TRPCError && error.code === "INTERNAL_SERVER_ERROR") {
      return normalizeAssistantExecutionError(error);
    }
    throw error;
  }
}

export async function resolveProjectIdentifier(ctx: ToolContext, identifier: string) {
  const caller = createProjectCaller(createScopedCallerContext(ctx));
  return resolveEntityOrAssistantError(
    () => caller.resolveByIdentifier({ identifier }),
    `Project not found: ${identifier}`,
  );
}

export async function resolveResourceIdentifier(ctx: ToolContext, identifier: string) {
  const caller = createResourceCaller(createScopedCallerContext(ctx));
  return resolveEntityOrAssistantError(
    () => caller.resolveByIdentifier({ identifier }),
    `Resource not found: ${identifier}`,
  );
}

export function createScopedCallerContext(ctx: ToolContext): TRPCContext {
  if (!ctx.session?.user || !ctx.dbUser) {
    throw new AssistantVisibleError("Authenticated assistant context is required for this tool.");
  }

  // Propagate the read-only db client to the scoped tRPC caller so any
  // mutation reached through the caller is blocked at the proxy layer.
  // Previously we passed `ctx.db` verbatim — if the caller received
  // `ctx.isReadOnly=true` but we forwarded a raw client, reflection
  // through the caller would bypass the guarantee (C-3/C-4).
  return {
    session: ctx.session,
    db: ctx.db,
    dbUser: ctx.dbUser,
    roleDefaults: ctx.roleDefaults ?? null,
    clientIp: null,
  };
}

export function sanitizeWebhook<T extends { secret?: string | null }>(webhook: T) {
  const { secret: _secret, ...rest } = webhook;
  return {
    ...rest,
    hasSecret: Boolean(webhook.secret),
  };
}

export function sanitizeWebhookList<T extends { secret?: string | null }>(webhooks: T[]) {
  return webhooks.map((webhook) => sanitizeWebhook(webhook));
}

/** Resolve a responsible person name against existing resources. Returns the exact displayName or an error object. */
export async function resolveResponsiblePerson(
  name: string,
  ctx: ToolContext,
): Promise<{ displayName: string } | { error: string }> {
  const caller = createResourceCaller(createScopedCallerContext(ctx));
  const result = await caller.resolveResponsiblePersonName({ name });

  if (result.status === "resolved") {
    return { displayName: result.displayName };
  }

  if (result.status === "ambiguous" || result.status === "missing") {
    return { error: result.message };
  }

  return { error: `Unable to resolve responsible person: ${name}` };
}
