import * as z from 'zod'

const privacyEnum = z.enum(['public', 'members', 'private'])

export const emailSchema = z.object({
  email: z.string().trim().toLowerCase().email()
})

export const memberCreateSchema = z.object({
  email: z.string().trim().toLowerCase().email(),
  name: z.string().min(1).max(200),
  circle: z.enum(['community', 'founder', 'practitioner']),
  contributionTier: z.enum(['0', '5', '15', '30', '50'])
})

export const memberProfileUpdateSchema = z.object({
  pronouns: z.string().max(100).optional(),
  timeZone: z.string().max(100).optional(),
  avatar: z.string().max(500).optional(),
  studio: z.string().max(200).optional(),
  bio: z.string().max(5000).optional(),
  location: z.string().max(200).optional(),
  socialLinks: z.object({
    mastodon: z.string().max(300).optional(),
    linkedin: z.string().max(300).optional(),
    website: z.string().max(300).optional(),
    other: z.string().max(300).optional()
  }).optional(),
  offering: z.object({
    text: z.string().max(2000).optional(),
    tags: z.array(z.string().max(100)).max(20).optional()
  }).optional(),
  lookingFor: z.object({
    text: z.string().max(2000).optional(),
    tags: z.array(z.string().max(100)).max(20).optional()
  }).optional(),
  showInDirectory: z.boolean().optional(),
  notifications: z.object({
    events: z.boolean().optional(),
    updates: z.boolean().optional(),
    peerRequests: z.boolean().optional(),
    connectionRequests: z.boolean().optional()
  }).optional(),
  pronounsPrivacy: privacyEnum.optional(),
  timeZonePrivacy: privacyEnum.optional(),
  avatarPrivacy: privacyEnum.optional(),
  studioPrivacy: privacyEnum.optional(),
  bioPrivacy: privacyEnum.optional(),
  locationPrivacy: privacyEnum.optional(),
  socialLinksPrivacy: privacyEnum.optional(),
  offeringPrivacy: privacyEnum.optional(),
  lookingForPrivacy: privacyEnum.optional(),
  craftTags: z.array(z.string().max(100)).max(16).optional(),
  craftTagsPrivacy: privacyEnum.optional(),
  communityConnectionsPrivacy: privacyEnum.optional()
})

export const eventRegistrationSchema = z.object({
  name: z.string().min(1).max(200),
  email: z.string().trim().toLowerCase().email(),
  dietary: z.boolean().optional()
})

export const paymentVerifySchema = z.object({
  cardToken: z.string().min(1),
  customerId: z.union([z.string(), z.number()]).transform(String)
})

// --- Helcim schemas ---

export const helcimCreatePlanSchema = z.object({
  name: z.string().min(1).max(200),
  amount: z.union([z.string().min(1), z.number().positive()]),
  frequency: z.string().min(1).max(50),
  currency: z.string().max(10).optional()
})

export const helcimCustomerSchema = z.object({
  name: z.string().min(1).max(200),
  email: z.string().trim().toLowerCase().email(),
  circle: z.enum(['community', 'founder', 'practitioner']).optional(),
  contributionTier: z.enum(['0', '5', '15', '30', '50']).optional()
})

export const helcimInitializePaymentSchema = z.object({
  amount: z.number().min(0).optional(),
  customerCode: z.string().max(200).optional(),
  metadata: z.object({
    type: z.string().max(100).optional(),
    eventTitle: z.string().max(500).optional(),
    eventId: z.string().max(200).optional()
  }).optional()
})

export const helcimSubscriptionSchema = z.object({
  customerId: z.union([z.string().min(1), z.number()]),
  contributionTier: z.enum(['0', '5', '15', '30', '50']),
  customerCode: z.union([z.string().min(1).max(200), z.number()]).transform(String),
  cardToken: z.string().max(500).optional().nullable()
})

export const helcimUpdateBillingSchema = z.object({
  customerId: z.union([z.string().min(1), z.number()]),
  billingAddress: z.object({
    name: z.string().max(200).optional(),
    street: z.string().min(1).max(500),
    city: z.string().min(1).max(200),
    province: z.string().max(200).optional(),
    state: z.string().max(200).optional(),
    country: z.string().min(1).max(100),
    postalCode: z.string().min(1).max(20)
  })
})

// --- Event ticket/registration schemas ---

export const ticketPurchaseSchema = z.object({
  name: z.string().min(1).max(200),
  email: z.string().trim().toLowerCase().email(),
  transactionId: z.string().max(500).optional()
})

export const ticketReserveSchema = z.object({
  email: z.string().trim().toLowerCase().email()
})

export const ticketEligibilitySchema = z.object({
  email: z.string().trim().toLowerCase().email()
})

export const waitlistSchema = z.object({
  name: z.string().max(200).optional(),
  email: z.string().trim().toLowerCase().email(),
  membershipLevel: z.string().max(100).optional()
})

export const waitlistDeleteSchema = z.object({
  email: z.string().trim().toLowerCase().email()
})

export const cancelRegistrationSchema = z.object({
  email: z.string().trim().toLowerCase().email()
})

export const checkRegistrationSchema = z.object({
  email: z.string().trim().toLowerCase().email()
})

export const guestRegisterSchema = z.object({
  name: z.string().min(1).max(200),
  email: z.string().trim().toLowerCase().email()
})

export const eventPaymentSchema = z.object({
  name: z.string().min(1).max(200),
  email: z.string().trim().toLowerCase().email(),
  paymentToken: z.string().min(1).max(500)
})

// --- Member schemas ---

export const updateContributionSchema = z.object({
  contributionTier: z.enum(['0', '5', '15', '30', '50'])
})

export const updateCircleSchema = z.object({
  circle: z.enum(['community', 'founder', 'practitioner'])
})

export const peerSupportUpdateSchema = z.object({
  enabled: z.boolean().optional(),
  skillTopics: z.array(z.string().max(200)).max(20).optional(),
  supportTopics: z.array(z.string().max(200)).max(20).optional(),
  availability: z.string().max(500).optional(),
  personalMessage: z.string().max(2000).optional(),
  slackUsername: z.string().max(200).optional()
})

// --- Series ticket schemas ---

export const seriesTicketPurchaseSchema = z.object({
  name: z.string().min(1).max(200),
  email: z.string().trim().toLowerCase().email(),
  paymentId: z.string().max(500).optional(),
  ticketType: z.enum(['member', 'public', 'guest']).optional(),
})

export const seriesTicketEligibilitySchema = z.object({
  email: z.string().trim().toLowerCase().email()
})

// --- Admin schemas ---

export const adminEventCreateSchema = z.object({
  title: z.string().min(1).max(500),
  description: z.string().min(1).max(50000),
  startDate: z.string().min(1),
  endDate: z.string().min(1),
  location: z.string().max(500).optional(),
  maxAttendees: z.number().int().positive().optional(),
  membersOnly: z.boolean().optional(),
  registrationDeadline: z.string().optional(),
  pricing: z.object({
    paymentRequired: z.boolean().optional(),
    isFree: z.boolean().optional()
  }).optional(),
  tickets: z.object({
    enabled: z.boolean().optional(),
    public: z.object({
      available: z.boolean().optional(),
      name: z.string().max(200).optional(),
      description: z.string().max(2000).optional(),
      price: z.number().min(0).optional(),
      quantity: z.number().int().positive().optional(),
      earlyBirdPrice: z.number().min(0).optional(),
      earlyBirdDeadline: z.string().optional()
    }).optional()
  }).optional(),
  image: z.string().url().optional(),
  category: z.string().max(100).optional(),
  tags: z.array(z.string().max(100)).max(20).optional(),
  series: z.string().optional()
})

export const adminEventUpdateSchema = z.object({
  title: z.string().min(1).max(500),
  description: z.string().min(1).max(50000),
  startDate: z.string().min(1),
  endDate: z.string().min(1),
  location: z.string().max(500).optional(),
  maxAttendees: z.number().int().positive().optional().nullable(),
  membersOnly: z.boolean().optional(),
  registrationDeadline: z.string().optional().nullable(),
  pricing: z.object({
    paymentRequired: z.boolean().optional(),
    isFree: z.boolean().optional(),
    publicPrice: z.number().min(0).optional()
  }).optional(),
  tickets: z.object({
    enabled: z.boolean().optional(),
    public: z.object({
      available: z.boolean().optional(),
      name: z.string().max(200).optional(),
      description: z.string().max(2000).optional(),
      price: z.number().min(0).optional(),
      quantity: z.number().int().positive().optional().nullable(),
      sold: z.number().int().min(0).optional(),
      earlyBirdPrice: z.number().min(0).optional().nullable(),
      earlyBirdDeadline: z.string().optional().nullable()
    }).optional()
  }).optional(),
  image: z.string().url().optional().nullable(),
  category: z.string().max(100).optional(),
  tags: z.array(z.string().max(100)).max(20).optional(),
  series: z.any().optional(),
  slug: z.string().max(500).optional()
}).passthrough()

export const adminSeriesCreateSchema = z.object({
  id: z.string().min(1).max(200),
  title: z.string().min(1).max(500),
  description: z.string().min(1).max(50000),
  type: z.string().max(100).optional(),
  totalEvents: z.number().int().positive().optional().nullable()
})

export const adminSeriesUpdateSchema = z.object({
  id: z.string().min(1).max(200),
  title: z.string().min(1).max(500),
  description: z.string().max(50000).optional(),
  type: z.string().max(100).optional(),
  totalEvents: z.number().int().positive().optional().nullable()
})

export const adminSeriesItemUpdateSchema = z.object({
  title: z.string().min(1).max(500).optional(),
  description: z.string().max(50000).optional(),
  type: z.string().max(100).optional(),
  totalEvents: z.number().int().positive().optional().nullable(),
  isActive: z.boolean().optional()
})

export const adminSeriesTicketsSchema = z.object({
  id: z.string().min(1).max(200),
  tickets: z.object({
    enabled: z.boolean().optional(),
    requiresSeriesTicket: z.boolean().optional(),
    allowIndividualEventTickets: z.boolean().optional(),
    currency: z.string().max(10).optional(),
    member: z.object({
      available: z.boolean().optional(),
      isFree: z.boolean().optional(),
      price: z.number().min(0).optional(),
      name: z.string().max(200).optional(),
      description: z.string().max(2000).optional(),
      circleOverrides: z.record(z.any()).optional()
    }).optional(),
    public: z.object({
      available: z.boolean().optional(),
      name: z.string().max(200).optional(),
      description: z.string().max(2000).optional(),
      price: z.number().min(0).optional(),
      quantity: z.number().int().positive().optional().nullable(),
      sold: z.number().int().min(0).optional(),
      reserved: z.number().int().min(0).optional(),
      earlyBirdPrice: z.number().min(0).optional().nullable(),
      earlyBirdDeadline: z.string().optional().nullable()
    }).optional(),
    capacity: z.object({
      total: z.number().int().positive().optional().nullable(),
      reserved: z.number().int().min(0).optional()
    }).optional(),
    waitlist: z.object({
      enabled: z.boolean().optional(),
      maxSize: z.number().int().positive().optional().nullable(),
      entries: z.array(z.any()).optional()
    }).optional()
  })
})

export const adminMemberCreateSchema = z.object({
  name: z.string().min(1).max(200),
  email: z.string().trim().toLowerCase().email(),
  circle: z.enum(['community', 'founder', 'practitioner']),
  contributionTier: z.enum(['0', '5', '15', '30', '50'])
})

export const adminMemberUpdateSchema = z.object({
  name: z.string().min(1).max(200),
  email: z.string().trim().toLowerCase().email(),
  circle: z.enum(['community', 'founder', 'practitioner']),
  contributionTier: z.enum(['0', '5', '15', '30', '50']),
  status: z.enum(['pending_payment', 'active', 'suspended', 'cancelled'])
})

export const adminRoleUpdateSchema = z.object({
  role: z.enum(['admin', 'member'])
})

export const bulkMemberImportSchema = z.object({
  members: z.array(z.object({
    name: z.string().min(1).max(200),
    email: z.string().trim().toLowerCase().email(),
    circle: z.enum(['community', 'founder', 'practitioner']),
    contributionTier: z.enum(['0', '5', '15', '30', '50'])
  })).min(1).max(100)
})

export const memberInviteSchema = z.object({
  memberIds: z.array(z.string().min(1)).min(1).max(100),
  emailTemplate: z.string().min(1).max(10000)
})

// --- Tag schemas ---

export const tagSuggestionSchema = z.object({
  label: z.string().min(1).max(100),
  pool: z.enum(['craft', 'cooperative'])
})

export const communityConnectionsUpdateSchema = z.object({
  topics: z.array(z.object({
    tagSlug: z.string().min(1).max(100),
    state: z.enum(['help', 'interested', 'seeking'])
  })).max(20).optional(),
  offerPeerSupport: z.boolean().optional(),
  availability: z.string().max(500).optional(),
  slackHandle: z.string().max(200).optional(),
  personalMessage: z.string().max(2000).optional(),
  details: z.string().max(300).optional()
})
