import { z } from "zod";
import {
  applicationRecordSchema,
  applicationStatuses,
  type ApplicationRecord,
} from "./application-record";
import {
  documentMetadataSchema,
  staffDocumentKinds,
} from "./application-schema";
import { hasVisibleText, multiLineText } from "./application-text";
export const staffStatusSchema = z
  .object({
    revision: z.number().int().nonnegative(),
    status: z.enum(applicationStatuses).exclude(["pending"]),
  })
  .strict();
export const STAFF_NOTE_LIMIT = 100,
  STAFF_NOTE_LENGTH = 1000;
export const staffNoteSchema = z
  .object({
    text: multiLineText(STAFF_NOTE_LENGTH).refine(
      hasVisibleText,
      "Write a note.",
    ),
  })
  .strict();
export const staffAssignmentSchema = z
  .object({
    revision: z.number().int().nonnegative(),
    assignee: z
      .email()
      .max(254)
      .transform((email) => email.toLowerCase())
      .nullable(),
  })
  .strict();
export const staffTeamSchema = z.object({
  me: z.string(),
  team: z.array(z.string()).max(50),
});
export type StaffTeam = z.infer<typeof staffTeamSchema>;
export const staffArchiveSchema = z
  .object({ revision: z.number().int().nonnegative(), archived: z.boolean() })
  .strict();
export const staffRetentionSchema = z
  .object({
    revision: z.number().int().nonnegative(),
    classificationReviewed: z.boolean(),
    hold: z.enum([
      "none",
      "investigation",
      "litigation",
      "regulatory",
      "business-review",
    ]),
    loanEndedAt: z.iso.datetime().nullable(),
    borrowerRelationshipEndedAt: z.iso.datetime().nullable(),
    basis: z.string().trim().min(1).max(500),
    nextReviewAt: z.iso.datetime().nullable(),
  })
  .strict()
  .superRefine((value, ctx) => {
    if (value.hold !== "none" && !value.nextReviewAt)
      ctx.addIssue({
        code: "custom",
        path: ["nextReviewAt"],
        message: "Set a review date for this hold.",
      });
  });
export const staffViewSchema = applicationRecordSchema
  .pick({
    id: true,
    reference: true,
    fields: true,
    particulars: true,
    loanContext: true,
    declaration: true,
    assessment: true,
    myinfo: true,
    createdAt: true,
    submittedAt: true,
    status: true,
    revision: true,
    retention: true,
    retentionReview: true,
    deleting: true,
    archivedAt: true,
    notes: true,
    assignee: true,
    source: true,
    history: true,
  })
  .extend({
    documents: z.array(
      documentMetadataSchema.extend({
        kind: z.enum(staffDocumentKinds),
        verified: z.boolean(),
        uploadedBy: z.string().optional(),
      }),
    ),
    notificationState: z.enum(["waiting", "pending", "sent", "review"]),
  })
  .strip();
export type StaffView = z.infer<typeof staffViewSchema>;
export function staffView(record: ApplicationRecord): StaffView {
  return staffViewSchema.parse({
    ...record,
    documents: record.documents.map(
      ({ kind, name, size, type, generation, uploadedBy }) => ({
        kind,
        name,
        size,
        type,
        verified: Boolean(generation),
        uploadedBy,
      }),
    ),
    notificationState: record.notification.state,
  });
}
