import { Router, Request, Response } from 'express';
import { omnlRateLimiter } from '../middleware/rate-limit';
import { omnlRequireApiKeyInProduction } from '../middleware/omnl-guards';
import { omnlAuditMiddleware } from '../middleware/omnl-audit-middleware';
import {
  createJournalEntry,
  postJournalEntry,
  reverseJournalEntry,
  getJournalEntry,
  createBalanceReservation,
  releaseBalanceReservation,
  getBalanceReservation,
} from '../../services/omnl-payout-journal';

const router = Router();
router.use(omnlRateLimiter);
router.use(omnlAuditMiddleware);
router.use(omnlRequireApiKeyInProduction);

function routeParam(value: string | string[] | undefined): string {
  if (Array.isArray(value)) return value[0] ?? '';
  return value ?? '';
}

/**
 * POST /journal-entries — payout orchestrator integration (CR-004).
 */
router.post('/journal-entries', (req: Request, res: Response) => {
  try {
    const record = createJournalEntry(req.body ?? {});
    res.status(201).json(record);
  } catch (e) {
    const msg = e instanceof Error ? e.message : String(e);
    res.status(msg.includes('invalid') ? 422 : 400).json({ error: msg });
  }
});

router.get('/journal-entries/:id', (req: Request, res: Response) => {
  const record = getJournalEntry(routeParam(req.params.id));
  if (!record) {
    res.status(404).json({ error: 'not found' });
    return;
  }
  res.json(record);
});

router.post('/journal-entries/:id/post', (req: Request, res: Response) => {
  try {
    res.json(postJournalEntry(routeParam(req.params.id)));
  } catch (e) {
    const msg = e instanceof Error ? e.message : String(e);
    res.status(msg.includes('not found') ? 404 : 422).json({ error: msg });
  }
});

router.post('/journal-entries/:id/reverse', (req: Request, res: Response) => {
  try {
    res.json(reverseJournalEntry(routeParam(req.params.id)));
  } catch (e) {
    const msg = e instanceof Error ? e.message : String(e);
    res.status(msg.includes('not found') ? 404 : 422).json({ error: msg });
  }
});

/**
 * POST /balance-reservations — reserve funds before payout dispatch.
 */
router.post('/balance-reservations', (req: Request, res: Response) => {
  try {
    const body = req.body ?? {};
    if (!body.instructionId || body.amount == null || !body.currency) {
      res.status(400).json({ error: 'instructionId, amount, currency required' });
      return;
    }
    const record = createBalanceReservation(body);
    res.status(201).json(record);
  } catch (e) {
    const msg = e instanceof Error ? e.message : String(e);
    res.status(400).json({ error: msg });
  }
});

router.get('/balance-reservations/:id', (req: Request, res: Response) => {
  const record = getBalanceReservation(routeParam(req.params.id));
  if (!record) {
    res.status(404).json({ error: 'not found' });
    return;
  }
  res.json(record);
});

router.delete('/balance-reservations/:id', (req: Request, res: Response) => {
  try {
    res.json(releaseBalanceReservation(routeParam(req.params.id)));
  } catch (e) {
    const msg = e instanceof Error ? e.message : String(e);
    res.status(msg.includes('not found') ? 404 : 422).json({ error: msg });
  }
});

export default router;
