import { z } from "zod" import { WEBHOOK_EVENT_IDS } from "@/lib/webhooks/events" export const propertySchema = z.object({ name: z.string().min(1, "Property name is required").max(200), address_line1: z.string().min(1, "Address is required").max(300), address_line2: z.string().max(300).optional(), city: z.string().min(1, "City is required").max(120), state: z.string().max(120).optional(), postal_code: z.string().max(20).optional(), country: z.string().max(120).default("US"), property_type: z.enum(["residential", "commercial", "mixed"]).default("residential"), total_units: z.number().int().min(1).default(1), notes: z.string().max(5000).optional(), image_url: z.string().url().nullable().optional(), }) export const unitSchema = z.object({ property_id: z.string().uuid(), unit_number: z.string().min(1, "Unit number is required").max(50), bedrooms: z.number().int().min(0).default(1), bathrooms: z.number().min(0).default(1), sq_ft: z.number().int().positive().optional(), rent_amount: z.number().positive("Rent amount must be positive"), status: z.enum(["vacant", "occupied", "maintenance", "unavailable"]).default("vacant"), notes: z.string().max(5000).optional(), }) export const tenantSchema = z.object({ property_id: z.string().uuid(), unit_id: z.string().uuid().optional(), first_name: z.string().min(1, "First name is required").max(100), last_name: z.string().min(1, "Last name is required").max(100), email: z.string().email("Invalid email").max(254).optional().or(z.literal("")), phone: z.string().max(40).optional(), emergency_contact_name: z.string().max(200).optional(), emergency_contact_phone: z.string().max(40).optional(), move_in_date: z.string().optional(), notes: z.string().max(5000).optional(), }) export const rentPaymentSchema = z.object({ tenant_id: z.string().uuid(), property_id: z.string().uuid(), unit_id: z.string().uuid().optional(), amount: z.number().positive("Amount must be positive"), due_date: z.string().min(1, "Due date is required"), paid_date: z.string().optional(), status: z.enum(["pending", "paid", "overdue", "partial", "waived"]).default("pending"), payment_method: z.string().max(100).optional(), notes: z.string().max(5000).optional(), }) export const maintenanceSchema = z.object({ property_id: z.string().uuid(), unit_id: z.string().uuid().optional(), tenant_id: z.string().uuid().optional(), title: z.string().min(1, "Title is required").max(200), description: z.string().min(1, "Description is required").max(5000), category: z.enum(["plumbing", "electrical", "hvac", "appliance", "structural", "pest", "general"]).default("general"), priority: z.enum(["low", "medium", "high", "emergency"]).default("medium"), assigned_to: z.string().max(200).optional(), estimated_cost: z.number().positive().optional(), }) export const leaseSchema = z.object({ tenant_id: z.string().uuid(), property_id: z.string().uuid(), unit_id: z.string().uuid().optional(), lease_start: z.string().min(1, "Lease start date is required"), lease_end: z.string().min(1, "Lease end date is required"), rent_amount: z.number().positive("Rent amount must be positive"), security_deposit: z.number().positive().optional(), lease_type: z.enum(["fixed", "month_to_month"]).default("fixed"), status: z.enum(["active", "expired", "terminated", "renewed"]).optional(), auto_renew: z.boolean().default(false), notes: z.string().max(5000).optional(), }) export const expenseSchema = z.object({ property_id: z.string().uuid(), unit_id: z.string().uuid().optional(), category: z.enum(["repairs", "utilities", "insurance", "mortgage", "taxes", "management", "supplies", "other"]), description: z.string().min(1, "Description is required").max(500), amount: z.number().positive("Amount must be positive"), expense_date: z.string().min(1, "Date is required"), vendor: z.string().max(200).optional(), is_recurring: z.boolean().default(false), recurrence: z.enum(["monthly", "quarterly", "yearly"]).optional(), notes: z.string().max(5000).optional(), }) export type PropertyFormValues = z.infer export type UnitFormValues = z.infer export type TenantFormValues = z.infer export type RentPaymentFormValues = z.infer export type MaintenanceFormValues = z.infer export type LeaseFormValues = z.infer export const vendorSchema = z.object({ name: z.string().min(1, "Vendor name is required").max(200), trade: z.string().max(120).optional(), phone: z.string().max(40).optional(), email: z.string().email("Invalid email").max(254).optional().or(z.literal("")), notes: z.string().max(5000).optional(), property_id: z.string().uuid().optional().or(z.literal("")), }) export const inspectionSchema = z.object({ property_id: z.string().uuid("Property is required"), unit_id: z.string().uuid().optional().or(z.literal("")), type: z.enum(["move_in", "move_out", "routine"]), date: z.string().min(1, "Date is required"), notes: z.string().max(5000).optional(), }) export const paymentLinkSchema = z.object({ payment_id: z.string().uuid("Valid payment ID is required"), }) export const followUpRuleSchema = z.object({ type: z.enum(["overdue_rent", "maintenance_stale", "lease_renewal", "vacant_unit"]), name: z.string().min(1, "Name is required").max(200), trigger_days: z.number().int().min(0).max(3650).default(3), message_template: z.string().max(5000).optional(), }) // Outbound webhooks. `events` is the set of subscribed event ids; an empty array // means "all events". SSRF/host validation happens server-side (see lib/webhooks/ssrf). export const webhookEndpointSchema = z.object({ url: z.string().url("Enter a valid URL").max(2000), description: z.string().max(200).optional().or(z.literal("")), events: z.array(z.enum(WEBHOOK_EVENT_IDS as [string, ...string[]])).default([]), }) export type ExpenseFormValues = z.infer export type VendorFormValues = z.infer export type InspectionFormValues = z.infer export type WebhookEndpointFormValues = z.infer