const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs');
const multer = require('multer');
const { authenticate } = require('../middlewares/auth');

const productionOrderController = require('../controllers/productionOrderController');
const materialIssueController = require('../controllers/materialIssueController');
const productionConfirmationController = require('../controllers/productionConfirmationController');
const scrapReportingController = require('../controllers/scrapReportingController');
const wipTrackingController = require('../controllers/wipTrackingController');
const mrpController = require('../controllers/mrpController');
const routingExecutionController = require('../controllers/routingExecutionController');
const productionSchedulingController = require('../controllers/productionSchedulingController');
const productionCostingController = require('../controllers/productionCostingController');
const workOrderController = require('../controllers/workOrderController');
const routeCardController = require('../controllers/routeCardController');
const productionNestingController = require('../controllers/productionNestingController');
const productionQCController = require('../controllers/productionQCController');
const productionFinalInspectionController = require('../controllers/productionFinalInspectionController');
const productionPackingController = require('../controllers/productionPackingController');
const productionFGInwardController = require('../controllers/productionFGInwardController');
const fgStockLedgerController = require('../controllers/fgStockLedgerController');
const fgDispatchController = require('../controllers/fgDispatchController');
const inProgressMaterialRequestController = require('../controllers/inProgressMaterialRequestController');
const productionWipLedgerController = require('../controllers/productionWipLedgerController');

const nestingUploadsDir = path.join(__dirname, '../uploads/nesting');
if (!fs.existsSync(nestingUploadsDir)) {
  fs.mkdirSync(nestingUploadsDir, { recursive: true });
}
const nestingUpload = multer({
  storage: multer.diskStorage({
    destination: (req, file, cb) => cb(null, nestingUploadsDir),
    filename: (req, file, cb) => {
      const ext = path.extname(file.originalname);
      const name = path.basename(file.originalname, ext).replace(/[^a-zA-Z0-9-_]/g, '_');
      cb(null, `${name}_${Date.now()}${ext}`);
    }
  }),
  limits: { fileSize: 10 * 1024 * 1024 }
});

router.use(authenticate);

router.get('/production-order', productionOrderController.getAll);
router.get(
  '/production-order/:id/material-receipt-lines',
  productionOrderController.getMaterialReceiptLines
);
router.put(
  '/production-order/:id/material-receipt-lines',
  productionOrderController.saveMaterialReceiptLines
);
router.get('/production-order/:id', productionOrderController.getById);
router.post('/production-order', productionOrderController.create);
router.put('/production-order/:id', productionOrderController.update);
router.delete('/production-order/:id', productionOrderController.delete);
router.post('/production-order/:id/release', productionOrderController.release);
router.post(
  '/production-order/:id/release-additional-batch',
  productionOrderController.releaseAdditionalBatch
);
router.post(
  '/production-order/:id/batch/:batchId/release',
  productionOrderController.releaseProductionOrderBatch
);
router.get('/production-order/:id/reservations', productionOrderController.getReservations);
router.post('/production-order/explode-bom', productionOrderController.explodeBOM);
router.post('/production-order/:id/send-to-nesting', productionNestingController.sendProductionOrderToNesting);

router.get('/nesting', productionNestingController.getNestingList);
router.post('/nesting/:productionOrderId/start', productionNestingController.startNestingForProductionOrder);
router.get('/nesting/:productionOrderId', productionNestingController.getNestingByProductionOrder);
router.get('/nesting-confirmations/:productionOrderId', productionNestingController.getNestingConfirmations);
router.post('/nesting-confirmations/:productionOrderId', productionNestingController.upsertNestingConfirmation);
router.put('/nesting-entry/:id', nestingUpload.single('nesting_file'), productionNestingController.updateNestingEntry);
router.post('/nesting-entry/:id/start', productionNestingController.startNestingEntry);
router.post('/nesting-entry/:id/complete', nestingUpload.single('nesting_file'), productionNestingController.completeNestingEntry);
router.patch('/nesting/stores-request-lines/:id', productionNestingController.patchNestingStoresRequestLine);

// Work Order routes
// IMPORTANT: keep /prefill before /:id (otherwise :id captures "prefill")
router.get('/work-order', workOrderController.getAll);
router.get('/work-order/prefill/:productionOrderId', workOrderController.getPrefillFromProductionOrder);
router.get('/work-order/:id', workOrderController.getById);
router.post('/work-order', workOrderController.create);
router.put('/work-order/:id', workOrderController.update);
router.delete('/work-order/:id', workOrderController.delete);
router.post('/work-order/:id/release', workOrderController.release);

// Production Storage (WIP) ledger
router.get('/wip-storage/ledger', productionWipLedgerController.getLedger);

// Route Card routes
router.get('/route-card', routeCardController.getAll);
router.get('/route-card/wip-by-operation', routeCardController.getWipByOperation);
router.get('/route-card/:id/pdf', routeCardController.generatePDF);
router.get('/route-card/:id/process-log-sheet/pdf', routeCardController.generateProcessLogSheetPDF);
router.put('/route-card/:id/pdf-sign-offs', routeCardController.updatePdfSignOffs);
router.put('/route-card/:id/raw-material-processes', routeCardController.updateRawMaterialProcesses);
router.get('/route-card/:id', routeCardController.getById);
router.post('/route-card/generate/:workOrderId', routeCardController.generateFromWorkOrder);
router.post('/route-card/operation/:id/start', routeCardController.startOperation);
router.post('/route-card/operation/:id/complete', routeCardController.completeOperation);
router.post('/route-card/operation/:id/actuals', routeCardController.updateActuals);
router.get('/route-card/operation/:id/wip-consumption', routeCardController.getWipOperationConsumption);
router.put('/route-card/operation/:id/wip-consumption', routeCardController.saveWipOperationConsumption);
router.post('/route-card/operation/:id/wip-reverse', routeCardController.reverseWipOperationConsumption);
router.get('/route-card/operation/:id/component-tracking', routeCardController.getOperationComponentTracking);
router.put('/route-card/operation/:id/component-tracking', routeCardController.saveOperationComponentTracking);
router.post('/route-card/operation/:id/cancel', routeCardController.cancelOperation);
router.post('/route-card/operation/:routeCardOperationId/move-to-qc', productionQCController.moveFromRouteCardOperation);

// Production QC routes
router.get('/production-qc', productionQCController.getAll);
router.get('/production-qc/qc-inspectors', productionQCController.getQCInspectors);
router.get('/production-qc/:id', productionQCController.getById);
router.get('/production-qc/:id/component-tracking', productionQCController.getComponentTracking);
router.put('/production-qc/:id/component-tracking', productionQCController.saveComponentTracking);
router.post('/production-qc/:id/start', productionQCController.startQC);
router.post('/production-qc/:id/complete', productionQCController.completeQC);
router.post('/production-qc/:id/approve', productionQCController.approveQC);
router.post('/production-qc/:id/generate-rework-route-card', productionQCController.generateReworkRouteCard);

// Final Inspection routes
router.get('/final-inspection', productionFinalInspectionController.getAll);
router.get('/final-inspection/:id', productionFinalInspectionController.getById);
router.post('/route-card/:routeCardId/final-qc', productionFinalInspectionController.createFromRouteCard);
router.post('/final-inspection/:id/start', productionFinalInspectionController.start);
router.post('/final-inspection/:id/complete', productionFinalInspectionController.complete);
router.post('/final-inspection/:id/approve', productionFinalInspectionController.approve);

// Production Packing routes
router.get('/packing', productionPackingController.getAll);
router.get('/packing/packers', productionPackingController.getPackersByRouteCard);
router.get('/packing/prefill/:routeCardId', productionPackingController.getPrefillByRouteCard);
router.get('/packing/:id', productionPackingController.getById);
router.post('/packing', productionPackingController.create);
router.post('/packing/:id/start', productionPackingController.start);
router.post('/packing/:id/update', productionPackingController.updateProgress);
router.post('/packing/:id/complete', productionPackingController.complete);
router.get('/fg-inward', productionFGInwardController.getAll);
router.post('/fg-inward', productionFGInwardController.create);
router.get('/fg-stock-ledger', fgStockLedgerController.getAll);
router.post('/fg-stock-ledger/backfill', fgStockLedgerController.backfill);
router.post('/fg-stock-ledger/backfill-stores', fgStockLedgerController.backfillStoresLedger);
router.get('/fg-dispatch', fgDispatchController.getAll);
router.get('/fg-dispatch/eligible-items', fgDispatchController.getEligibleItems);
router.get('/fg-dispatch/invoice-options', fgDispatchController.getInvoiceOptions);
router.get('/fg-dispatch/invoice-prefill/:invoiceId', fgDispatchController.getInvoicePrefill);
router.get('/fg-dispatch/available-stock', fgDispatchController.getAvailableStock);
router.get('/fg-dispatch/:id', fgDispatchController.getById);
router.post('/fg-dispatch', fgDispatchController.create);
router.post('/fg-dispatch/:id/submit', fgDispatchController.submit);
router.post('/fg-dispatch/:id/approve', fgDispatchController.approve);
router.post('/fg-dispatch/:id/start', fgDispatchController.start);
router.post('/fg-dispatch/:id/deliver', fgDispatchController.deliver);
router.post('/fg-dispatch/:id/status', fgDispatchController.updateStatus);

router.get('/material-issue', materialIssueController.getAll);
router.get('/material-issue/:id', materialIssueController.getById);
router.post('/material-issue', materialIssueController.create);
router.put('/material-issue/:id', materialIssueController.update);
router.delete('/material-issue/:id', materialIssueController.delete);
router.post('/material-issue/:id/post', materialIssueController.post);
router.post('/material-issue/:id/receive', materialIssueController.receive);
router.post('/material-issue/:id/return', materialIssueController.returnToStores);

router.get('/production-confirmation', productionConfirmationController.getAll);
router.get('/production-confirmation/:id', productionConfirmationController.getById);
router.post('/production-confirmation', productionConfirmationController.create);
router.put('/production-confirmation/:id', productionConfirmationController.update);
router.delete('/production-confirmation/:id', productionConfirmationController.delete);
router.post('/production-confirmation/:id/post', productionConfirmationController.post);

router.get('/scrap-reporting', scrapReportingController.getAll);
router.get('/scrap-reporting/:id', scrapReportingController.getById);
router.post('/scrap-reporting', scrapReportingController.create);
router.put('/scrap-reporting/:id', scrapReportingController.update);
router.delete('/scrap-reporting/:id', scrapReportingController.delete);
router.post('/scrap-reporting/:id/post', scrapReportingController.post);

router.get('/wip-tracking', wipTrackingController.getAll);
router.get('/wip-tracking/:id', wipTrackingController.getById);
router.post('/wip-tracking', wipTrackingController.create);
router.put('/wip-tracking/:id', wipTrackingController.update);
router.delete('/wip-tracking/:id', wipTrackingController.delete);

// Routing Execution routes
router.get('/routing-execution/production-order/:productionOrderId', routingExecutionController.getByProductionOrder);
router.get('/routing-execution/shop-floor', routingExecutionController.getShopFloorOperations);
router.post('/routing-execution/:id/start', routingExecutionController.startOperation);
router.post('/routing-execution/:id/complete', routingExecutionController.completeOperation);
router.get('/routing-execution/work-center/:workCenterId/utilization', routingExecutionController.getWorkCenterUtilization);
router.post('/routing-execution/production-order/:productionOrderId/update-dates', routingExecutionController.updateProductionOrderDates);

// MRP (Material Requirement Planning) routes
router.post('/mrp/run', mrpController.runMRP);
router.get('/mrp/customer-po/:id', mrpController.getMRPForCustomerPO);
router.get('/mrp/production-order/:id', mrpController.getMRPForProductionOrder);
router.get('/mrp/shortages', mrpController.getMRPShortages);
router.get('/mrp/check-sent-materials', mrpController.checkSentMaterials);
router.post('/mrp/create-pr', mrpController.createPRFromMRP);
router.post('/mrp/create-material-request', mrpController.createMaterialRequestFromMRP);
router.get('/in-progress-material-request', inProgressMaterialRequestController.getAll);
router.get('/in-progress-material-request/:id', inProgressMaterialRequestController.getById);
router.post('/in-progress-material-request', inProgressMaterialRequestController.create);
router.put('/in-progress-material-request/:id', inProgressMaterialRequestController.update);
router.patch('/in-progress-material-request/:id/status', inProgressMaterialRequestController.updateStatus);

// Production Scheduling routes
router.get('/schedule', productionSchedulingController.getSchedule);
router.get('/schedule/production-order/:productionOrderId', productionSchedulingController.getScheduleByProductionOrder);
router.post('/schedule/forward/:productionOrderId', productionSchedulingController.forwardSchedule);
router.post('/schedule/backward/:productionOrderId', productionSchedulingController.backwardSchedule);
router.get('/schedule/work-center-loading', productionSchedulingController.getWorkCenterLoading);
router.post('/schedule/optimize', productionSchedulingController.optimizeSchedule);
router.put('/schedule/:id/status', productionSchedulingController.updateScheduleStatus);

// Production Costing routes
router.get('/costing/estimate', productionCostingController.estimateByFinishedGood);
router.post('/costing/estimate/save', productionCostingController.saveEstimateByFinishedGood);
router.post('/costing/estimate/update-bom-rates', productionCostingController.updateBomRatesByFinishedGood);
router.get('/costing/estimate/saved', productionCostingController.getSavedEstimateByFinishedGood);
router.get('/costing/:productionOrderId', productionCostingController.getProductionCost);
router.get('/costing/:productionOrderId/variance', productionCostingController.getCostVariance);
router.post('/costing/calculate-standard/:productionOrderId', productionCostingController.calculateStandardCost);
router.post('/costing/calculate-actual/:productionOrderId', productionCostingController.calculateActualCost);
router.post('/costing/calculate-variance/:productionOrderId', productionCostingController.calculateCostVariance);
router.post('/costing/calculate-all/:productionOrderId', productionCostingController.calculateAllCosts);

// Material Substitution Routes
const materialSubstitutionController = require('../controllers/materialSubstitutionController');
router.post('/substitute-component/:componentId', authenticate, materialSubstitutionController.substituteProductionOrderComponent);

// Machine History Card Routes
const machineHistoryCardRoutes = require('./machineHistoryCardRoutes');
router.use('/machine-history-card', machineHistoryCardRoutes);

module.exports = router;

