// src/routes/personalization.routes.ts
import { Router, Request, Response, NextFunction } from 'express';
import { z } from 'zod';
import * as db from '../services/db/index.db';
import { validateRequest } from '../middleware/validation.middleware';
import { publicReadLimiter } from '../config/rateLimiters';
import { sendSuccess } from '../utils/apiResponse';
import { optionalNumeric } from '../utils/zodUtils';

const router = Router();

// --- Zod Schemas for Personalization Routes (as per ADR-003) ---
// These routes do not expect any input, so we define an empty schema
// to maintain a consistent validation pattern across the application.
const emptySchema = z.object({});

// Schema for master-items with optional pagination
const masterItemsSchema = z.object({
  query: z.object({
    limit: optionalNumeric({ integer: true, positive: true, max: 500 }),
    offset: optionalNumeric({ default: 0, integer: true, nonnegative: true }),
  }),
});

/**
 * @openapi
 * /personalization/master-items:
 *   get:
 *     tags: [Personalization]
 *     summary: Get master items list
 *     description: Get the master list of all grocery items with optional pagination. Response is cached for 1 hour.
 *     parameters:
 *       - in: query
 *         name: limit
 *         schema:
 *           type: integer
 *           maximum: 500
 *         description: Maximum number of items to return. If omitted, returns all items.
 *       - in: query
 *         name: offset
 *         schema:
 *           type: integer
 *           default: 0
 *         description: Number of items to skip
 *     responses:
 *       200:
 *         description: List of master grocery items with total count
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/SuccessResponse'
 */
router.get(
  '/master-items',
  publicReadLimiter,
  validateRequest(masterItemsSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      // Parse and apply defaults from schema
      const { limit, offset } = masterItemsSchema.shape.query.parse(req.query);

      // LOGGING: Track how often this heavy DB call is actually made vs served from cache
      req.log.info({ limit, offset }, 'Fetching master items list from database...');

      // Optimization: This list changes rarely. Instruct clients to cache it for 1 hour (3600s).
      res.set('Cache-Control', 'public, max-age=3600');

      const result = await db.personalizationRepo.getAllMasterItems(req.log, limit, offset);
      sendSuccess(res, result);
    } catch (error) {
      req.log.error({ error }, 'Error fetching master items in /api/personalization/master-items:');
      next(error);
    }
  },
);

/**
 * @openapi
 * /personalization/dietary-restrictions:
 *   get:
 *     tags: [Personalization]
 *     summary: Get dietary restrictions
 *     description: Get the master list of all available dietary restrictions.
 *     responses:
 *       200:
 *         description: List of all dietary restrictions
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/SuccessResponse'
 */
router.get(
  '/dietary-restrictions',
  publicReadLimiter,
  validateRequest(emptySchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const restrictions = await db.personalizationRepo.getDietaryRestrictions(req.log);
      sendSuccess(res, restrictions);
    } catch (error) {
      req.log.error(
        { error },
        'Error fetching dietary restrictions in /api/personalization/dietary-restrictions:',
      );
      next(error);
    }
  },
);

/**
 * @openapi
 * /personalization/appliances:
 *   get:
 *     tags: [Personalization]
 *     summary: Get kitchen appliances
 *     description: Get the master list of all available kitchen appliances.
 *     responses:
 *       200:
 *         description: List of all kitchen appliances
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/SuccessResponse'
 */
router.get(
  '/appliances',
  publicReadLimiter,
  validateRequest(emptySchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const appliances = await db.personalizationRepo.getAppliances(req.log);
      sendSuccess(res, appliances);
    } catch (error) {
      req.log.error({ error }, 'Error fetching appliances in /api/personalization/appliances:');
      next(error);
    }
  },
);

export default router;
