/**
 * Zod Validation Schemas for API endpoints
 * Centralized validation logic for type-safety and security
 */

import { z } from 'zod';

// ==========================================
// QR Code Schemas
// ==========================================

export const qrStyleSchema = z.object({
  fgColor: z.string().regex(/^#[0-9A-F]{6}$/i, 'Invalid foreground color format').optional(),
  bgColor: z.string().regex(/^#[0-9A-F]{6}$/i, 'Invalid background color format').optional(),
  cornerStyle: z.enum(['square', 'rounded']).optional(),
  size: z.number().min(100).max(1000).optional(),
});

export const createQRSchema = z.object({
  title: z.string()
    .min(1, 'Title is required')
    .max(100, 'Title must be less than 100 characters'),

  content: z.record(z.any()), // Accept any object structure for content

  isStatic: z.boolean().optional(),

  contentType: z.enum(['URL', 'VCARD', 'GEO', 'PHONE', 'SMS', 'WHATSAPP', 'TEXT', 'PDF', 'APP', 'COUPON', 'FEEDBACK'], {
    errorMap: () => ({ message: 'Invalid content type' })
  }),

  tags: z.array(z.string()).optional(),

  style: z.object({
    foregroundColor: z.string().optional(),
    backgroundColor: z.string().optional(),
    cornerStyle: z.enum(['square', 'rounded']).optional(),
    size: z.number().optional(),
  }).optional(),
});

export const updateQRSchema = z.object({
  title: z.string()
    .min(1, 'Title is required')
    .max(100, 'Title must be less than 100 characters')
    .optional(),

  content: z.string()
    .min(1, 'Content is required')
    .max(5000, 'Content must be less than 5000 characters')
    .optional(),

  style: qrStyleSchema.optional(),

  isActive: z.boolean().optional(),
});

export const bulkQRSchema = z.object({
  qrs: z.array(
    z.object({
      title: z.string().min(1).max(100),
      content: z.string().min(1).max(5000),
      contentType: z.enum(['URL', 'VCARD', 'GEO', 'PHONE', 'SMS', 'WHATSAPP', 'TEXT', 'PDF', 'APP', 'COUPON', 'FEEDBACK']),
    })
  ).min(1, 'At least one QR code is required')
    .max(100, 'Maximum 100 QR codes per bulk creation'),
});

// ==========================================
// Authentication Schemas
// ==========================================

export const loginSchema = z.object({
  email: z.string()
    .email('Invalid email format')
    .toLowerCase(),

  password: z.string()
    .min(1, 'Password is required'),
});

export const signupSchema = z.object({
  name: z.string()
    .min(2, 'Name must be at least 2 characters')
    .max(100, 'Name must be less than 100 characters')
    .trim(),

  email: z.string()
    .email('Invalid email format')
    .toLowerCase()
    .trim(),

  password: z.string()
    .min(8, 'Password must be at least 8 characters')
    .max(100, 'Password must be less than 100 characters'),
  // Password complexity rules removed for easier testing
});

export const forgotPasswordSchema = z.object({
  email: z.string()
    .email('Invalid email format')
    .toLowerCase()
    .trim(),
});

export const resetPasswordSchema = z.object({
  token: z.string().min(1, 'Reset token is required'),
  password: z.string()
    .min(8, 'Password must be at least 8 characters')
    .max(100, 'Password must be less than 100 characters'),
  // Password complexity rules removed for easier testing
});

// ==========================================
// Settings Schemas
// ==========================================

export const updateProfileSchema = z.object({
  name: z.string()
    .min(2, 'Name must be at least 2 characters')
    .max(100, 'Name must be less than 100 characters')
    .trim(),
});

export const changePasswordSchema = z.object({
  currentPassword: z.string()
    .min(1, 'Current password is required'),

  newPassword: z.string()
    .min(8, 'Password must be at least 8 characters')
    .max(100, 'Password must be less than 100 characters'),
  // Password complexity rules removed for easier testing
});

// ==========================================
// Stripe Schemas
// ==========================================

export const createCheckoutSchema = z.object({
  priceId: z.string().min(1, 'Price ID is required'),
});

// ==========================================
// Newsletter Schemas
// ==========================================

export const newsletterSubscribeSchema = z.object({
  email: z.string()
    .email('Invalid email format')
    .toLowerCase()
    .trim()
    .max(255, 'Email must be less than 255 characters'),
});

// ==========================================
// Helper: Format Zod Errors
// ==========================================

export function formatZodError(error: z.ZodError) {
  return {
    error: 'Validation failed',
    details: error.errors.map(err => ({
      field: err.path.join('.'),
      message: err.message,
    })),
  };
}

// ==========================================
// Helper: Validate with Zod
// ==========================================

export async function validateRequest<T>(
  schema: z.ZodSchema<T>,
  data: unknown
): Promise<{ success: true; data: T } | { success: false; error: any }> {
  try {
    const validatedData = schema.parse(data);
    return { success: true, data: validatedData };
  } catch (error) {
    if (error instanceof z.ZodError) {
      return { success: false, error: formatZodError(error) };
    }
    return { success: false, error: { error: 'Invalid request data' } };
  }
}
