import type { FastifyInstance } from 'fastify';
import { BadRequestError, ForbiddenError, UnauthorizedError } from '../../lib/errors.js';
import { CreateExportSchema } from './types.js';
import type { ExportJobDoc } from './types.js';
import * as repo from './repository.js';

const DEFAULT_PRODUCT_ID = 'lysnrai';

export async function exportRoutes(app: FastifyInstance) {
  function requireAdmin(req: import('fastify').FastifyRequest): string {
    const role = req.jwtPayload?.role;
    if (!role || !['super_admin', 'admin'].includes(role)) {
      throw new ForbiddenError('Admin access required');
    }
    const sub = req.jwtPayload?.sub;
    if (!sub) throw new UnauthorizedError('Missing sub in token');
    return sub;
  }

  // Start a new export job
  app.post('/exports', async (req, reply) => {
    const adminId = requireAdmin(req);
    const parsed = CreateExportSchema.safeParse(req.body);
    if (!parsed.success) {
      throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; '));
    }

    const now = new Date().toISOString();
    const expiresAt = new Date(Date.now() + 7 * 86400000).toISOString(); // 7 days

    const job: ExportJobDoc = {
      id: `exp_${crypto.randomUUID()}`,
      productId: DEFAULT_PRODUCT_ID,
      type: parsed.data.type,
      format: parsed.data.format,
      filters: parsed.data.filters,
      status: 'pending',
      requestedBy: adminId,
      expiresAt,
      createdAt: now,
    };

    const created = await repo.createExportJob(job);

    // TODO: Queue actual export processing via jobs module.
    // For now, mark as processing to indicate the job is accepted.
    req.log.info(
      { exportId: created.id, type: created.type, format: created.format },
      '[exports] Export job created'
    );

    return reply.status(201).send(created);
  });

  // List export jobs
  app.get('/exports', async req => {
    requireAdmin(req);
    const query = req.query as Record<string, string>;
    const limit = query.limit ? parseInt(query.limit, 10) : 20;
    const jobs = await repo.listExportJobs(DEFAULT_PRODUCT_ID, Math.min(limit, 100));
    return { exports: jobs, count: jobs.length };
  });

  // Get a specific export job
  app.get('/exports/:id', async req => {
    requireAdmin(req);
    const { id } = req.params as { id: string };
    const job = await repo.getExportJob(id, DEFAULT_PRODUCT_ID);
    if (!job) throw new BadRequestError('Export job not found');
    return job;
  });
}
