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

import { z } from 'zod';

// Enums
export const notePriorityEnum = z.enum(['low', 'normal', 'high']);
export const noteStatusEnum = z.enum(['active', 'done', 'cancelled']); // deferred removed - now using personal reminders in note_layouts
export const noteHistoryActionEnum = z.enum(['created', 'updated', 'status_changed', 'commented', 'returned', 'priority_changed']);

// Note input schema
export const createNoteSchema = z.object({
  title: z.string().trim().min(1, 'Title is required').max(255, 'Title is too long'),
  content: z.string().trim().min(1, 'Content is required'),
  priority: notePriorityEnum.default('normal'),
  isPublic: z.boolean().default(false),
  column: z.number().int().min(1).max(6).default(1),
  positionY: z.number().int().min(0).default(0),
  height: z.number().int().min(65).max(1000).default(220),
  reminderAt: z.string().datetime().nullable().optional()
    .transform(val => val ? new Date(val) : null),
  // userId и spaceId заполняются на бэкенде из контекста авторизации
});

export const updateNoteSchema = z.object({
  title: z.string().min(1, 'Title is required').max(255, 'Title is too long').optional(),
  content: z.string().min(1, 'Content is required').optional(),
  priority: notePriorityEnum.optional(),
  status: noteStatusEnum.optional(),
  isPublic: z.boolean().optional(),
  column: z.number().int().min(1).max(6).optional(),
  positionY: z.number().int().min(0).optional(),
  height: z.number().int().min(65).max(1000).optional(),
  userId: z.string().uuid().optional(),
  spaceId: z.string().uuid().optional(),
  comment: z.string().optional(), // Комментарий при изменении статуса
  reminderAt: z.string().datetime().nullable().optional()
    .transform(val => val !== undefined ? (val ? new Date(val) : null) : undefined),
});

// Note status change schema
export const changeNoteStatusSchema = z.object({
  status: noteStatusEnum,
  comment: z.string().optional(),
  reason: z.string().optional(),
});

// Note response schema (compatible with BaseService)
export const noteResponseSchema = z.object({
  id: z.string().uuid(),
  title: z.string(),
  content: z.string(),
  authorId: z.string().uuid(),
  userId: z.string().uuid(),
  spaceId: z.string().uuid(),
  priority: notePriorityEnum,
  status: noteStatusEnum,
  isPublic: z.boolean(),
  column: z.number().int().min(1).max(6),
  positionY: z.number().int().min(0),
  height: z.number().int().min(65).max(1000),
  lastCommentAt: z.string().datetime().nullable(),
  lastCommentAuthorId: z.string().uuid().nullable(),
  priorityUpdatedAt: z.string().datetime().nullable(),
  lastPriorityAuthorId: z.string().uuid().nullable(),
  createdAt: z.string().datetime(),
  updatedAt: z.string().datetime(),
  archivedAt: z.string().datetime().nullable(),
  layout: z.object({
    reminderAt: z.string().datetime().nullable(),
    lastCommentViewedAt: z.string().datetime().nullable(),
    lastPriorityViewedAt: z.string().datetime().nullable(),
  }).nullable(),
});

// Note layout schemas (for personal positioning and reminders)
export const updateNoteLayoutSchema = z.object({
  column: z.number().int().min(1).max(6).optional(),
  positionY: z.number().int().min(0).optional(),
  height: z.number().int().min(65).max(1000).optional(),
  reminderAt: z.string().datetime().nullable().optional()
    .transform(val => val !== undefined ? (val ? new Date(val) : null) : undefined),
  lastCommentViewedAt: z.string().datetime().nullable().optional()
    .transform(val => val !== undefined ? (val ? new Date(val) : null) : undefined),
});

export const noteLayoutResponseSchema = z.object({
  id: z.string().uuid(),
  noteId: z.string().uuid(),
  userId: z.string().uuid(),
  column: z.number().int().min(1).max(6),
  positionY: z.number().int().min(0),
  height: z.number().int().min(65).max(1000),
  reminderAt: z.string().datetime().nullable(),
  lastCommentViewedAt: z.string().datetime().nullable(),
  lastPriorityViewedAt: z.string().datetime().nullable(),
  createdAt: z.string().datetime(),
  updatedAt: z.string().datetime(),
});

// Note comment schemas
export const createNoteCommentSchema = z.object({
  noteId: z.string().uuid('Invalid note ID'),
  content: z.string().min(1, 'Comment content is required'),
});

export const noteCommentResponseSchema = z.object({
  id: z.string(),
  noteId: z.string(),
  authorId: z.string(),
  content: z.string(),
  isRead: z.boolean(),
  createdAt: z.string().datetime(),
  updatedAt: z.string().datetime(),
});

// Note history schemas
export const noteHistoryResponseSchema = z.object({
  id: z.string(),
  noteId: z.string(),
  action: noteHistoryActionEnum,
  payload: z.object({
    oldStatus: z.string().optional(),
    newStatus: z.string().optional(),
    commentText: z.string().optional(),
    reason: z.string().optional(),
    changes: z.object({}).optional(),
  }).optional(),
  authorId: z.string(),
  createdAt: z.string().datetime(),
});

// Notes list response schema
export const notesListResponseSchema = z.object({
  success: z.boolean(),
  data: z.array(noteResponseSchema),
});

// Single note response schema
export const noteResponseWrapperSchema = z.object({
  success: z.boolean(),
  data: noteResponseSchema,
});

// Note comments list response schema
export const noteCommentsListResponseSchema = z.object({
  success: z.boolean(),
  data: z.array(noteCommentResponseSchema),
});

// Note history list response schema
export const noteHistoryListResponseSchema = z.object({
  success: z.boolean(),
  data: z.array(noteHistoryResponseSchema),
});

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

// Types for frontend (exported via z.infer for type safety)
export type CreateNoteInput = z.infer<typeof createNoteSchema>;
export type UpdateNoteInput = z.infer<typeof updateNoteSchema>;
export type ChangeNoteStatusInput = z.infer<typeof changeNoteStatusSchema>;
export type CreateNoteCommentInput = z.infer<typeof createNoteCommentSchema>;
export type UpdateNoteLayoutInput = z.infer<typeof updateNoteLayoutSchema>;
export type NoteResponse = z.infer<typeof noteResponseSchema>;
export type NoteCommentResponse = z.infer<typeof noteCommentResponseSchema>;
export type NoteHistoryResponse = z.infer<typeof noteHistoryResponseSchema>;
export type NoteLayoutResponse = z.infer<typeof noteLayoutResponseSchema>;
export type NotePriority = z.infer<typeof notePriorityEnum>;
export type NoteStatus = z.infer<typeof noteStatusEnum>;
export type NoteHistoryAction = z.infer<typeof noteHistoryActionEnum>;
