'use server';

import { auth } from '@clerk/nextjs/server';
import { Metadata, credentials } from '@grpc/grpc-js';
import * as grpc from '@grpc/grpc-js';

import {
  GenerateResponse,
  GenerateServerStreamRequest,
  StudioApiGrpcServiceClient,
} from '../proto_gen/generate';

const client = new StudioApiGrpcServiceClient(
  'localhost:50051',
  credentials.createInsecure()
);

async function getAuthToken() {
  const { userId, getToken } = await auth();
  if (userId) {
    return await getToken();
  }
  return null;
}

// API route handler in Next.js
export default async function grpcHandler(params: any) {
  // Get Clerk authentication information
  const token = await getAuthToken();

  if (!token) {
    return { error: 'Unauthorized' };
  }

  // Create metadata and add Bearer token
  const metadata = new grpc.Metadata();
  metadata.add('authorization', `Bearer ${token}`);
  const request = GenerateServerStreamRequest.create(params);

  // Function to make gRPC request with metadata and return a Promise
  const generateAsync = (
    request: GenerateServerStreamRequest,
    metadata: Metadata
  ) => {
    return new Promise<{
      data?: { messages: string[] };
      error?: string;
    }>((resolve) => {
      const call = client.generateClipServerStream(request, metadata);
      const messages: string[] = [];

      call.on('data', (response: GenerateResponse) => {
        messages.push(response.message);
      });

      call.on('end', () => {
        resolve({ data: { messages } });
      });

      call.on('error', (error: Error) => {
        resolve({ error: error.message });
      });
    });
  };

  // Await the gRPC request
  return await generateAsync(request, metadata);
}
