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<typeof propertySchema>
export type UnitFormValues = z.infer<typeof unitSchema>
export type TenantFormValues = z.infer<typeof tenantSchema>
export type RentPaymentFormValues = z.infer<typeof rentPaymentSchema>
export type MaintenanceFormValues = z.infer<typeof maintenanceSchema>
export type LeaseFormValues = z.infer<typeof leaseSchema>
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<typeof expenseSchema>
export type VendorFormValues = z.infer<typeof vendorSchema>
export type InspectionFormValues = z.infer<typeof inspectionSchema>
export type WebhookEndpointFormValues = z.infer<typeof webhookEndpointSchema>
