// src/shared/contracts/notes.ts
// Notes contracts - centralized types for notes management
// Zod Alignment: Strict validation with z.string().datetime().nullable() for all date fields

import { z } from 'zod';

/**
 * Zod schemas for notes validation
 */

// Note priority values
export const notePrioritySchema = z.enum(['low', 'normal', 'high']);
export type NotePriority = z.infer<typeof notePrioritySchema>;

// Note status values
export const noteStatusSchema = z.enum(['active', 'done', 'cancelled']);
export type NoteStatus = z.infer<typeof noteStatusSchema>;

// Note history action values
export const noteHistoryActionSchema = z.enum(['created', 'updated', 'status_changed', 'commented', 'returned', 'priority_changed']);
export type NoteHistoryAction = z.infer<typeof noteHistoryActionSchema>;

// Note layout schema
export const noteLayoutSchema = z.object({
  id: z.string().uuid(),
  noteId: z.string().uuid(),
  userId: z.string().uuid(),
  column: z.number(),
  positionY: z.number(),
  height: z.number(),
  reminderAt: z.string().datetime().nullable(),
  lastViewedAt: z.string().datetime().nullable(), // Unified field for last view time
  createdAt: z.string().datetime(),
  updatedAt: z.string().datetime(),
});
export type NoteLayout = z.infer<typeof noteLayoutSchema>;

// Note comment schema
export const noteCommentSchema = z.object({
  id: z.string().uuid(),
  noteId: z.string().uuid(),
  authorId: z.string().uuid(),
  content: z.string(),
  createdAt: z.string().datetime(),
  updatedAt: z.string().datetime(),
});
export type NoteComment = z.infer<typeof noteCommentSchema>;

// Note history entry schema
export const noteHistoryEntrySchema = z.object({
  id: z.string().uuid(),
  noteId: z.string().uuid(),
  action: noteHistoryActionSchema,
  payload: z.object({
    oldStatus: z.string().optional(),
    newStatus: z.string().optional(),
    commentText: z.string().optional(),
    reason: z.string().optional(),
    changes: z.record(z.string(), z.unknown()).optional(),
  }).optional(),
  authorId: z.string().uuid(),
  createdAt: z.string().datetime(),
});
export type NoteHistoryEntry = z.infer<typeof noteHistoryEntrySchema>;

// Note response schema (strict ISO 8601 datetime validation)
export const noteResponseSchema = z.object({
  id: z.string().uuid(),
  title: z.string(),
  content: z.string(),
  authorId: z.string().uuid(),
  authorName: z.string().nullish().catch(null),
  userId: z.string().uuid(),
  spaceId: z.string().uuid(),
  priority: notePrioritySchema,
  status: noteStatusSchema,
  isPublic: z.boolean(),
  isAuthority: z.boolean().optional(),
  createdAt: z.string().datetime(),
  updatedAt: z.string().datetime(),
  archivedAt: z.string().datetime().nullable(),
  lastCommentAt: z.string().datetime().nullish().catch(null),
  lastCommentAuthorId: z.string().uuid().nullish().catch(null),
  priorityUpdatedAt: z.string().datetime().nullable(),
  lastPriorityAuthorId: z.string().uuid().nullable(),
  lastMentionAt: z.string().datetime().nullish().catch(null), // Personal mention timestamp (soft validation)
  layout: noteLayoutSchema.nullable(),
  statusChangeReason: z.string().nullish().catch(null), // Soft validation for status change reason
});
export type Note = z.infer<typeof noteResponseSchema>;

/**
 * Event payloads (strict typing)
 */

// Note event payload for note creation
export const noteCreatedEventSchema = z.object({
  noteId: z.string().uuid(),
  note: noteResponseSchema,
  authorId: z.string().uuid(),
  content: z.string(),
});
export type NoteCreatedEvent = z.infer<typeof noteCreatedEventSchema>;

// Note event payload for note update
export const noteUpdatedEventSchema = z.object({
  noteId: z.string().uuid(),
  note: noteResponseSchema,
  authorId: z.string().uuid(),
  performerId: z.string().uuid().optional(),
  oldStatus: z.string().optional(),
  userId: z.string().uuid().optional(),
  contentUpdated: z.boolean().optional(),
  statusChanged: z.boolean().optional(),
  isPublicChanged: z.boolean().optional(),
  newIsPublic: z.boolean().optional(),
  priorityChanged: z.boolean().optional(),
  oldPriority: z.string().optional(),
});
export type NoteUpdatedEvent = z.infer<typeof noteUpdatedEventSchema>;

// Note event payload for note deletion
export const noteDeletedEventSchema = z.object({
  noteId: z.string().uuid(),
});
export type NoteDeletedEvent = z.infer<typeof noteDeletedEventSchema>;

// Comment event payload for comment creation
export const commentCreatedEventSchema = z.object({
  noteId: z.string().uuid(),
  commentId: z.string().uuid(),
  authorId: z.string().uuid(),
  noteTitle: z.string(),
  isPublic: z.boolean(),
  content: z.string(),
  lastCommentAt: z.string().datetime(),
  lastCommentAuthorId: z.string().uuid(),
});
export type CommentCreatedEvent = z.infer<typeof commentCreatedEventSchema>;

// Personal note reminder event payload
export const personalNoteReminderEventSchema = z.object({
  noteId: z.string().uuid(),
  title: z.string(),
  userId: z.string().uuid(),
  reminderAt: z.string().datetime(),
});
export type PersonalNoteReminderEvent = z.infer<typeof personalNoteReminderEventSchema>;
