import { z } from 'zod';

// Accepts both 24-hour (HH:MM[:SS]) and 12-hour (H[H]:MM AM/PM) formats so
// every booking — voice, chat, dashboard — can be canonicalized into the
// start_at/end_at columns the EXCLUDE constraint protects.
const BOOKING_TIME_RE = /^(?:(?:[01]?\d|2[0-3]):[0-5]\d(?::[0-5]\d)?|(?:0?[1-9]|1[0-2]):[0-5]\d\s*[AaPp][Mm]?\.?)$/;
const bookingTimeSchema = z
  .string()
  .regex(BOOKING_TIME_RE, 'booking_time must be HH:MM (24h) or H:MM AM/PM (12h)');

const bookingDateSchema = z
  .string()
  .regex(/^\d{4}-\d{2}-\d{2}$/, 'booking_date must be YYYY-MM-DD');

export const createBookingSchema = z.object({
  branch_id: z.string().uuid().optional(),
  customer_id: z.string().uuid().optional(),
  guest_name: z.string().min(1, 'Guest name is required'),
  guest_phone: z.string().optional(),
  guest_email: z.string().email().optional(),
  table_no: z.string().optional(),
  table_id: z.string().uuid().nullable().optional(),
  party_size: z.number().int().positive().optional(),
  booking_date: bookingDateSchema.optional(),
  booking_time: bookingTimeSchema.optional(),
  start_at: z.string().datetime({ offset: true }).optional(),
  duration_min: z.number().int().min(15).max(480).optional(),
  buffer_min: z.number().int().min(0).max(60).optional(),
  zone: z.string().optional(),
  channel: z.enum(['chat', 'voice', 'whatsapp', 'email', 'sms']).optional(),
  occasion: z.string().optional(),
  dietary_needs: z.array(z.string()).optional(),
  special_requests: z.string().optional(),
  is_vip: z.boolean().optional(),
  notes: z.string().optional(),
}).refine(
  (data) => Boolean(data.start_at) || (Boolean(data.booking_date) && Boolean(data.booking_time)),
  { message: 'Provide either start_at or both booking_date and booking_time so the booking has an occupancy window', path: ['booking_time'] }
);

export const updateBookingSchema = z.object({
  status: z.enum(['pending','confirmed','seated','completed','cancelled','noshow','escalated','reminder_sent']).optional(),
  table_no: z.string().nullable().optional(),
  table_id: z.string().uuid().nullable().optional(),
  party_size: z.number().int().positive().optional(),
  booking_date: bookingDateSchema.optional(),
  booking_time: bookingTimeSchema.optional(),
  start_at: z.string().datetime({ offset: true }).optional(),
  duration_min: z.number().int().min(15).max(480).optional(),
  buffer_min: z.number().int().min(0).max(60).optional(),
  zone: z.string().optional(),
  notes: z.string().optional(),
  special_requests: z.string().optional(),
  reminder_sent: z.boolean().optional(),
  is_vip: z.boolean().optional(),
});

export type CreateBookingInput = z.infer<typeof createBookingSchema>;
export type UpdateBookingInput = z.infer<typeof updateBookingSchema>;
