/**
 * Document Collaboration Routes
 * Comments, annotations, and review features
 */

import { FastifyInstance } from 'fastify';
import {
  createDocumentComment,
  getDocumentComments,
  getThreadedDocumentComments,
  updateDocumentComment,
  resolveDocumentComment,
  getDocumentCommentStatistics,
} from '@the-order/database';
import { authenticateJWT, requireRole } from '@the-order/shared';
import { createDocumentAuditLog } from '@the-order/database';

export async function registerCollaborationRoutes(server: FastifyInstance): Promise<void> {
  // Create comment
  server.post(
    '/documents/:id/comments',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        body: {
          type: 'object',
          required: ['comment_text'],
          properties: {
            version_id: { type: 'string' },
            parent_comment_id: { type: 'string' },
            comment_text: { type: 'string' },
            comment_type: { type: 'string', enum: ['comment', 'suggestion', 'question', 'resolution'] },
            page_number: { type: 'number' },
            x_position: { type: 'number' },
            y_position: { type: 'number' },
            highlight_text: { type: 'string' },
          },
        },
        tags: ['collaboration'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const body = request.body as any;
      const user = (request as any).user;

      const comment = await createDocumentComment({
        document_id: id,
        ...body,
        author_id: user.id,
      });

      await createDocumentAuditLog({
        document_id: id,
        version_id: body.version_id,
        action: 'commented',
        performed_by: user.id,
      });

      return reply.code(201).send(comment);
    }
  );

  // Get comments for document
  server.get(
    '/documents/:id/comments',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        querystring: {
          type: 'object',
          properties: {
            version_id: { type: 'string' },
            include_resolved: { type: 'boolean' },
            threaded: { type: 'boolean' },
          },
        },
        tags: ['collaboration'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const query = request.query as {
        version_id?: string;
        include_resolved?: boolean;
        threaded?: boolean;
      };

      if (query.threaded) {
        const comments = await getThreadedDocumentComments(id, query.version_id);
        return reply.send({ comments });
      } else {
        const comments = await getDocumentComments(
          id,
          query.version_id,
          query.include_resolved || false
        );
        return reply.send({ comments });
      }
    }
  );

  // Update comment
  server.patch(
    '/comments/:id',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        body: {
          type: 'object',
          properties: {
            comment_text: { type: 'string' },
            status: { type: 'string', enum: ['open', 'resolved', 'dismissed'] },
          },
        },
        tags: ['collaboration'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const body = request.body as any;
      const comment = await updateDocumentComment(id, body);
      if (!comment) {
        return reply.code(404).send({ error: 'Comment not found' });
      }
      return reply.send(comment);
    }
  );

  // Resolve comment
  server.post(
    '/comments/:id/resolve',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        tags: ['collaboration'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const user = (request as any).user;
      const comment = await resolveDocumentComment(id, user.id);
      if (!comment) {
        return reply.code(404).send({ error: 'Comment not found' });
      }
      return reply.send(comment);
    }
  );

  // Get comment statistics
  server.get(
    '/documents/:id/comments/statistics',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        tags: ['collaboration'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const stats = await getDocumentCommentStatistics(id);
      return reply.send(stats);
    }
  );
}

