import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import { z } from 'zod';
import { getCosmosConfig, updateCosmosConfig, deleteCosmosConfig } from './repository.js';
import { reinitializeContainers, getCosmosStatus } from '../../lib/cosmos-init.js';
import { BadRequestError } from '../../lib/auth.js';
import type { UpdateCosmosConfig } from './types.js';

const updateConfigSchema = z.object({
  endpoint: z.string().url(),
  key: z.string().min(1),
  database: z.string().optional(),
});

export async function cosmosConfigRoutes(fastify: FastifyInstance) {
  // Get current Cosmos configuration
  fastify.get('/cosmos-config', async (request: FastifyRequest, reply: FastifyReply) => {
    const config = await getCosmosConfig();
    if (!config) {
      return reply.send({
        configured: false,
        endpoint: null,
        database: null,
      });
    }

    // Don't return the key for security
    return reply.send({
      configured: true,
      endpoint: config.endpoint,
      database: config.database,
      updatedAt: config.updatedAt,
    });
  });

  // Get Cosmos connection status
  fastify.get('/cosmos-status', async (request: FastifyRequest, reply: FastifyReply) => {
    const status = getCosmosStatus();
    return reply.send(status);
  });

  // Update Cosmos configuration
  fastify.post('/cosmos-config', async (request: FastifyRequest, reply: FastifyReply) => {
    try {
      const body = updateConfigSchema.parse(request.body) as UpdateCosmosConfig;

      // Update the configuration
      await updateCosmosConfig(body);

      // Reinitialize Cosmos connection with new credentials
      try {
        await reinitializeContainers(body.endpoint, body.key);
        return reply.send({
          success: true,
          message: 'Cosmos configuration updated and connection established successfully',
        });
      } catch (error: any) {
        return reply.code(400).send({
          success: false,
          message: 'Configuration saved but failed to connect to Cosmos',
          error: error.message,
        });
      }
    } catch (error: any) {
      if (error instanceof z.ZodError) {
        throw new BadRequestError('Invalid request body');
      }
      throw error;
    }
  });

  // Delete Cosmos configuration
  fastify.delete('/cosmos-config', async (request: FastifyRequest, reply: FastifyReply) => {
    await deleteCosmosConfig();
    return reply.send({
      success: true,
      message: 'Cosmos configuration deleted',
    });
  });

  // Test Cosmos connection
  fastify.post('/cosmos-test', async (request: FastifyRequest, reply: FastifyReply) => {
    const schema = z.object({
      endpoint: z.string().url(),
      key: z.string().min(1),
    });

    try {
      const body = schema.parse(request.body);

      // Try to initialize with the provided credentials
      try {
        await reinitializeContainers(body.endpoint, body.key);
        return reply.send({
          success: true,
          message: 'Successfully connected to Cosmos',
        });
      } catch (error: any) {
        return reply.code(400).send({
          success: false,
          message: 'Failed to connect to Cosmos',
          error: error.message,
        });
      }
    } catch (error: any) {
      if (error instanceof z.ZodError) {
        throw new BadRequestError('Invalid request body');
      }
      throw error;
    }
  });
}
