import * as z from "zod";

/**
 * Provider self-registration schema. One flat schema validates the whole
 * single-page form on submit. Bounds mirror the backend `RegisterProviderDto`
 * exactly. Messages are dictionary keys — resolved through `t()` by `FormField`.
 *
 * NOT in this schema (handled as component state, not react-hook-form fields):
 *  - OTP verification status — gated separately before the form can submit.
 *  - Logo + KYC documents — upload results (s3 keys), all optional.
 *
 * Station coordinates come from the map pin (numbers set via `setValue`); they
 * start `undefined` and the superRefine turns "no pin dropped" into a localized
 * `locationRequired` error rather than zod's default invalid_type message.
 */

/** Saudi number in E.164 as emitted by PhoneInput: +966 followed by 9 digits */
const SAUDI_MOBILE = /^\+966\d{9}$/;

export const registrationSchema = z
  .object({
    // ── Account ──
    firstName: z
      .string()
      .trim()
      .min(1, { message: "auth.validation.firstNameRequired" }),
    lastName: z
      .string()
      .trim()
      .min(1, { message: "auth.validation.lastNameRequired" }),
    email: z
      .string()
      .trim()
      .min(1, { message: "auth.validation.emailRequired" })
      .email({ message: "auth.validation.emailInvalid" }),
    phoneNumber: z
      .string()
      .min(1, { message: "auth.validation.phoneRequired" })
      .regex(SAUDI_MOBILE, { message: "auth.validation.phoneInvalid" }),
    password: z
      .string()
      .min(8, { message: "auth.validation.passwordMin8" })
      .max(72, { message: "auth.validation.passwordMax" }),
    confirmPassword: z
      .string()
      .min(1, { message: "auth.validation.confirmPasswordRequired" }),

    // ── Business ──
    businessName: z
      .string()
      .trim()
      .min(2, { message: "auth.validation.businessNameLength" })
      .max(100, { message: "auth.validation.businessNameLength" }),

    // ── Service station & coverage ──
    stationAddress: z
      .string()
      .trim()
      .min(1, { message: "auth.validation.addressRequired" })
      .max(255),
    stationCity: z
      .string()
      .trim()
      .min(1, { message: "auth.validation.cityRequired" })
      .max(100),
    stationState: z.string().trim().max(100).optional(),
    stationZipCode: z.string().trim().max(20).optional(),
    stationLatitude: z.number().min(-90).max(90).optional(),
    stationLongitude: z.number().min(-180).max(180).optional(),
    serviceRadiusKm: z
      .number()
      .min(1, { message: "auth.validation.radiusRange" })
      .max(200, { message: "auth.validation.radiusRange" })
      .optional(),
  })
  .superRefine((data, ctx) => {
    if (data.password !== data.confirmPassword) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["confirmPassword"],
        message: "auth.validation.passwordMismatch",
      });
    }
    if (
      data.stationLatitude === undefined ||
      data.stationLongitude === undefined
    ) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["stationLatitude"],
        message: "auth.validation.locationRequired",
      });
    }
    // A cleared radius (undefined) gets a localized message rather than zod's
    // default invalid_type text.
    if (data.serviceRadiusKm === undefined) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["serviceRadiusKm"],
        message: "auth.validation.radiusRange",
      });
    }
  });

export type RegistrationFormValues = z.infer<typeof registrationSchema>;
