import { z } from "zod";
import { CONSTANTS, PROPERTY_TYPE } from "@/constants/constants";
import { numberField } from "./common.schema";

const { RESIDENTIAL, COMMERCIAL, LAND, PLOTS } = PROPERTY_TYPE;
const { SELL, RENT, LEASE, PRE_LEASE } = CONSTANTS;

export const propertyFormSchema = z.object({
  listingType: z.string().nonempty("Listing Type is required").default("sell"),
  propertyType: z
    .string()
    .nonempty("Property Category is required")
    .default(""),
  subcategory: z.string().nonempty("Sub Category is required").default(""),
  title: z.string().min(3, "Title must be at least 3 characters").default(""),
  description: z.string().optional().default(""),
  state: z
    .string()
    .min(1, {
      message: "State is required",
    })
    .default(""),
  city: z.string().min(1, "City is required").default(""),
  locality: z.string().nonempty("Locality/Area is required").default(""),
  project: z.string().min(1, "Project Name is required").default(""),

  configuration: z.string().default(""),
  furnishingType: z.string().default(""),
  facing: z.string().optional().default(""),

  carpetArea: numberField({
    required: true,
    message: "Carpet Area is required",
  }),
  builtUpArea: numberField(),
  superBuiltUpArea: numberField(),
  unitOfMeasurement: z.string().optional().default(""),

  flatNumber: z.string().optional().default(""),
  projectUnit: z.string().optional().default(""),
  floorNumber: numberField({ int: true, defaultValue: 0 }),
  totalFloors: numberField({ int: true, defaultValue: 0 }),

  bathrooms: z.string().optional().default(""),
  balconies: z.string().optional().default(""),
  pantry: z.string().optional().default(""),
  parking: z.string().optional().default(""),
  ageOfProperty: z.string().optional().default(""),

  allDocuments: z.string().optional().default(""),
  widthDepth: z.string().optional().default(""),
  fencing: z.string().optional().default(""),
  length: numberField(),
  width: numberField(),

  waterSupply: z.string().optional().default(""),
  fireNOC: z.string().optional().default(""),
  loadingArea: z.preprocess(
    (v) => (typeof v === "string" ? Number(v) : v),
    z.number().optional().default(0)
  ),

  ownerName: z.string().nonempty("Owner Name is required").default(""),
  ownerContact: z
    .string()
    .nonempty("Owner Contact is required")
    .regex(/^\d+$/, "Owner Contact must be a number string")
    .length(10, "Owner Contact must be exactly 10 digits")
    .default(""),
  ownerEmail: z.string().email().optional(),

  price: numberField(),
  ownershipType: z.string().nonempty("Ownership Type is required").default(""),
  brokerageAvailable: z
    .string()
    .nonempty("Brokerage Available is required")
    .default("no"),
  brokerageAmount: numberField(),

  availability: z.string().nonempty("Availability is required").default(""),

  monthlyRent: numberField(),
  securityDeposit: numberField(),
  maintenanceCharges: numberField(),

  lockInPeriod: z.string().optional().default(""),
  leaseDuration: z.string().optional().default(""),
  agreementType: z.string().optional().default(""),

  amenities: z.array(z.string()).optional().default([]),
  propertyTags: z.array(z.string()).optional().default([]),
});

export const applyPropertyRefinements = <T extends z.ZodTypeAny>(schema: T) => {
  return schema.superRefine((data: any, ctx) => {
    /* ---------- Brokerage ---------- */
    if (
      data.brokerageAvailable === "yes" &&
      (data.brokerageAmount === undefined || data.brokerageAmount < 0)
    ) {
      ctx.addIssue({
        path: ["brokerageAmount"],
        message: "Brokerage Amount is required if brokerage is available",
        code: z.ZodIssueCode.custom,
      });
    }

    /* ---------- Area validations ---------- */
    // Skip area validations for "land / plot" property type
    if (data.propertyTypeName?.toLowerCase() !== "land / plot") {
      if (data.builtUpArea < data.carpetArea) {
        ctx.addIssue({
          path: ["builtUpArea"],
          message: "Built-up Area cannot be less than Carpet Area",
          code: z.ZodIssueCode.custom,
        });
      }

      if (data.superBuiltUpArea < data.builtUpArea) {
        ctx.addIssue({
          path: ["superBuiltUpArea"],
          message: "Super Built-up Area cannot be less than Built-up Area",
          code: z.ZodIssueCode.custom,
        });
      }
    }

    /* ---------- Property Type ---------- */
    const needsConfig =
      data.propertyTypeName === RESIDENTIAL ||
      data.propertyTypeName === COMMERCIAL;

    if (needsConfig && !data.configuration) {
      ctx.addIssue({
        path: ["configuration"],
        message:
          "Configuration is required for Residential and Commercial properties",
        code: z.ZodIssueCode.custom,
      });
    }

    if (needsConfig && !data.furnishingType) {
      ctx.addIssue({
        path: ["furnishingType"],
        message:
          "Furnishing Type is required for Residential and Commercial properties",
        code: z.ZodIssueCode.custom,
      });
    }

    /* ---------- Listing Type ---------- */
    if (data.listingType === SELL) {
      if (data.price === null || data.price === undefined) {
        ctx.addIssue({
          path: ["price"],
          message: "Price is required for Sell properties",
          code: z.ZodIssueCode.custom,
        });
      }
    } else {
      if (data.monthlyRent === null || data.monthlyRent === undefined) {
        ctx.addIssue({
          path: ["monthlyRent"],
          message: "Monthly Rent is required for Rent properties",
          code: z.ZodIssueCode.custom,
        });
      }

      if (data.securityDeposit === null || data.securityDeposit === undefined) {
        ctx.addIssue({
          path: ["securityDeposit"],
          message: "Security Deposit is required for Rent properties",
          code: z.ZodIssueCode.custom,
        });
      }

      if (!data.maintenanceCharges) {
        ctx.addIssue({
          path: ["maintenanceCharges"],
          message: "Maintenance Charges is required for Rent properties",
          code: z.ZodIssueCode.custom,
        });
      }

      if (data.listingType === LEASE || data.listingType === PRE_LEASE) {
        // Check for lockInPeriod (should be a number > 0)
        if (data.lockInPeriod === undefined || data.lockInPeriod === null || data.lockInPeriod === '' || (typeof data.lockInPeriod === 'number' && data.lockInPeriod <= 0)) {
          ctx.addIssue({
            path: ["lockInPeriod"],
            message: "Lock In Period is required for Lease properties",
            code: z.ZodIssueCode.custom,
          });
        }
        
        // Check for leaseDuration (should be a non-empty string)
        if (!data.leaseDuration || (typeof data.leaseDuration === 'string' && data.leaseDuration.trim() === '')) {
          ctx.addIssue({
            path: ["leaseDuration"],
            message: "Lease Duration is required for Lease properties",
            code: z.ZodIssueCode.custom,
          });
        }
        
        // Check for agreementType (should be a non-empty string)
        if (!data.agreementType || (typeof data.agreementType === 'string' && data.agreementType.trim() === '')) {
          ctx.addIssue({
            path: ["agreementType"],
            message: "Agreement Type is required for Lease properties",
            code: z.ZodIssueCode.custom,
          });
        }
      }
    }
  });
};
