// src/server/features/notes/db/repository/history.ts
// History functions for managing note history and comments

import crypto from 'node:crypto';
import { db } from '../../../../shared/db/client';
import { notes } from '../notes.table';
import { noteHistory } from '../note_history.table';
import { noteComments } from '../note_comments.table';
import { eq } from 'drizzle-orm';
import { dayjs } from '../../../../shared/lib/dayjs';
import { loggerService } from '../../../../shared/lib/logger';
import type { NoteHistoryPayload } from '../../lib/history.service';

const logger = loggerService.get('DB').child({ module: 'notes-repo-history' });

/**
 * Find all comments for a note
 */
export async function findComments(noteId: string) {
  const result = await db
    .select({
      id: noteComments.id,
      noteId: noteComments.noteId,
      authorId: noteComments.authorId,
      content: noteComments.content,
      createdAt: noteComments.createdAt,
      updatedAt: noteComments.updatedAt,
    })
    .from(noteComments)
    .where(eq(noteComments.noteId, noteId))
    .orderBy(noteComments.createdAt);

  // Update lastCommentAt and lastCommentAuthorId in notes table if there are comments
  if (result.length > 0) {
    const latestComment = result[result.length - 1];
    await db
      .update(notes)
      .set({
        lastCommentAt: latestComment.createdAt,
        lastCommentAuthorId: latestComment.authorId,
      })
      .where(eq(notes.id, noteId));
  }

  // Day.js Protocol: Backend uses dayjs.utc() for all date operations
  return result.map(entry => ({
    ...entry,
    createdAt: dayjs.utc(entry.createdAt).toISOString(),
    updatedAt: dayjs.utc(entry.updatedAt).toISOString(),
  }));
}

/**
 * Find a comment by ID
 */
export async function findCommentById(commentId: string) {
  const result = await db
    .select()
    .from(noteComments)
    .where(eq(noteComments.id, commentId))
    .limit(1);

  if (!result || result.length === 0) {
    return null;
  }

  const comment = result[0];

  // Day.js Protocol: Backend uses dayjs.utc() for all date operations
  return {
    ...comment,
    createdAt: dayjs.utc(comment.createdAt).toISOString(),
    updatedAt: dayjs.utc(comment.updatedAt).toISOString(),
  };
}

/**
 * Find all history entries for a note
 */
export async function findHistory(noteId: string) {
  const result = await db
    .select({
      id: noteHistory.id,
      noteId: noteHistory.noteId,
      action: noteHistory.action,
      payload: noteHistory.payload,
      authorId: noteHistory.authorId,
      createdAt: noteHistory.createdAt,
    })
    .from(noteHistory)
    .where(eq(noteHistory.noteId, noteId))
    .orderBy(noteHistory.createdAt);

  // Day.js Protocol: Backend uses dayjs.utc() for all date operations
  // Parse JSON payload from string to object (MySQL may return JSON as string)
  return result.map(entry => ({
    ...entry,
    payload: typeof entry.payload === 'string'
      ? JSON.parse(entry.payload)
      : entry.payload,
    createdAt: dayjs.utc(entry.createdAt).toISOString(),
  }));
}

/**
 * Create a history entry
 */
export async function createHistoryEntry(
  noteId: string,
  action: 'created' | 'updated' | 'status_changed' | 'commented' | 'returned' | 'priority_changed',
  payload: NoteHistoryPayload,
  authorId: string
) {
  // Day.js Protocol: Backend uses dayjs.utc() for all date operations
  const historyValues = {
    id: crypto.randomUUID(),
    noteId: noteId,
    action: action,
    payload: payload,
    authorId: authorId,
    createdAt: dayjs.utc().toDate(), // Explicitly set server-side UTC time as Date object
  };

  await db.insert(noteHistory).values(historyValues);
}
