// src/server/features/schedule/schedule.schema.ts
// Zod schemas for schedule validation

import { z } from 'zod';

// Shift status enum - normalized to capitalized format for consistency
// Accepts both lowercase and uppercase for backward compatibility, but normalizes to capitalized
export const shiftStatusEnum = z.enum(['Blank', 'Work', 'Holiday', 'Unavailable']);

// Role at shift enum
export const roleAtShiftEnum = z.enum(['Manager', 'Maid']);

// User role enum
export const userRoleEnum = z.enum(['ADMIN', 'MANAGER', 'MAID', 'GOD']);

// Grid query schema
export const getShiftsGridSchema = z.object({
  month: z.coerce.number().int().min(1).max(12),
  year: z.coerce.number().int().min(2000).max(2100),
});

// Update shift schema
export const updateShiftSchema = z.object({
  userId: z.string(),
  date: z.coerce.date(),
  roleAtShift: roleAtShiftEnum,
  status: shiftStatusEnum,
});

// Bulk update shifts schema
export const bulkUpdateShiftsSchema = z.object({
  shifts: z.array(updateShiftSchema),
});

// Approve shifts schema
export const approveShiftsSchema = z.object({
  month: z.coerce.number().int().min(1).max(12),
  year: z.coerce.number().int().min(2000).max(2100),
});

// Reject shifts schema
export const rejectShiftsSchema = z.object({
  month: z.coerce.number().int().min(1).max(12),
  year: z.coerce.number().int().min(2000).max(2100),
});

// User response schema
export const userResponseSchema = z.object({
  id: z.string(),
  username: z.string(),
  firstName: z.string(),
  lastName: z.string(),
  fullName: z.string(),
  email: z.string().nullable().optional(),
  role: userRoleEnum.nullable(),
  isMaidAlso: z.boolean(),
});

// Shift response schema
export const shiftResponseSchema = z.object({
  id: z.string(),
  date: z.string(),
  userId: z.string(),
  roleAtShift: roleAtShiftEnum,
  status: shiftStatusEnum,
  isApproved: z.boolean(),
  createdBy: z.string(),
  createdAt: z.string(),
  updatedAt: z.string(),
  archivedAt: z.string().nullable(),
});

// Employment period response schema
export const employmentPeriodResponseSchema = z.object({
  id: z.string(),
  userId: z.string(),
  startDate: z.string(),
  endDate: z.string().nullable(),
  isMaid: z.boolean(),
  createdAt: z.string(),
});

// Flat schema for shifts grid data (without success wrapper)
export const shiftsGridDataSchema = z.object({
  managers: z.array(userResponseSchema),
  maids: z.array(userResponseSchema),
  shifts: z.array(shiftResponseSchema),
  employmentPeriods: z.array(employmentPeriodResponseSchema),
});

// Flat schema for pending count data (without success wrapper)
export const pendingCountDataSchema = z.object({
  count: z.number(),
});

// Shift grid response schema
export const shiftsGridResponseSchema = z.object({
  success: z.boolean(),
  data: z.object({
    managers: z.array(userResponseSchema),
    maids: z.array(userResponseSchema),
    shifts: z.array(shiftResponseSchema),
    employmentPeriods: z.array(employmentPeriodResponseSchema),
  }),
});

// Success response schema
export const successResponseSchema = z.object({
  success: z.boolean(),
  message: z.string(),
});

// Error response schema
export const errorResponseSchema = z.object({
  success: z.boolean(),
  error: z.object({
    message: z.string(),
    code: z.string(),
  }),
});

// Pending count response schema
export const pendingCountResponseSchema = z.object({
  success: z.boolean(),
  data: z.object({
    count: z.number(),
  }),
});

// Types
export type GetShiftsGridInput = z.infer<typeof getShiftsGridSchema>;
export type UpdateShiftInput = z.infer<typeof updateShiftSchema>;
export type BulkUpdateShiftsInput = z.infer<typeof bulkUpdateShiftsSchema>;
export type ApproveShiftsInput = z.infer<typeof approveShiftsSchema>;
export type RejectShiftsInput = z.infer<typeof rejectShiftsSchema>;
export type UserResponse = z.infer<typeof userResponseSchema>;
export type ShiftResponse = z.infer<typeof shiftResponseSchema>;
export type EmploymentPeriodResponse = z.infer<typeof employmentPeriodResponseSchema>;
export type ShiftsGridResponse = z.infer<typeof shiftsGridResponseSchema>;
export type PendingCountResponse = z.infer<typeof pendingCountResponseSchema>;
export type ShiftsGridData = z.infer<typeof shiftsGridDataSchema>;
export type PendingCountData = z.infer<typeof pendingCountDataSchema>;
