import type { FastifyInstance } from 'fastify';
import { extractAuth } from '../../lib/auth.js';
import { BadRequestError } from '../../lib/errors.js';
import { CreateIncidentSchema, UpdateIncidentSchema } from './types.js';
import type { IncidentDoc, IncidentUpdate } from './types.js';
import * as repo from './repository.js';
import { checkAllServices } from './health-checker.js';

const DEFAULT_PRODUCT_ID = 'lysnrai';

export async function statusRoutes(app: FastifyInstance) {
  // ── Public endpoints (no auth) ─────────────────────────────

  // Get current platform status (health checks all services)
  app.get('/status', async () => {
    return checkAllServices();
  });

  // Get active incidents
  app.get('/status/incidents', async () => {
    return repo.listActiveIncidents(DEFAULT_PRODUCT_ID);
  });

  // Get incident by ID
  app.get('/status/incidents/:id', async req => {
    const { id } = req.params as { id: string };
    return repo.getIncident(id, DEFAULT_PRODUCT_ID);
  });

  // Get incident history (all incidents, paginated)
  app.get('/status/history', async req => {
    const limit = parseInt((req.query as Record<string, string>).limit || '20', 10);
    return repo.listIncidents(DEFAULT_PRODUCT_ID, Math.min(limit, 100));
  });

  // ── Admin endpoints (auth required) ────────────────────────

  // Create a new incident
  app.post('/status/incidents', async (req, reply) => {
    await extractAuth(req);
    const parsed = CreateIncidentSchema.safeParse(req.body);
    if (!parsed.success) {
      throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; '));
    }

    const now = new Date().toISOString();
    const doc: IncidentDoc = {
      id: `inc_${crypto.randomUUID()}`,
      productId: DEFAULT_PRODUCT_ID,
      title: parsed.data.title,
      severity: parsed.data.severity,
      status: 'investigating',
      affectedServices: parsed.data.affectedServices,
      updates: [
        {
          status: 'investigating',
          message: parsed.data.message,
          createdAt: now,
        },
      ],
      createdAt: now,
      updatedAt: now,
    };

    const created = await repo.createIncident(doc);
    return reply.status(201).send(created);
  });

  // Update an incident (add update, change status/severity)
  app.put('/status/incidents/:id', async req => {
    await extractAuth(req);
    const { id } = req.params as { id: string };
    const parsed = UpdateIncidentSchema.safeParse(req.body);
    if (!parsed.success) {
      throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; '));
    }

    const existing = await repo.getIncident(id, DEFAULT_PRODUCT_ID);
    const now = new Date().toISOString();
    const updates = parsed.data;

    // Add new update entry if message provided
    const newUpdates: IncidentUpdate[] = [...existing.updates];
    if (updates.message) {
      newUpdates.push({
        status: updates.status || existing.status,
        message: updates.message,
        createdAt: now,
      });
    }

    const updated: IncidentDoc = {
      ...existing,
      status: updates.status || existing.status,
      severity: updates.severity || existing.severity,
      updates: newUpdates,
      updatedAt: now,
      resolvedAt: updates.status === 'resolved' ? now : existing.resolvedAt,
    };

    return repo.updateIncident(updated);
  });
}
