import { z } from 'zod';

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

// ─── Contact sub-schema ──────────────────────────────────────────────────────

export const contactSchema = z
  .object({
    channel: z.enum(['email', 'phone', 'whatsapp', 'other']),
    value: z.string().min(1),
    /** E.164-normalized number; required when channel is phone/whatsapp. */
    valueE164: optionalPhoneE164Schema.optional(),
    /** ISO-3166-1 alpha-2 country the number was parsed against. */
    valueCountry: optionalCountryIsoSchema.optional(),
    label: z.string().optional(),
    isPrimary: z.boolean().optional().default(false),
    notes: z.string().optional(),
  })
  .superRefine((data, ctx) => {
    // Post-audit F6: email channel must carry a syntactically valid
    // address. Otherwise sales send-outs bounce silently and the bounce
    // monitor can't classify.
    if (data.channel === 'email' && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.value)) {
      ctx.addIssue({
        code: 'custom',
        path: ['value'],
        message: 'Must be a valid email address.',
      });
    }
  });

// ─── Create ──────────────────────────────────────────────────────────────────

export const createClientSchema = z.object({
  fullName: humanTextSchema({ min: 1, max: 200 }),
  contacts: z.array(contactSchema).min(1, 'At least one contact is required'),
  /** ISO-3166-1 alpha-2 nationality code. */
  nationalityIso: optionalCountryIsoSchema.optional(),
  preferredContactMethod: z.enum(['email', 'phone', 'whatsapp']).optional(),
  preferredLanguage: z.string().optional(),
  /** IANA timezone (e.g. 'Europe/Warsaw'). */
  timezone: optionalIanaTimezoneSchema.optional(),
  source: z.enum(['website', 'manual', 'referral', 'broker', 'other']).optional(),
  sourceDetails: z.string().optional(),
  /** When the client was created from a website-inquiry triage, points
   *  back at the originating `website_submissions.id`. Drives the
   *  conversion-funnel-by-source chart. Migration 0065 installs the FK. */
  sourceInquiryId: z.string().optional(),
  tagIds: z.array(z.string()).optional().default([]),
});

// ─── Update ──────────────────────────────────────────────────────────────────

export const updateClientSchema = createClientSchema
  .omit({ contacts: true, tagIds: true })
  .partial();

// ─── List ─────────────────────────────────────────────────────────────────────

export const listClientsSchema = baseListQuerySchema.extend({
  source: z.enum(['website', 'manual', 'referral', 'broker', 'other']).optional(),
  nationality: z.string().optional(),
  tagIds: z
    .string()
    .transform((v) => v.split(',').filter(Boolean))
    .optional(),
});

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

export type ContactInput = z.infer<typeof contactSchema>;
export type CreateClientInput = z.infer<typeof createClientSchema>;
export type UpdateClientInput = z.infer<typeof updateClientSchema>;
export type ListClientsInput = z.infer<typeof listClientsSchema>;
