import { z } from 'zod';

import { baseListQuerySchema } from '@/lib/api/list-query';
import {
  optionalCountryIsoSchema,
  optionalIanaTimezoneSchema,
  optionalPhoneE164Schema,
  optionalSubdivisionIsoSchema,
} from '@/lib/validators/i18n';

// ─── Residential client ──────────────────────────────────────────────────────

export const createResidentialClientSchema = z.object({
  fullName: z.string().min(1).max(200),
  email: z
    .string()
    .email()
    .optional()
    .or(z.literal('').transform(() => undefined)),
  phone: z.string().optional(),
  /** E.164-normalized phone alongside the legacy free-text `phone`. */
  phoneE164: optionalPhoneE164Schema.optional(),
  /** ISO-3166-1 alpha-2 the phone was parsed against. */
  phoneCountry: optionalCountryIsoSchema.optional(),
  /** ISO-3166-1 alpha-2 nationality. */
  nationalityIso: optionalCountryIsoSchema.optional(),
  /** IANA timezone. */
  timezone: optionalIanaTimezoneSchema.optional(),
  placeOfResidence: z.string().optional(),
  /** ISO-3166-1 alpha-2 country of residence. */
  placeOfResidenceCountryIso: optionalCountryIsoSchema.optional(),
  /** ISO 3166-2 subdivision code for place of residence. */
  subdivisionIso: optionalSubdivisionIsoSchema.optional(),
  preferredContactMethod: z.enum(['email', 'phone']).optional(),
  status: z.enum(['prospect', 'active', 'inactive']).optional().default('prospect'),
  source: z.enum(['website', 'manual', 'referral', 'broker', 'other']).optional(),
  notes: z.string().optional(),
});

export const updateResidentialClientSchema = createResidentialClientSchema.partial();

export const listResidentialClientsSchema = baseListQuerySchema.extend({
  status: z.enum(['prospect', 'active', 'inactive']).optional(),
  source: z.enum(['website', 'manual', 'referral', 'broker', 'other']).optional(),
});

// ─── Residential interest ────────────────────────────────────────────────────

/**
 * Default pipeline stages - used as the fallback when a port hasn't
 * configured its own list via the residential admin page. Mirror the
 * legacy hard-coded set so existing data continues to validate.
 *
 * Per-port stages are stored in `system_settings.residential_pipeline_stages`
 * (JSON array of stage ids). The validators below accept any string and
 * defer the membership check to a runtime helper that reads the live
 * stage list. This lets admins add/rename stages without a deploy.
 */
export const DEFAULT_RESIDENTIAL_PIPELINE_STAGES = [
  'new',
  'contacted',
  'viewing_scheduled',
  'offer_made',
  'offer_accepted',
  'closed_won',
  'closed_lost',
] as const;

/** Backwards-compat alias kept for any existing imports. */
export const PIPELINE_STAGES = DEFAULT_RESIDENTIAL_PIPELINE_STAGES;

/**
 * Residence unit types offered at Port Nimara. Single source of truth for the
 * residential interest's `residenceType` field + the residential UI select.
 * Mirrors (intentionally duplicated, separate repo) the website register form's
 * multi-select options.
 */
export const RESIDENCE_TYPES = [
  'Two Bedroom Marina Villa',
  'Four Bedroom Oceanfront Villa',
  'Five Bedroom Oceanfront Villa',
] as const;

export const createResidentialInterestSchema = z.object({
  residentialClientId: z.string().min(1),
  pipelineStage: z.string().optional().default('new'),
  source: z.enum(['website', 'manual', 'referral', 'broker', 'other']).optional(),
  notes: z.string().optional(),
  preferences: z.string().optional(),
  // Accept the known unit types or null/'' (cleared via the inline select).
  residenceType: z
    .preprocess((v) => (v === '' ? null : v), z.enum(RESIDENCE_TYPES).nullable())
    .optional(),
  assignedTo: z.string().optional(),
});

export const updateResidentialInterestSchema = createResidentialInterestSchema
  .omit({ residentialClientId: true })
  .partial();

export const listResidentialInterestsSchema = baseListQuerySchema.extend({
  // pipelineStage accepts a string OR string[] so the FilterBar can filter
  // multi-select. The legacy single-string form stays accepted so existing
  // callers (e.g. residential-client-tabs) don't need to migrate.
  pipelineStage: z.union([z.string(), z.array(z.string())]).optional(),
  // Source filter - mirrors the main interest list. Comma-separated when
  // submitted as a query string ("website,referral").
  source: z.union([z.string(), z.array(z.string())]).optional(),
  assignedTo: z.string().optional(),
  residentialClientId: z.string().optional(),
});

// ─── Public website inquiry ──────────────────────────────────────────────────

/**
 * Shape posted by the public website's residential interest form. Coerces
 * to internal create-shapes inside the public route.
 *
 * The legacy `phone` field stays free-text - older website builds may post
 * raw international strings ('+44 7700 900123'). The route handler parses
 * it server-side into `phoneE164` + `phoneCountry`. Newer website builds
 * can post normalized values directly.
 */
export const publicResidentialInquirySchema = z.object({
  firstName: z.string().min(1),
  lastName: z.string().min(1),
  email: z.string().email(),
  phone: z.string().min(1),
  /** Pre-normalized E.164 form, optional for backwards compat. */
  phoneE164: optionalPhoneE164Schema.optional(),
  /** ISO-3166-1 alpha-2 the phone was parsed against. */
  phoneCountry: optionalCountryIsoSchema.optional(),
  /** ISO-3166-1 alpha-2 nationality. */
  nationalityIso: optionalCountryIsoSchema.optional(),
  /** IANA timezone. */
  timezone: optionalIanaTimezoneSchema.optional(),
  placeOfResidence: z.string().optional(),
  /** ISO-3166-1 alpha-2 country of residence. */
  placeOfResidenceCountryIso: optionalCountryIsoSchema.optional(),
  /** ISO 3166-2 subdivision code for place of residence. */
  subdivisionIso: optionalSubdivisionIsoSchema.optional(),
  preferredContactMethod: z.enum(['email', 'phone']).optional(),
  notes: z.string().optional(),
  preferences: z.string().optional(),
});

// ─── Types ────────────────────────────────────────────────────────────────────

export type CreateResidentialClientInput = z.infer<typeof createResidentialClientSchema>;
export type UpdateResidentialClientInput = z.infer<typeof updateResidentialClientSchema>;
export type ListResidentialClientsInput = z.infer<typeof listResidentialClientsSchema>;

export type CreateResidentialInterestInput = z.infer<typeof createResidentialInterestSchema>;
export type UpdateResidentialInterestInput = z.infer<typeof updateResidentialInterestSchema>;
export type ListResidentialInterestsInput = z.infer<typeof listResidentialInterestsSchema>;

export type PublicResidentialInquiryInput = z.infer<typeof publicResidentialInquirySchema>;
