/**
 * Document Version Routes
 * Version management and revision history
 */

import { FastifyInstance } from 'fastify';
import {
  getDocumentVersions,
  getDocumentVersionByNumber,
  getLatestDocumentVersion,
  compareDocumentVersions,
  restoreDocumentVersion,
  getDocumentVersionHistory,
} from '@the-order/database';
import { authenticateJWT, requireRole } from '@the-order/shared';
import { createDocumentAuditLog } from '@the-order/database';

export async function registerVersionRoutes(server: FastifyInstance): Promise<void> {
  // Get all versions for a document
  server.get(
    '/documents/:id/versions',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        tags: ['versions'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const versions = await getDocumentVersions(id);
      return reply.send({ versions });
    }
  );

  // Get specific version
  server.get(
    '/documents/:id/versions/:version',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
            version: { type: 'number' },
          },
        },
        tags: ['versions'],
      },
    },
    async (request, reply) => {
      const { id, version } = request.params as { id: string; version: string };
      const versionNumber = parseInt(version, 10);

      const docVersion = await getDocumentVersionByNumber(id, versionNumber);
      if (!docVersion) {
        return reply.code(404).send({ error: 'Version not found' });
      }

      return reply.send(docVersion);
    }
  );

  // Get latest version
  server.get(
    '/documents/:id/versions/latest',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        tags: ['versions'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const version = await getLatestDocumentVersion(id);
      if (!version) {
        return reply.code(404).send({ error: 'No versions found' });
      }
      return reply.send(version);
    }
  );

  // Get version history with user info
  server.get(
    '/documents/:id/versions/history',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        tags: ['versions'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const history = await getDocumentVersionHistory(id);
      return reply.send({ history });
    }
  );

  // Compare two versions
  server.get(
    '/documents/:id/versions/:v1/compare/:v2',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
            v1: { type: 'string' },
            v2: { type: 'string' },
          },
        },
        tags: ['versions'],
      },
    },
    async (request, reply) => {
      const { id, v1, v2 } = request.params as { id: string; v1: string; v2: string };

      const version1 = await getDocumentVersionByNumber(id, parseInt(v1, 10));
      const version2 = await getDocumentVersionByNumber(id, parseInt(v2, 10));

      if (!version1 || !version2) {
        return reply.code(404).send({ error: 'One or both versions not found' });
      }

      const comparison = await compareDocumentVersions(version1.id, version2.id);
      return reply.send(comparison);
    }
  );

  // Restore document to a previous version
  server.post(
    '/documents/:id/versions/:version/restore',
    {
      preHandler: [authenticateJWT, requireRole('admin', 'attorney')],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
            version: { type: 'number' },
          },
        },
        body: {
          type: 'object',
          properties: {
            change_summary: { type: 'string' },
          },
        },
        tags: ['versions'],
      },
    },
    async (request, reply) => {
      const { id, version } = request.params as { id: string; version: string };
      const body = request.body as { change_summary?: string };
      const user = (request as any).user;

      const targetVersion = await getDocumentVersionByNumber(id, parseInt(version, 10));
      if (!targetVersion) {
        return reply.code(404).send({ error: 'Version not found' });
      }

      const restoredVersion = await restoreDocumentVersion(
        id,
        targetVersion.id,
        user.id,
        body.change_summary
      );

      await createDocumentAuditLog({
        document_id: id,
        version_id: restoredVersion.id,
        action: 'version_restored',
        performed_by: user.id,
        details: { restored_from_version: targetVersion.version_number },
      });

      return reply.send(restoredVersion);
    }
  );
}

