import * as http from 'http';
import { NativeConnection, Worker } from '@temporalio/worker';
import * as activities from './activities';
import { config } from './config';
import { startOutboxPoller } from './outbox-poller';

// 顶层状态：health server 与 shutdown handler 共享
let isReady = false;
let isShuttingDown = false;

async function run() {
  console.log(`[Worker] Connecting to Temporal at ${config.temporal.address}...`);

  const connection = await NativeConnection.connect({
    address: config.temporal.address,
  });

  const worker = await Worker.create({
    connection,
    namespace: config.temporal.namespace,
    taskQueue: config.temporal.taskQueue,
    workflowsPath: require.resolve('./workflows/dsl-workflow'),
    activities,
  });

  console.log(`[Worker] Started. Polling task queue: ${config.temporal.taskQueue}`);
  console.log(`[Worker] Namespace: ${config.temporal.namespace}`);

  // event_trigger workflow 的 outbox poller
  const outboxPoller = await startOutboxPoller();

  // K8s probe 用的 HTTP health server
  const healthServer = startHealthServer();

  // 优雅关闭协调器
  const shutdown = async (signal: string) => {
    if (isShuttingDown) return;
    isShuttingDown = true;
    console.log(`[Worker] ${signal} received, beginning graceful shutdown...`);

    // 1. worker.shutdown() 是同步调用，触发 worker.run() 在当前 activity/workflow 完成后 resolve
    worker.shutdown();
    console.log('[Worker] worker.shutdown() called, draining in-flight tasks');

    // 2. 停止 outbox poller，释放其 PG / Temporal client 连接
    try {
      await outboxPoller.stop();
    } catch (err) {
      console.error('[Worker] OutboxPoller stop error:', err);
    }

    // 3. 关闭 health server（停止 K8s probe 请求）
    await new Promise<void>((resolve) => healthServer.close(() => resolve()));
    console.log('[Worker] Health server closed');
  };

  process.on('SIGTERM', () => void shutdown('SIGTERM'));
  process.on('SIGINT', () => void shutdown('SIGINT'));

  isReady = true;

  // worker.run() 会一直阻塞到 worker.shutdown() 被调用并且 in-flight 任务全部 drain
  await worker.run();

  // worker.run() resolve 之后再关闭 NativeConnection（worker 仍在用它的时候不能关）
  await connection.close();
  console.log('[Worker] Temporal connection closed. Bye.');
}

/**
 * 最简 HTTP health 端点，用于 K8s liveness/readiness probe。
 * - /health/live  — 进程存活就返回 200
 * - /health/ready — 处于运行中且未进入 shutdown 才返回 200，否则 503
 */
function startHealthServer(): http.Server {
  const port = Number(process.env.WORKER_HEALTH_PORT) || 8081;
  const server = http.createServer((req, res) => {
    if (req.url === '/health/live') {
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ status: 'ok' }));
      return;
    }
    if (req.url === '/health/ready') {
      const ok = isReady && !isShuttingDown;
      res.writeHead(ok ? 200 : 503, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ status: ok ? 'ok' : 'shutting_down' }));
      return;
    }
    res.writeHead(404);
    res.end();
  });
  server.listen(port, () => {
    console.log(`[Worker] Health server listening on :${port}`);
  });
  return server;
}

run().catch((err) => {
  console.error('[Worker] Fatal error:', err);
  process.exit(1);
});
