import * as z from "zod";
import { SafeFileCtor } from "@/utils/safeFile";

const reraId = z.preprocess(
  (val) => {
    if (typeof val !== "string") return undefined;
    const trimmed = val.trim();
    return trimmed === "" ? undefined : trimmed;
  },
  z
    .string()
    // .regex(
    //   /^([A-Z]{2,})?\/?([A-Z]{2,})?\/?([A-Z0-9]+)\/?(\d{4})?$/,
    //   "Invalid RERA ID format"
    // )
    .optional()
);

export const addProjectSchema = z.object({
  projectName: z
    .string()
    .min(3, { message: "Project name must be at least 3 characters" }),
  team: z.string().optional(),
  propertyType: z
    .string({ required_error: "Please select a project type" })
    .min(1, { message: "Please select a project type " }),
  subCategory: z
    .string({ required_error: "Please select a sub category" })
    .min(1, { message: "Please select a sub category " }),
  status: z
    .string({ required_error: "Please select a project status" })
    .min(1, { message: "Please select a project status " }),
  locality: z.string().min(3, { message: "Area is required" }),
  landmark: z.string().optional(),
  state: z
    .string({ required_error: "Please select a state" })
    .min(1, { message: "Please select a state " }),
  city: z
    .string({ required_error: "Please select a city" })
    .min(1, { message: "Please select a city " }),
  pincode: z.preprocess((val) => {
    return typeof val === "number" && !isNaN(val) ? val : undefined;
  }, z.number({ required_error: "Pincode is required" }).int("Pincode must be an integer").gte(100000, "Pincode must be exactly 6 digits").lte(999999, "Pincode must be exactly 6 digits")),
  pricePerSqYard: z.preprocess((val) => {
    return typeof val === "number" && !isNaN(val) ? val : undefined;
  }, z.number({ required_error: "Price is required" }).int("Price must be an integer").min(1, "Price must be at least 1")),

  hasBlockLayout: z.boolean().optional().default(false),

  possessionDate: z.date().optional(),
  reraId: reraId,
  description: z.string().optional(),
});

export const addUnitSchema = z.object({
  block: z.string().min(1, { message: "Block is required" }),
  floor: z.preprocess((val) => {
    if (val === null || (typeof val === "string" && val.trim() === "")) {
      return undefined;
    }
    const n = Number(val as any);
    return isNaN(n) ? undefined : n;
  }, z.number({ required_error: "Floor is required", invalid_type_error: "Floor must be a number" }).positive({ message: "Floor must be a positive number" })),
  unitNumber: z
    .string({ required_error: "Please enter a unit number" })
    .min(1, { message: "Unit number must be at least 1 character" }),
  status: z
    .string({ required_error: "Please select a unit status" })
    .min(1, { message: "Please select a unit status" }),
  size: z.preprocess((val) => {
    if (val === null || (typeof val === "string" && val.trim() === "")) {
      return undefined;
    }
    const n = Number(val as any);
    return isNaN(n) ? undefined : n;
  }, z.number({ required_error: "Size is required", invalid_type_error: "Size must be a number" }).positive({ message: "Size must be a positive number" })),
  price: z.preprocess((val) => {
    if (val === null || (typeof val === "string" && val.trim() === "")) {
      return undefined;
    }
    const n = Number(val as any);
    return isNaN(n) ? undefined : n;
  }, z.number({ required_error: "Price is required", invalid_type_error: "Price must be a number" }).positive({ message: "Price must be a positive number" })),
});

export const uploadFileSchema = z.object({
  category: z.string({
    required_error: "Category is required",
  }),
  description: z.string().optional(),
  name: z.string({
    required_error: "Name is required",
  }),
  document: z
    .instanceof(SafeFileCtor as any, { message: "Please upload a file" })
    .refine(
      (file) =>
        !file ||
        (typeof File !== "undefined" &&
          (file as File).size <= 50 * 1024 * 1024),
      {
        message: "File size must be less than 50MB",
      }
    ),
});

export const paymentTermSchema = z.object({
  name: z.string().min(1, "Rule name is required"),

  stage: z.string().min(1, "Payment stage is required"),

  triggerType: z.enum(["percentage", "amount"], {
    required_error: "Trigger type is required",
  }),

  triggerValue: z.coerce
    .number({
      required_error: "Trigger value is required",
      invalid_type_error: "Trigger value must be a number",
    })
    .min(1, "Trigger value must be at least 1"),

  documentTemplate: z.string().min(1, "Document template is required"),

  paymentPlans: z
    .array(z.string())
    .nonempty("At least one payment plan must be selected"),

  status: z.boolean(),
  sendEmail: z.boolean(),
  sendSMS: z.boolean(),
});

const timelineSchema = z.object({
  formType: z.literal("timeline"),
  label: z
    .string({
      required_error: "Label is required",
    })
    .min(1, "Label is required"),
  startDate: z.date({
    required_error: "Start date is required",
  }),
  endDate: z.date({
    required_error: "End date is required",
  }),

  status: z
    .string({
      required_error: "Status is required",
    })
    .min(1, "Status is required"),
  progress: z.preprocess(
    (val) => {
      return typeof val === "number" && !isNaN(val) ? val : undefined;
    },
    z
      .number({
        required_error: "Progress is required",
      })
      .min(0, "Progress must be at least 0")
      .max(100, "Progress cannot exceed 100")
  ),
});

export const photoUploadSchema = z.object({
  formType: z.literal("photos"),
  photos: z.array(
    z.object({
      photoUrl: z.string(),
      caption: z.string().optional(),
      file: z.instanceof(SafeFileCtor as any).optional(),
    })
  ),
});

export const progressTimelineSchema = z.discriminatedUnion("formType", [
  timelineSchema,
  photoUploadSchema,
]);
