import { z } from 'zod';
import { SupportLevel, BuildingType } from '@prisma/client';

export const createLocationSchema = z.object({
  address: z.string().min(1, 'Address is required'),
  firstName: z.string().optional(),
  lastName: z.string().optional(),
  email: z.string().email().optional().or(z.literal('')),
  phone: z.string().optional(),
  unitNumber: z.string().optional(),
  supportLevel: z.nativeEnum(SupportLevel).optional(),
  sign: z.boolean().optional().default(false),
  signSize: z.string().optional(),
  notes: z.string().optional(),
  buildingNotes: z.string().max(2000, 'Building notes must be 2000 characters or less').optional(),
  latitude: z.number().min(-90).max(90).optional(),
  longitude: z.number().min(-180).max(180).optional(),
});

export const updateLocationSchema = z.object({
  // Location fields
  address: z.string().min(1).optional(),
  latitude: z.number().min(-90).max(90).nullable().optional(),
  longitude: z.number().min(-180).max(180).nullable().optional(),
  postalCode: z.string().nullable().optional(),
  province: z.string().nullable().optional(),
  buildingType: z.nativeEnum(BuildingType).nullable().optional(),
  buildingNotes: z.string().max(2000, 'Building notes must be 2000 characters or less').nullable().optional(),
  // Address fields (will update first address)
  firstName: z.string().nullable().optional(),
  lastName: z.string().nullable().optional(),
  email: z.string().email().optional().or(z.literal('')).nullable().optional(),
  phone: z.string().nullable().optional(),
  unitNumber: z.string().nullable().optional(),
  supportLevel: z.nativeEnum(SupportLevel).nullable().optional(),
  sign: z.boolean().optional(),
  signSize: z.string().nullable().optional(),
  notes: z.string().nullable().optional(),
});

export const listLocationsSchema = z.object({
  page: z.coerce.number().int().positive().default(1),
  limit: z.coerce.number().int().positive().max(100).default(20),
  search: z.string().optional(),
  supportLevel: z.nativeEnum(SupportLevel).optional(),
  hasSign: z.coerce.boolean().optional(),
  confidenceLevel: z.enum(['high', 'medium', 'low', 'none']).optional(),
  sortBy: z.enum(['createdAt', 'address', 'supportLevel']).optional().default('createdAt'),
  sortOrder: z.enum(['asc', 'desc']).optional().default('desc'),
});

export const locationIdSchema = z.object({
  id: z.string().min(1),
});

export const geocodeAddressSchema = z.object({
  address: z.string().min(1, 'Address is required'),
});

export const bulkDeleteSchema = z.object({
  ids: z.array(z.string().min(1)).min(1, 'At least one ID is required'),
});

export const reverseGeocodeSchema = z.object({
  latitude: z.number().min(-90).max(90),
  longitude: z.number().min(-180).max(180),
});

export const bulkImportSchema = z.object({
  format: z.enum(['standard', 'nar']).default('standard'),
  filterType: z.enum(['none', 'cut', 'mapArea', 'city', 'province']).default('none'),
  cutId: z.string().optional(),
  filterCity: z.string().optional(),
  filterProvince: z.string().optional(),
  residentialOnly: z.coerce.boolean().default(false),
  deduplicateRadius: z.coerce.number().min(0).max(100).default(5),
  skipGeocoding: z.coerce.boolean().default(true),
  batchSize: z.coerce.number().int().min(100).max(5000).default(1000),
});

export const boundsQuerySchema = z.object({
  minLat: z.coerce.number().min(-90).max(90),
  maxLat: z.coerce.number().min(-90).max(90),
  minLng: z.coerce.number().min(-180).max(180),
  maxLng: z.coerce.number().min(-180).max(180),
});

export type CreateLocationInput = z.infer<typeof createLocationSchema>;
export type UpdateLocationInput = z.infer<typeof updateLocationSchema>;
export type ListLocationsInput = z.infer<typeof listLocationsSchema>;
export type BulkImportInput = z.infer<typeof bulkImportSchema>;
export type BoundsQuery = z.infer<typeof boundsQuerySchema>;
