import { z } from 'zod';
import { SchedulingPollStatus, PollVoteValue } from '@prisma/client';

export const createPollSchema = z.object({
  title: z.string().min(1, 'Title is required').max(200),
  description: z.string().max(2000).optional(),
  location: z.string().max(500).optional(),
  timezone: z.string().default('America/Edmonton'),
  allowAnonymous: z.boolean().optional().default(true),
  isPrivate: z.boolean().optional().default(false),
  notifyOnVote: z.boolean().optional().default(true),
  votingDeadline: z.string().datetime().optional(),
  autoFinalize: z.boolean().optional().default(false),
  autoFinalizeThreshold: z.number().int().min(1).max(100).nullable().optional(),
  autoConvertToCalendar: z.boolean().optional().default(false),
  autoConvertToGancio: z.boolean().optional().default(false),
  autoConvertToShift: z.boolean().optional().default(false),
  tieBreaker: z.enum(['earliest', 'organizer_choice']).optional().default('earliest'),
  autoEnrollVoters: z.boolean().optional().default(true),
  options: z.array(z.object({
    date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be YYYY-MM-DD'),
    startTime: z.string().regex(/^\d{2}:\d{2}$/, 'Start time must be HH:MM'),
    endTime: z.string().regex(/^\d{2}:\d{2}$/, 'End time must be HH:MM'),
  })).min(1, 'At least 1 option required').max(20, 'Maximum 20 options'),
});

export const updatePollSchema = z.object({
  title: z.string().min(1).max(200).optional(),
  description: z.string().max(2000).nullable().optional(),
  location: z.string().max(500).nullable().optional(),
  timezone: z.string().optional(),
  allowAnonymous: z.boolean().optional(),
  isPrivate: z.boolean().optional(),
  notifyOnVote: z.boolean().optional(),
  votingDeadline: z.string().datetime().nullable().optional(),
  status: z.nativeEnum(SchedulingPollStatus).optional(),
  autoFinalize: z.boolean().optional(),
  autoFinalizeThreshold: z.number().int().min(1).max(100).nullable().optional(),
  autoConvertToCalendar: z.boolean().optional(),
  autoConvertToGancio: z.boolean().optional(),
  autoConvertToShift: z.boolean().optional(),
  tieBreaker: z.enum(['earliest', 'organizer_choice']).optional(),
  autoEnrollVoters: z.boolean().optional(),
});

export const addOptionsSchema = z.object({
  options: z.array(z.object({
    date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be YYYY-MM-DD'),
    startTime: z.string().regex(/^\d{2}:\d{2}$/, 'Start time must be HH:MM'),
    endTime: z.string().regex(/^\d{2}:\d{2}$/, 'End time must be HH:MM'),
  })).min(1).max(20),
});

export const participantNeedsInlineSchema = z.object({
  needsWheelchair: z.boolean().optional(),
  needsGroundFloor: z.boolean().optional(),
  needsHearingLoop: z.boolean().optional(),
  needsSignLanguage: z.boolean().optional(),
  otherAccessibility: z.string().max(1000).nullable().optional(),
  isVegan: z.boolean().optional(),
  isVegetarian: z.boolean().optional(),
  isGlutenFree: z.boolean().optional(),
  isHalal: z.boolean().optional(),
  isKosher: z.boolean().optional(),
  hasNutAllergy: z.boolean().optional(),
  otherDietary: z.string().max(1000).nullable().optional(),
  needsChildcare: z.boolean().optional(),
  childcareDetails: z.string().max(1000).nullable().optional(),
  needsTransportation: z.boolean().optional(),
  transportationNotes: z.string().max(1000).nullable().optional(),
  preferredLanguage: z.string().max(10).nullable().optional(),
  needsTranslation: z.boolean().optional(),
  translationLanguage: z.string().max(100).nullable().optional(),
  visibilityConsent: z.enum(['organizer_only', 'shared_with_hosts', 'public']).optional().default('organizer_only'),
}).optional();

export const submitVotesSchema = z.object({
  voterName: z.string().min(1, 'Name is required').max(100),
  voterEmail: z.preprocess(
    (val) => (typeof val === 'string' && val.trim() === '' ? undefined : val),
    z.string().email('Please enter a valid email address').max(200).optional(),
  ),
  voterToken: z.string().optional(),
  votes: z.array(z.object({
    optionId: z.string().min(1),
    value: z.nativeEnum(PollVoteValue),
  })).min(1, 'At least one vote required'),
  participantNeeds: participantNeedsInlineSchema,
});

export const submitCommentSchema = z.object({
  authorName: z.string().min(1, 'Name is required').max(100),
  content: z.string().min(1, 'Comment is required').max(2000),
});

export const finalizePollSchema = z.object({
  optionId: z.string().min(1, 'Option ID is required'),
});

export const convertToShiftSchema = z.object({
  maxVolunteers: z.number().int().min(1).default(10),
  isPublic: z.boolean().optional().default(true),
  cutId: z.string().optional(),
});

export const updateOptionSchema = z.object({
  date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be YYYY-MM-DD').optional(),
  startTime: z.string().regex(/^\d{2}:\d{2}$/, 'Start time must be HH:MM').optional(),
  endTime: z.string().regex(/^\d{2}:\d{2}$/, 'End time must be HH:MM').optional(),
});

export const listPollsSchema = z.object({
  page: z.coerce.number().int().positive().default(1),
  limit: z.coerce.number().int().positive().max(100).default(20),
  search: z.string().optional(),
  status: z.nativeEnum(SchedulingPollStatus).optional(),
});

export type CreatePollInput = z.infer<typeof createPollSchema>;
export type UpdatePollInput = z.infer<typeof updatePollSchema>;
export type AddOptionsInput = z.infer<typeof addOptionsSchema>;
export type SubmitVotesInput = z.infer<typeof submitVotesSchema>;
export type SubmitCommentInput = z.infer<typeof submitCommentSchema>;
export type FinalizePollInput = z.infer<typeof finalizePollSchema>;
export type ConvertToShiftInput = z.infer<typeof convertToShiftSchema>;
export type UpdateOptionInput = z.infer<typeof updateOptionSchema>;
export type ListPollsInput = z.infer<typeof listPollsSchema>;
