import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine, isMainModule } from '@angular/ssr/node';
import express from 'express';
import {
  dirname,
  join,
  resolve
} from 'node:path';
import { fileURLToPath } from 'node:url';
import bootstrap from './main.server';

const serverDistFolder = dirname(fileURLToPath(import.meta.url));
const browserDistFolder = resolve(serverDistFolder, '../browser');
const indexHtml = join(serverDistFolder, 'index.server.html');
const app = express();
const commonEngine = new CommonEngine({
  allowedHosts: [
    'toju.app',
    'www.toju.app',
    'localhost',
    '127.0.0.1'
  ]
});

app.set('trust proxy', 'loopback');

/**
 * Proxy endpoint for Gitea releases API to avoid CORS issues.
 */
app.get('/api/releases', async (_request, response) => {
  try {
    const upstreamResponse = await fetch('https://git.azaaxin.com/api/v1/repos/myxelium/Toju/releases', {
      headers: { Accept: 'application/json' }
    });

    if (!upstreamResponse.ok) {
      response.status(upstreamResponse.status).json({
        error: `Upstream returned ${upstreamResponse.status}`
      });

      return;
    }

    const data = await upstreamResponse.json();

    response.setHeader('Cache-Control', 'public, max-age=300');
    response.json(data);
  } catch (error) {
    console.error('Proxy fetch error:', error);
    response.status(502).json({
      error: 'Failed to fetch releases from upstream'
    });
  }
});

/**
 * Serve static files from /browser.
 */
app.get(
  '**',
  express.static(browserDistFolder, {
    maxAge: '1y',
    index: 'index.html',
    redirect: false
  })
);

/**
 * Handle all other requests by rendering the Angular application.
 */
app.get('**', (request, response, next) => {
  const {
    protocol,
    originalUrl,
    baseUrl,
    headers
  } = request;

  commonEngine
    .render({
      bootstrap,
      documentFilePath: indexHtml,
      url: `${protocol}://${headers.host}${originalUrl}`,
      publicPath: browserDistFolder,
      providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }]
    })
    .then((html) => response.send(html))
    .catch((error) => next(error));
});

/**
 * Start the server if this module is the main entry point.
 */
if (isMainModule(import.meta.url)) {
  const port = process.env['PORT'] || 4000;

  app.listen(port, () => {
    console.log(`Node Express server listening on http://localhost:${port}`);
  });
}

export default app;
