// src/routes/system.routes.ts
import { Router, Request, Response, NextFunction } from 'express';
import { logger } from '../services/logger.server';
import { geocodingService } from '../services/geocodingService.server';
import { validateRequest } from '../middleware/validation.middleware';
import { z } from 'zod';
import { requiredString } from '../utils/zodUtils';
import { systemService } from '../services/systemService';

const router = Router();

const geocodeSchema = z.object({
  body: z.object({
    address: requiredString('An address string is required.'),
  }),
});

// An empty schema for routes that do not expect any input, to maintain a consistent validation pattern.
const emptySchema = z.object({});

/**
 * Checks the status of the 'flyer-crawler-api' process managed by PM2.
 * This is intended for development and diagnostic purposes.
 */
router.get(
  '/pm2-status',
  validateRequest(emptySchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const status = await systemService.getPm2Status();
      res.json(status);
    } catch (error) {
      next(error);
    }
  },
);

/**
 * POST /api/system/geocode - Geocodes a given address string.
 * This acts as a secure proxy to the Google Maps Geocoding API.
 */
router.post(
  '/geocode',
  validateRequest(geocodeSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    // Infer type and cast request object as per ADR-003
    type GeocodeRequest = z.infer<typeof geocodeSchema>;
    const {
      body: { address },
    } = req as unknown as GeocodeRequest;

    try {
      const coordinates = await geocodingService.geocodeAddress(address, req.log);

      if (!coordinates) {
        // This check remains, but now it only fails if BOTH services fail.
        return res.status(404).json({ message: 'Could not geocode the provided address.' });
      }

      res.json(coordinates);
    } catch (error) {
      logger.error({ error }, 'Error geocoding address');
      next(error);
    }
  },
);

export default router;
