import Fastify from 'fastify';
import cors from '@fastify/cors';
import cookie from '@fastify/cookie';
import formbody from '@fastify/formbody';
import fastifyStatic from '@fastify/static';
import { existsSync } from 'node:fs';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { config } from './config.js';
import { getDb } from './db/index.js';
import { authRoutes } from './routes/auth.js';
import { adminRoutes } from './routes/admin.js';
import { majWpRoutes } from './routes/maj-wp.js';
import { extensionRoutes } from './routes/extension.js';
import { sourceRoutes } from './routes/sources.js';
import { startGmailPoller, gmailService } from './services/gmail.service.js';
import { startMondayPoller, mondayService } from './services/monday.service.js';

const __dirname = dirname(fileURLToPath(import.meta.url));

export async function buildApp() {
  const app = Fastify({
    logger: config.isDev,
    bodyLimit: config.maxPayloadBytes,
    trustProxy: config.trustProxy,
  });

  await app.register(cors, {
    origin: (origin, cb) => {
      if (!origin) return cb(null, true);
      const allowed = config.corsOrigins.some(
        (o) => origin === o || (o.endsWith('://') && origin.startsWith(o)),
      );
      if (allowed) cb(null, true);
      else if (config.isDev) cb(null, true);
      else cb(new Error('CORS blocked'), false);
    },
    credentials: true,
  });

  await app.register(cookie);
  await app.register(formbody);

  // API routes first — always take priority over static
  await app.register(authRoutes);
  await app.register(adminRoutes);
  await app.register(majWpRoutes);
  await app.register(extensionRoutes);
  await app.register(sourceRoutes);

  app.get('/api/health', async (_req, reply) => {
    let dbOk = false;
    try {
      getDb().prepare('SELECT 1 AS ok').get();
      dbOk = true;
    } catch {
      return reply.code(503).send({ status: 'error', database: false });
    }
    return {
      status: 'ok',
      version: '1.0.0',
      database: dbOk,
      gmail: { configured: config.gmail.enabled(), connected: gmailService.getStatus().connected },
      monday: { configured: config.monday.enabled() },
    };
  });

  const webDist = resolve(__dirname, '../../web/dist');
  if (existsSync(webDist)) {
    await app.register(fastifyStatic, {
      root: webDist,
      prefix: '/',
      wildcard: false,
    });

    app.setNotFoundHandler((request, reply) => {
      const url = request.url.split('?')[0] ?? '';
      if (url.startsWith('/api/')) {
        reply.code(404).send({ error: 'not_found' });
        return;
      }
      reply.sendFile('index.html');
    });
  } else if (config.isProduction) {
    throw new Error('Production requires web/dist — run npm run build first');
  }

  return app;
}

export async function startBackgroundJobs(): Promise<void> {
  if (config.instanceCount !== 1) {
    console.warn('[startup] Background pollers skipped — INSTANCE_COUNT != 1');
    return;
  }
  startGmailPoller();
  startMondayPoller();
}
