import { z } from 'zod'

/**
 * Base schemas for database entities
 */

// User schemas
export const UserRoleSchema = z.enum(['admin', 'user', 'artist', 'producer', 'moderator'])
export const UserStatusSchema = z.enum(['active', 'inactive', 'suspended', 'pending'])

export const UserSchema = z.object({
  id: z.string().uuid(),
  username: z.string().min(3).max(50),
  email: z.string().email(),
  firstName: z.string().min(1).max(100),
  lastName: z.string().min(1).max(100),
  displayName: z.string().max(100).optional(),
  role: UserRoleSchema,
  status: UserStatusSchema,
  avatar: z.string().url().optional(),
  bio: z.string().max(1000).optional(),
  location: z.string().max(100).optional(),
  website: z.string().url().optional(),
  isVerified: z.boolean().default(false),
  emailVerified: z.boolean().default(false),
  preferences: z.object({
    language: z.string().default('fr'),
    theme: z.enum(['light', 'dark', 'system']).default('system'),
    notifications: z.object({
      email: z.boolean().default(true),
      push: z.boolean().default(true),
      desktop: z.boolean().default(false),
    }),
    privacy: z.object({
      profileVisibility: z.enum(['public', 'friends', 'private']).default('public'),
      showOnlineStatus: z.boolean().default(true),
      allowDirectMessages: z.boolean().default(true),
    }),
  }),
  stats: z.object({
    tracksUploaded: z.number().default(0),
    playlistsCreated: z.number().default(0),
    followersCount: z.number().default(0),
    followingCount: z.number().default(0),
    totalPlays: z.number().default(0),
  }),
  lastSeenAt: z.date().optional(),
  createdAt: z.date(),
  updatedAt: z.date(),
})

// Audio schemas
export const AudioGenreSchema = z.enum([
  'rock', 'pop', 'jazz', 'classical', 'electronic', 'hip-hop', 'country', 
  'blues', 'reggae', 'folk', 'metal', 'punk', 'indie', 'ambient', 'techno'
])

export const AudioFormatSchema = z.enum(['mp3', 'wav', 'flac', 'aac', 'ogg'])
export const AudioQualitySchema = z.enum(['low', 'medium', 'high', 'lossless'])

export const AudioMetadataSchema = z.object({
  duration: z.number().positive(), // seconds
  bitrate: z.number().positive(), // kbps
  sampleRate: z.number().positive(), // Hz
  channels: z.number().min(1).max(8),
  format: AudioFormatSchema,
  quality: AudioQualitySchema,
  fileSize: z.number().positive(), // bytes
  bpm: z.number().positive().optional(),
  key: z.string().optional(), // Musical key
  loudness: z.number().optional(), // LUFS
})

export const AudioSchema = z.object({
  id: z.string().uuid(),
  title: z.string().min(1).max(200),
  slug: z.string(),
  artist: z.string().min(1).max(100),
  albumId: z.string().uuid().optional(),
  albumTitle: z.string().max(200).optional(),
  genre: AudioGenreSchema,
  subgenre: z.string().max(50).optional(),
  tags: z.array(z.string()).default([]),
  description: z.string().max(2000).optional(),
  lyrics: z.string().optional(),
  metadata: AudioMetadataSchema,
  waveformData: z.array(z.number()).optional(),
  fileUrl: z.string().url(),
  coverImageUrl: z.string().url().optional(),
  uploadedById: z.string().uuid(),
  isPublic: z.boolean().default(true),
  isExplicit: z.boolean().default(false),
  downloadEnabled: z.boolean().default(false),
  stats: z.object({
    plays: z.number().default(0),
    likes: z.number().default(0),
    shares: z.number().default(0),
    downloads: z.number().default(0),
    comments: z.number().default(0),
  }),
  releaseDate: z.date().optional(),
  createdAt: z.date(),
  updatedAt: z.date(),
})

// Playlist schemas
export const PlaylistVisibilitySchema = z.enum(['public', 'unlisted', 'private'])

export const PlaylistSchema = z.object({
  id: z.string().uuid(),
  title: z.string().min(1).max(200),
  slug: z.string(),
  description: z.string().max(2000).optional(),
  coverImageUrl: z.string().url().optional(),
  createdById: z.string().uuid(),
  visibility: PlaylistVisibilitySchema,
  isCollaborative: z.boolean().default(false),
  tags: z.array(z.string()).default([]),
  trackIds: z.array(z.string().uuid()),
  stats: z.object({
    followers: z.number().default(0),
    plays: z.number().default(0),
    shares: z.number().default(0),
  }),
  createdAt: z.date(),
  updatedAt: z.date(),
})

// Conversation schemas
export const ConversationTypeSchema = z.enum(['direct', 'group', 'channel'])
export const MessageTypeSchema = z.enum(['text', 'audio', 'image', 'file', 'system'])
export const MessageStatusSchema = z.enum(['sent', 'delivered', 'read', 'failed'])

export const ConversationSchema = z.object({
  id: z.string().uuid(),
  name: z.string().max(100).optional(),
  description: z.string().max(500).optional(),
  type: ConversationTypeSchema,
  isPrivate: z.boolean().default(false),
  avatarUrl: z.string().url().optional(),
  createdById: z.string().uuid(),
  participantIds: z.array(z.string().uuid()),
  lastMessageId: z.string().uuid().optional(),
  lastActivityAt: z.date(),
  createdAt: z.date(),
  updatedAt: z.date(),
})

export const MessageSchema = z.object({
  id: z.string().uuid(),
  conversationId: z.string().uuid(),
  senderId: z.string().uuid(),
  content: z.string(),
  type: MessageTypeSchema,
  status: MessageStatusSchema,
  parentMessageId: z.string().uuid().optional(), // For replies
  attachments: z.array(z.object({
    id: z.string().uuid(),
    type: z.enum(['image', 'audio', 'video', 'file']),
    url: z.string().url(),
    filename: z.string(),
    size: z.number(),
    mimeType: z.string(),
  })).default([]),
  reactions: z.array(z.object({
    emoji: z.string(),
    userId: z.string().uuid(),
    createdAt: z.date(),
  })).default([]),
  mentions: z.array(z.string().uuid()).default([]),
  isEdited: z.boolean().default(false),
  isDeleted: z.boolean().default(false),
  createdAt: z.date(),
  updatedAt: z.date(),
})

// Export all types
export type User = z.infer<typeof UserSchema>
export type UserRole = z.infer<typeof UserRoleSchema>
export type UserStatus = z.infer<typeof UserStatusSchema>

export type Audio = z.infer<typeof AudioSchema>
export type AudioGenre = z.infer<typeof AudioGenreSchema>
export type AudioMetadata = z.infer<typeof AudioMetadataSchema>

export type Playlist = z.infer<typeof PlaylistSchema>
export type PlaylistVisibility = z.infer<typeof PlaylistVisibilitySchema>

export type Conversation = z.infer<typeof ConversationSchema>
export type ConversationType = z.infer<typeof ConversationTypeSchema>

export type Message = z.infer<typeof MessageSchema>
export type MessageType = z.infer<typeof MessageTypeSchema>
export type MessageStatus = z.infer<typeof MessageStatusSchema>

/**
 * Validation utilities
 */
export const validateUser = (data: unknown): User => UserSchema.parse(data)
export const validateAudio = (data: unknown): Audio => AudioSchema.parse(data)
export const validatePlaylist = (data: unknown): Playlist => PlaylistSchema.parse(data)
export const validateConversation = (data: unknown): Conversation => ConversationSchema.parse(data)
export const validateMessage = (data: unknown): Message => MessageSchema.parse(data)