import { FastifyInstance } from 'fastify';
import { z } from 'zod';
import { withTenant } from '../data/db.js';

const driftReportSchema = z.object({
  stack_name: z.string(),
  stack_fingerprint: z.string(),
  agent_version: z.string(),
  scanned_at: z.string(),
  state_serial: z.number(),
  lineage: z.string(),
  total_resources: z.number(),
  drifted_resources: z.array(z.object({
    resource_type: z.string(),
    resource_address: z.string(),
    module: z.string().optional(),
    provider: z.string(),
    severity: z.enum(['critical', 'high', 'medium', 'low']),
    diffs: z.array(z.object({
      attribute_name: z.string(),
      old_value: z.string(),
      new_value: z.string(),
      sensitive: z.boolean(),
    })),
  })),
  drift_score: z.number(),
  nonce: z.string(),
});

export async function registerProcessorRoutes(app: FastifyInstance) {
  app.post('/v1/ingest/drift', async (request, reply) => {
    const parsed = driftReportSchema.safeParse(request.body);
    if (!parsed.success) {
      return reply.status(400).send({ error: 'Invalid drift report', details: parsed.error.flatten() });
    }

    const report = parsed.data;
    const tenantId = (request as any).tenantId;

    // Nonce replay prevention
    const redis = (app as any).redis;
    const nonceKey = `nonce:${report.nonce}`;
    const exists = await redis.exists(nonceKey);
    if (exists) {
      return reply.status(409).send({ error: 'Nonce already used (replay rejected)' });
    }
    await redis.setex(nonceKey, 86400, '1'); // 24h TTL

    // Persist
    const pool = (app as any).pool;
    await withTenant(pool, tenantId, async (client) => {
      await client.query(
        `INSERT INTO drift_reports (tenant_id, stack_name, stack_fingerprint, agent_version, scanned_at, state_serial, lineage, total_resources, drift_score, nonce, raw_report)
         VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)`,
        [tenantId, report.stack_name, report.stack_fingerprint, report.agent_version, report.scanned_at, report.state_serial, report.lineage, report.total_resources, report.drift_score, report.nonce, JSON.stringify(report)]
      );
    });

    // TODO: Trigger notification if drift_score > threshold
    // TODO: Trigger remediation workflow if auto-remediate enabled

    return reply.status(201).send({ status: 'accepted' });
  });
}
