/**
 * Legal Matter Routes
 * Matter management and matter-document relationships
 */

import { FastifyInstance } from 'fastify';
import {
  createLegalMatter,
  getLegalMatter,
  getLegalMatterByNumber,
  listLegalMatters,
  updateLegalMatter,
  addMatterParticipant,
  getMatterParticipants,
  linkDocumentToMatter,
  getMatterDocuments,
  getDocumentMatters,
} from '@the-order/database';
import { authenticateJWT, requireRole } from '@the-order/shared';
import { createDocumentAuditLog } from '@the-order/database';

export async function registerMatterRoutes(server: FastifyInstance): Promise<void> {
  // Create matter
  server.post(
    '/matters',
    {
      preHandler: [authenticateJWT, requireRole('admin', 'attorney')],
      schema: {
        body: {
          type: 'object',
          required: ['matter_number', 'title'],
          properties: {
            matter_number: { type: 'string' },
            title: { type: 'string' },
            description: { type: 'string' },
            matter_type: { type: 'string' },
            status: { type: 'string' },
            priority: { type: 'string' },
            client_id: { type: 'string' },
            responsible_attorney_id: { type: 'string' },
            practice_area: { type: 'string' },
            jurisdiction: { type: 'string' },
            court_name: { type: 'string' },
            case_number: { type: 'string' },
            opened_date: { type: 'string' },
            billing_code: { type: 'string' },
            metadata: { type: 'object' },
          },
        },
        tags: ['matters'],
      },
    },
    async (request, reply) => {
      const body = request.body as any;
      const user = (request as any).user;

      const matter = await createLegalMatter({
        ...body,
        created_by: user?.id,
      });

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

  // Get matter by ID
  server.get(
    '/matters/:id',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        tags: ['matters'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const matter = await getLegalMatter(id);
      if (!matter) {
        return reply.code(404).send({ error: 'Matter not found' });
      }
      return reply.send(matter);
    }
  );

  // Get matter by number
  server.get(
    '/matters/number/:number',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            number: { type: 'string' },
          },
        },
        tags: ['matters'],
      },
    },
    async (request, reply) => {
      const { number } = request.params as { number: string };
      const matter = await getLegalMatterByNumber(number);
      if (!matter) {
        return reply.code(404).send({ error: 'Matter not found' });
      }
      return reply.send(matter);
    }
  );

  // List matters
  server.get(
    '/matters',
    {
      preHandler: [authenticateJWT],
      schema: {
        querystring: {
          type: 'object',
          properties: {
            status: { type: 'string' },
            matter_type: { type: 'string' },
            client_id: { type: 'string' },
            responsible_attorney_id: { type: 'string' },
            practice_area: { type: 'string' },
            search: { type: 'string' },
            limit: { type: 'number' },
            offset: { type: 'number' },
          },
        },
        tags: ['matters'],
      },
    },
    async (request, reply) => {
      const query = request.query as any;
      const matters = await listLegalMatters(
        {
          status: query.status,
          matter_type: query.matter_type,
          client_id: query.client_id,
          responsible_attorney_id: query.responsible_attorney_id,
          practice_area: query.practice_area,
          search: query.search,
        },
        query.limit || 100,
        query.offset || 0
      );
      return reply.send({ matters, total: matters.length });
    }
  );

  // Update matter
  server.patch(
    '/matters/:id',
    {
      preHandler: [authenticateJWT, requireRole('admin', 'attorney')],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        body: {
          type: 'object',
          properties: {
            title: { type: 'string' },
            description: { type: 'string' },
            status: { type: 'string' },
            priority: { type: 'string' },
            responsible_attorney_id: { type: 'string' },
            closed_date: { type: 'string' },
          },
        },
        tags: ['matters'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const body = request.body as any;
      const matter = await updateLegalMatter(id, body);
      if (!matter) {
        return reply.code(404).send({ error: 'Matter not found' });
      }
      return reply.send(matter);
    }
  );

  // Add participant to matter
  server.post(
    '/matters/:id/participants',
    {
      preHandler: [authenticateJWT, requireRole('admin', 'attorney')],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        body: {
          type: 'object',
          required: ['role'],
          properties: {
            user_id: { type: 'string' },
            role: { type: 'string' },
            organization_name: { type: 'string' },
            email: { type: 'string' },
            phone: { type: 'string' },
            is_primary: { type: 'boolean' },
            access_level: { type: 'string' },
            notes: { type: 'string' },
          },
        },
        tags: ['matters'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const body = request.body as any;
      const participant = await addMatterParticipant(id, body);
      return reply.code(201).send(participant);
    }
  );

  // Get matter participants
  server.get(
    '/matters/:id/participants',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        tags: ['matters'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const participants = await getMatterParticipants(id);
      return reply.send({ participants });
    }
  );

  // Link document to matter
  server.post(
    '/matters/:matter_id/documents/:document_id',
    {
      preHandler: [authenticateJWT, requireRole('admin', 'attorney', 'legal_staff')],
      schema: {
        params: {
          type: 'object',
          properties: {
            matter_id: { type: 'string' },
            document_id: { type: 'string' },
          },
        },
        body: {
          type: 'object',
          required: ['relationship_type'],
          properties: {
            relationship_type: { type: 'string' },
            folder_path: { type: 'string' },
            is_primary: { type: 'boolean' },
            display_order: { type: 'number' },
            notes: { type: 'string' },
          },
        },
        tags: ['matters'],
      },
    },
    async (request, reply) => {
      const { matter_id, document_id } = request.params as {
        matter_id: string;
        document_id: string;
      };
      const body = request.body as any;
      const user = (request as any).user;

      const link = await linkDocumentToMatter(matter_id, document_id, body.relationship_type, {
        folder_path: body.folder_path,
        is_primary: body.is_primary,
        display_order: body.display_order,
        notes: body.notes,
      });

      await createDocumentAuditLog({
        document_id,
        matter_id,
        action: 'linked_to_matter',
        performed_by: user?.id,
      });

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

  // Get matter documents
  server.get(
    '/matters/:id/documents',
    {
      preHandler: [authenticateJWT],
      schema: {
        params: {
          type: 'object',
          properties: {
            id: { type: 'string' },
          },
        },
        querystring: {
          type: 'object',
          properties: {
            relationship_type: { type: 'string' },
          },
        },
        tags: ['matters'],
      },
    },
    async (request, reply) => {
      const { id } = request.params as { id: string };
      const { relationship_type } = request.query as { relationship_type?: string };
      const documents = await getMatterDocuments(id, relationship_type);
      return reply.send({ documents });
    }
  );

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

