import { z } from "zod";

export const ballotVerificationMethodSchema = z.enum([
  "email",
  "sms_2fa",
  "email_sms",
]);

export const digitalSignatureTypeSchema = z.enum([
  "typed",
  "drawn",
  "checkbox_consent",
]);

export const requestVoterVerificationSchema = z.object({
  slug: z.string().trim().min(1).max(128),
  email: z.string().trim().email().max(255),
  phone: z.string().trim().max(50).optional().nullable(),
});

export const confirmVoterVerificationSchema = z.object({
  challengeToken: z.string().min(16).max(2048),
  code: z.string().trim().regex(/^\d{6}$/, "Enter the 6-digit code"),
});

/** @deprecated Prefer request + confirm OTP flow */
export const verifyVoterSchema = requestVoterVerificationSchema;

export const ballotSelectionSchema = z
  .object({
    electionPositionId: z.string().uuid(),
    candidateId: z.string().uuid().optional().nullable(),
    rank: z.number().int().min(1).max(100).optional().nullable(),
    writeInText: z.string().trim().max(255).optional().nullable(),
  })
  .refine(
    (value) => Boolean(value.candidateId) || Boolean(value.writeInText),
    "Each selection needs a candidate or a write-in"
  );

export const castBallotSchema = z
  .object({
    votingToken: z.string().min(16).max(512),
    selections: z.array(ballotSelectionSchema).min(1),
    consentAccepted: z.boolean().optional(),
    signerName: z.string().trim().max(255).optional().nullable(),
    signatureType: digitalSignatureTypeSchema.optional().nullable(),
    drawnSignaturePath: z.string().trim().max(50000).optional().nullable(),
  })
  .refine(
    (data) =>
      data.signatureType !== "typed" ||
      (data.signerName != null && data.signerName.trim().length > 0),
    {
      message: "Typed signatures require a signer name",
      path: ["signerName"],
    }
  )
  .refine(
    (data) =>
      data.signatureType !== "drawn" ||
      (data.drawnSignaturePath != null &&
        data.drawnSignaturePath.trim().length > 0),
    {
      message: "Drawn signatures require stroke data",
      path: ["drawnSignaturePath"],
    }
  );

export const withdrawConsentSchema = z.object({
  ballotCastEventId: z.string().uuid(),
});

export const generateVoterRollSchema = z.object({
  electionId: z.string().uuid(),
});

export type RequestVoterVerificationInput = z.infer<
  typeof requestVoterVerificationSchema
>;
export type ConfirmVoterVerificationInput = z.infer<
  typeof confirmVoterVerificationSchema
>;
export type CastBallotInput = z.infer<typeof castBallotSchema>;
export type BallotSelectionInput = z.infer<typeof ballotSelectionSchema>;
