/**
 * @fileoverview Centralized Zod validation schemas for all Aurora API endpoints.
 * Provides type-safe request/response validation for every entity in the system.
 */

import { z } from "zod";

// ============================================================================
// Common Schemas
// ============================================================================

/**
 * Standard pagination query parameters.
 */
export const PaginationSchema = z.object({
    limit: z.coerce.number().min(1).max(100).optional().default(50),
    offset: z.coerce.number().min(0).optional().default(0),
});

/**
 * Numeric ID parameter validation.
 */
export const NumericIdSchema = z.coerce.number().int().positive();

/**
 * Discord snowflake ID validation (string of digits).
 */
export const SnowflakeIdSchema = z.string().regex(/^\d{17,20}$/, "Invalid Discord ID format");

// ============================================================================
// Items Schemas
// ============================================================================

/**
 * Valid item types in the system.
 */
export const ItemTypeEnum = z.enum([
    "CONSUMABLE",
    "EQUIPMENT",
    "MATERIAL",
    "LOOTBOX",
    "COLLECTIBLE",
    "KEY",
    "TOOL"
]);

/**
 * Valid item rarities.
 */
export const ItemRarityEnum = z.enum(["C", "R", "SR", "SSR"]);

/**
 * Query parameters for listing items.
 */
export const ItemQuerySchema = PaginationSchema.extend({
    search: z.string().optional(),
    type: z.string().optional(),
    rarity: z.string().optional(),
});

/**
 * Schema for creating a new item.
 */
export const CreateItemSchema = z.object({
    name: z.string().min(1, "Name is required").max(100),
    description: z.string().max(500).nullable().optional(),
    rarity: ItemRarityEnum.optional().default("C"),
    type: ItemTypeEnum,
    price: z.union([z.string(), z.number()]).nullable().optional(),
    iconUrl: z.string().optional(),
    imageUrl: z.string().optional(),
    usageData: z.any().nullable().optional(),
});

/**
 * Schema for updating an existing item.
 */
export const UpdateItemSchema = z.object({
    name: z.string().min(1).max(100).optional(),
    description: z.string().max(500).nullable().optional(),
    rarity: ItemRarityEnum.optional(),
    type: ItemTypeEnum.optional(),
    price: z.union([z.string(), z.number()]).nullable().optional(),
    iconUrl: z.string().optional(),
    imageUrl: z.string().optional(),
    usageData: z.any().nullable().optional(),
});

// ============================================================================
// Users Schemas
// ============================================================================

/**
 * Query parameters for listing users.
 */
export const UserQuerySchema = PaginationSchema.extend({
    search: z.string().optional(),
    sortBy: z.enum(["balance", "level", "xp", "username"]).optional().default("balance"),
    sortOrder: z.enum(["asc", "desc"]).optional().default("desc"),
});

/**
 * Schema for updating a user.
 */
export const UpdateUserSchema = z.object({
    username: z.string().min(1).max(32).optional(),
    balance: z.union([z.string(), z.number()]).optional(),
    xp: z.union([z.string(), z.number()]).optional(),
    level: z.coerce.number().int().min(0).optional(),
    dailyStreak: z.coerce.number().int().min(0).optional(),
    isActive: z.boolean().optional(),
    settings: z.record(z.string(), z.any()).optional(),
    classId: z.union([z.string(), z.number()]).optional(),
});

/**
 * Schema for adding an item to user inventory.
 */
export const InventoryAddSchema = z.object({
    itemId: z.coerce.number().int().positive("Item ID is required"),
    quantity: z.union([z.string(), z.number()]).refine(
        (val) => BigInt(val) > 0n,
        "Quantity must be positive"
    ),
});

/**
 * Query params for removing inventory items.
 */
export const InventoryRemoveQuerySchema = z.object({
    amount: z.coerce.number().int().min(1).optional().default(1),
});

// ============================================================================
// Classes Schemas
// ============================================================================

/**
 * Schema for creating a new class.
 */
export const CreateClassSchema = z.object({
    id: z.union([z.string(), z.number()]),
    name: z.string().min(1, "Name is required").max(50),
    balance: z.union([z.string(), z.number()]).optional().default("0"),
    roleId: z.string().nullable().optional(),
});

/**
 * Schema for updating a class.
 */
export const UpdateClassSchema = z.object({
    name: z.string().min(1).max(50).optional(),
    balance: z.union([z.string(), z.number()]).optional(),
    roleId: z.string().nullable().optional(),
});

// ============================================================================
// Moderation Schemas
// ============================================================================

/**
 * Valid moderation case types.
 */
export const ModerationTypeEnum = z.enum([
    "warn",
    "timeout",
    "kick",
    "ban",
    "note",
    "prune"
]);

/**
 * Query parameters for searching moderation cases.
 */
export const CaseQuerySchema = PaginationSchema.extend({
    userId: z.string().optional(),
    moderatorId: z.string().optional(),
    type: ModerationTypeEnum.optional(),
    active: z.preprocess(
        (val) => val === "true" ? true : val === "false" ? false : undefined,
        z.boolean().optional()
    ),
});

/**
 * Schema for creating a moderation case.
 */
export const CreateCaseSchema = z.object({
    type: ModerationTypeEnum,
    userId: z.string().min(1, "User ID is required"),
    username: z.string().min(1, "Username is required"),
    moderatorId: z.string().min(1, "Moderator ID is required"),
    moderatorName: z.string().min(1, "Moderator name is required"),
    reason: z.string().min(1, "Reason is required").max(1000),
    metadata: z.record(z.string(), z.any()).optional().default({}),
});

/**
 * Schema for clearing/resolving a moderation case.
 */
export const ClearCaseSchema = z.object({
    clearedBy: z.string().min(1, "Cleared by ID is required"),
    clearedByName: z.string().min(1, "Cleared by name is required"),
    reason: z.string().max(500).optional().default("Cleared via API"),
});

/**
 * Case ID pattern validation (CASE-XXXX format).
 */
export const CaseIdPattern = /^CASE-\d+$/i;

// ============================================================================
// Transactions Schemas
// ============================================================================

/**
 * Query parameters for listing transactions.
 */
export const TransactionQuerySchema = PaginationSchema.extend({
    userId: z.string().optional(),
    type: z.string().optional(),
});

// ============================================================================
// Lootdrops Schemas
// ============================================================================

/**
 * Query parameters for listing lootdrops.
 */
export const LootdropQuerySchema = z.object({
    limit: z.coerce.number().min(1).max(100).optional().default(50),
});

/**
 * Schema for spawning a lootdrop.
 */
export const CreateLootdropSchema = z.object({
    channelId: z.string().min(1, "Channel ID is required"),
    amount: z.coerce.number().int().positive().optional(),
    currency: z.string().optional(),
});

// ============================================================================
// Admin Actions Schemas
// ============================================================================

/**
 * Schema for toggling maintenance mode.
 */
export const MaintenanceModeSchema = z.object({
    enabled: z.boolean(),
    reason: z.string().max(200).optional(),
});

// ============================================================================
// Type Exports
// ============================================================================

export type ItemQuery = z.infer<typeof ItemQuerySchema>;
export type CreateItem = z.infer<typeof CreateItemSchema>;
export type UpdateItem = z.infer<typeof UpdateItemSchema>;
export type UserQuery = z.infer<typeof UserQuerySchema>;
export type UpdateUser = z.infer<typeof UpdateUserSchema>;
export type InventoryAdd = z.infer<typeof InventoryAddSchema>;
export type CreateClass = z.infer<typeof CreateClassSchema>;
export type UpdateClass = z.infer<typeof UpdateClassSchema>;
export type CaseQuery = z.infer<typeof CaseQuerySchema>;
export type CreateCase = z.infer<typeof CreateCaseSchema>;
export type ClearCase = z.infer<typeof ClearCaseSchema>;
export type TransactionQuery = z.infer<typeof TransactionQuerySchema>;
export type CreateLootdrop = z.infer<typeof CreateLootdropSchema>;
export type MaintenanceMode = z.infer<typeof MaintenanceModeSchema>;
