import type { FastifyInstance } from 'fastify';
import {
  listHandler, statsHandler, nextNoHandler, getHandler, createHandler,
  updateHandler, deleteHandler, stageHandler, dispatchHandler, cancelHandler,
  getCommentsHandler, addCommentHandler, getDispatchHistoryHandler, editDispatchHistoryHandler, revertDispatchHistoryHandler,
  getTimelineHandler, joNoHandler,
} from '../controllers/order.controller.js';
import { authorize, authorizeAny } from '../plugins/authorize.js';
import { PERMISSIONS } from '../constants/permissions.js';
import { createOrderSchema, updateOrderSchema, updateStageSchema, dispatchSchema, cancelSchema, addCommentSchema, updateJoNoSchema } from '../schemas/order.schema.js';

// The Reports page's "Order No" filter needs to browse the order list to
// pick from, so Reports-View also unlocks this browse endpoint. An employee
// restricted to ORDERS_STAGE_UPDATE alone also needs to browse orders to
// see (and act on) the lines their stage assignments actually apply to —
// without it, the Orders page and dashboard drill-downs come back empty
// for them even though they're allowed to move stages.
const CAN_BROWSE_ORDERS = [PERMISSIONS.ORDERS_VIEW, PERMISSIONS.REPORTS_VIEW, PERMISSIONS.ORDERS_STAGE_UPDATE];

// Stage-change is a narrower action than full order editing — an employee
// with only ORDERS_STAGE_UPDATE (not ORDERS_EDIT) can move products through
// production but can't touch the rest of the order.
const CAN_UPDATE_STAGE = [PERMISSIONS.ORDERS_EDIT, PERMISSIONS.ORDERS_STAGE_UPDATE];

// Dispatch used to ride on CAN_UPDATE_STAGE too, which meant anyone allowed
// to move a line through production stages could also dispatch it, with no
// way to grant one without the other — split out so an admin can hand out
// stage-move access without automatically handing out dispatch, and vice
// versa.
const CAN_DISPATCH = [PERMISSIONS.ORDERS_EDIT, PERMISSIONS.ORDERS_DISPATCH];

// Same split-out-from-ORDERS_EDIT pattern as stage-move/dispatch above — an
// employee can be handed just JO-number correction rights without also
// getting full order editing.
const CAN_EDIT_JO_NO = [PERMISSIONS.ORDERS_EDIT, PERMISSIONS.ORDERS_JO_NO_EDIT];

export default async function orderRoutes(fastify: FastifyInstance) {
  fastify.get('/api/orders', { preHandler: [authorizeAny(CAN_BROWSE_ORDERS)] }, listHandler);
  fastify.get('/api/orders/stats', { preHandler: [authorize(PERMISSIONS.ORDERS_VIEW)] }, statsHandler);
  fastify.get('/api/orders/next-no', { preHandler: [authorize(PERMISSIONS.ORDERS_VIEW)] }, nextNoHandler);
  fastify.get('/api/orders/:id', { preHandler: [authorize(PERMISSIONS.ORDERS_VIEW)] }, getHandler);
  fastify.post('/api/orders', { preHandler: [authorize(PERMISSIONS.ORDERS_CREATE)], schema: createOrderSchema }, createHandler);
  fastify.put('/api/orders/:id', { preHandler: [authorize(PERMISSIONS.ORDERS_EDIT)], schema: updateOrderSchema }, updateHandler);
  fastify.delete('/api/orders/:id', { preHandler: [authorize(PERMISSIONS.ORDERS_DELETE)] }, deleteHandler);
  fastify.patch('/api/orders/:id/products/:productId/stage', { preHandler: [authorizeAny(CAN_UPDATE_STAGE)], schema: updateStageSchema }, stageHandler);
  fastify.patch('/api/orders/:id/products/:productId/jo-no', { preHandler: [authorizeAny(CAN_EDIT_JO_NO)], schema: updateJoNoSchema }, joNoHandler);
  fastify.post('/api/orders/:id/dispatch', { preHandler: [authorizeAny(CAN_DISPATCH)], schema: dispatchSchema }, dispatchHandler);
  fastify.post('/api/orders/:id/cancel', { preHandler: [authorize(PERMISSIONS.ORDERS_EDIT)], schema: cancelSchema }, cancelHandler);
  fastify.get('/api/orders/:id/comments', { preHandler: [authorize(PERMISSIONS.ORDERS_VIEW)] }, getCommentsHandler);
  fastify.post('/api/orders/:id/comments', { preHandler: [authorize(PERMISSIONS.ORDERS_EDIT)], schema: addCommentSchema }, addCommentHandler);
  fastify.get('/api/orders/:id/products/:productId/dispatch-history', { preHandler: [authorize(PERMISSIONS.ORDERS_VIEW)] }, getDispatchHistoryHandler);
  fastify.get('/api/orders/:id/timeline', { preHandler: [authorize(PERMISSIONS.ORDERS_VIEW)] }, getTimelineHandler);
  fastify.patch(
    '/api/orders/:id/products/:productId/dispatch-history/:historyId',
    { preHandler: [authorize(PERMISSIONS.ORDERS_DISPATCH_HISTORY_EDIT)] },
    editDispatchHistoryHandler,
  );
  fastify.delete(
    '/api/orders/:id/products/:productId/dispatch-history/:historyId',
    { preHandler: [authorize(PERMISSIONS.ORDERS_DISPATCH_REVERT)] },
    revertDispatchHistoryHandler,
  );
}
