import { z, ZodObject } from "zod";
import { CustomField } from "@/redux/api/customFieldApi";

export const buildZodSchema = (fields: CustomField[]): ZodObject<any> => {
  const shape: Record<string, any> = {};

  for (const field of fields) {
    // Build the base schema for the type first
    let baseSchema: z.ZodTypeAny;

    switch (field.type) {
      case "text":
      case "textarea":
      case "dropdown":
      case "radio":
        baseSchema = z.string();
        break;

      case "email":
        baseSchema = z.string().email(`${field.label} must be a valid email`);
        break;

      case "number":
        baseSchema = z.number({
          invalid_type_error: `${field.label} must be a number`,
        });
        break;

      case "phone":
        baseSchema = z
          .string()
          .regex(
            /^\+?\d{6,15}$/,
            `${field.label} must be a valid phone number`
          );
        break;

      case "checkbox":
        baseSchema = z.array(z.string());
        break;

      case "date":
        baseSchema = z.string();
        break;

      default:
        baseSchema = z.any();
    }

    // Apply "required" rules that rely on the underlying type BEFORE refine/effects
    let schema = baseSchema;

    if (
      field.type === "text" ||
      field.type === "textarea" ||
      field.type === "dropdown" ||
      field.type === "radio" ||
      field.type === "email" ||
      field.type === "phone" ||
      field.type === "date"
    ) {
      if (field.required) {
        schema = (schema as z.ZodArray<z.ZodString>).refine(
          (val) => val.length > 0,
          {
            message: `${field.label} is required`,
          }
        );
      }
    } else if (field.type === "checkbox") {
      if (field.required) {
        schema = (schema as z.ZodArray<z.ZodString>).refine(
          (val) => val.length > 0,
          {
            message: `${field.label} is required`,
          }
        );
      }
    }

    if (field.type === "date") {
      schema = (schema as z.ZodString).refine((v) => !isNaN(Date.parse(v)), {
        message: `${field.label} must be a valid date`,
      });
    }

    if (!field.required) {
      schema = schema.optional();
    }

    shape[field.key] = schema;
  }

  return z.object({ customFields: z.object(shape) });
};
