import { type VercelRequest, type VercelResponse } from '@vercel/node';
import axios from 'axios';

import { resolveSession } from '../auth/_lib.js';

const POSTGREST_BASE_URL = process.env.POSTGREST_BASE_URL!;

function validatePath(path: string): boolean {
  if (path === '') return true;
  return !path.includes('..') && /^[a-zA-Z0-9\-_./@]+$/.test(path);
}

export default async function handler(req: VercelRequest, res: VercelResponse) {
  if (!POSTGREST_BASE_URL) {
    return res.status(503).json({
      error:
        'PostgREST proxy configuration error — check your environment variables',
    });
  }

  if (req.method !== 'GET') {
    return res.status(405).json({ error: 'Only GET requests are supported' });
  }

  const session = await resolveSession(req);
  if (!session) {
    return res.status(401).json({ error: 'Unauthenticated' });
  }

  if (session.renewedCookies) {
    res.setHeader('Set-Cookie', session.renewedCookies);
  }

  const segments = (req.query.path ?? req.query['...path']) as
    | string
    | string[]
    | undefined;
  const apiPath = Array.isArray(segments)
    ? segments.join('/')
    : (segments ?? '');

  if (!validatePath(apiPath)) {
    return res.status(400).json({ error: 'Invalid path' });
  }

  const targetUrl = new URL(`${POSTGREST_BASE_URL}/${apiPath}`);
  for (const [key, value] of Object.entries(req.query)) {
    if (key === 'path' || key === '...path') continue;
    if (value !== undefined) {
      targetUrl.searchParams.set(key, Array.isArray(value) ? value[0] : value);
    }
  }

  const forwardHeaders: Record<string, string> = {
    Authorization: `Bearer ${session.accessToken}`,
  };
  const clientAccept = req.headers['accept'];
  if (clientAccept) {
    forwardHeaders['Accept'] = Array.isArray(clientAccept)
      ? clientAccept[0]
      : clientAccept;
  }

  try {
    const upstream = await axios.get(targetUrl.toString(), {
      headers: forwardHeaders,
      validateStatus: () => true,
    });

    const contentRange = upstream.headers['content-range'];
    if (contentRange) res.setHeader('Content-Range', contentRange);
    res.setHeader(
      'Content-Type',
      upstream.headers['content-type'] || 'application/json',
    );
    return res
      .status(upstream.status)
      .send(
        typeof upstream.data === 'string'
          ? upstream.data
          : JSON.stringify(upstream.data),
      );
  } catch (error) {
    console.error('[postgrest proxy]', (error as Error).message);
    return res.status(502).json({ error: 'Unable to reach PostgREST service' });
  }
}
