import { FastifyPluginAsync, FastifyRequest, FastifyReply } from 'fastify';
import { CanvasApiEndpointController } from '../http/controllers/CanvasApiEndpointController';
import axios, { Method } from 'axios';

const ALLOWED_METHODS: Method[] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'];

// Type for proxy request input
interface CanvasProxyRequestInput {
    path: string;
    method?: Method;
    params?: any;
}

interface CreateEndpointBody {
    name: string;
    method: string;
    path: string;
    description?: string;
    user?: any;
}

interface UpdateEndpointBody {
    name?: string;
    method?: string;
    path?: string;
    description?: string;
}

const endpointsRoutes: FastifyPluginAsync = async (app) => {
    const controller = new CanvasApiEndpointController();

    app.get('/endpoints', async (request: FastifyRequest, reply: FastifyReply) => {
        return controller.getAll(request, reply);
    });

    app.post('/endpoints', async (request: FastifyRequest<{ Body: CreateEndpointBody }>, reply: FastifyReply) => {
        return controller.create(request, reply);
    });

    app.delete('/endpoints/:id', async (request: FastifyRequest<{ Params: { id: string } }>, reply: FastifyReply) => {
        return controller.delete(request, reply);
    });

    app.put('/endpoints/:id', async (request: FastifyRequest<{ Params: { id: string }; Body: UpdateEndpointBody }>, reply: FastifyReply) => {
        return controller.update(request, reply);
    });

    // Dynamic proxy route for external Canvas REST API
    app.post('/proxy-external', async (request: FastifyRequest<{ Body: CanvasProxyRequestInput }>, reply: FastifyReply) => {
        try {
            let baseUrl = process.env.CANVAS_API_URL || 'https://talnet.instructure.com';
            // Remove trailing /api/v1 if present
            baseUrl = baseUrl.replace(/\/api\/v1$/, '');
            // Always use the server's Canvas API key for Canvas requests
            const apiKey = process.env.CANVAS_API_KEY || '';
            const { path, method = 'GET', params } = request.body;
            if (!path) return reply.status(400).send({ error: 'Missing path' });
            if (!ALLOWED_METHODS.includes(method as Method)) {
                return reply.status(405).send({ error: `Method ${method} not allowed` });
            }
            const url = `${baseUrl}/api/v1${path}`;
            console.log('Proxying to Canvas:', { url, method, apiKey, params });
            const response = await axios.request({
                url,
                method,
                headers: { Authorization: `Bearer ${apiKey}` },
                params: method === 'GET' ? params : undefined,
                data: method !== 'GET' ? params : undefined,
            });
            console.log('Canvas response:', response.data);
            return reply.send(response.data);
        } catch (err) {
            console.error('Proxy error:', err);
            return reply.status(500).send({ error: err.message, details: err.response?.data || err });
        }
    });
};

export default endpointsRoutes; 