import { Router } from 'express';
import { DealerClaimController } from '../controllers/dealerClaim.controller';
import { DealerDashboardController } from '../controllers/dealerDashboard.controller';
import { authenticateToken } from '../middlewares/auth.middleware';
import { asyncHandler } from '../middlewares/errorHandler.middleware';
import { malwareScanMiddleware, malwareScanMultipleMiddleware } from '../middlewares/malwareScan.middleware';
import { sapLimiter, uploadLimiter } from '../middlewares/rateLimiter.middleware';
import { validateBody, validateParams } from '../middlewares/validate.middleware';
import {
  requestIdParamsSchema,
  updateIOSchema,
  updateEInvoiceSchema,
  sendCreditNoteSchema,
  testSapBlockSchema,
} from '../validators/dealerClaim.validator';
import multer from 'multer';
import path from 'path';

const router = Router();
const dealerClaimController = new DealerClaimController();
const dealerDashboardController = new DealerDashboardController();

// Configure multer for file uploads (memory storage for direct GCS upload)
const upload = multer({
  storage: multer.memoryStorage(),
  limits: {
    fileSize: 10 * 1024 * 1024, // 10MB
  },
  fileFilter: (req, file, cb) => {
    const allowedExtensions = ['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.jpg', '.jpeg', '.png', '.zip'];
    const ext = path.extname(file.originalname).toLowerCase();
    if (allowedExtensions.includes(ext)) {
      cb(null, true);
    } else {
      cb(new Error(`File type ${ext} not allowed. Allowed types: ${allowedExtensions.join(', ')}`));
    }
  },
});

/**
 * @route   GET /api/v1/dealer-claims/dashboard
 * @desc    Get dealer dashboard KPIs and category data
 * @access  Private
 */
router.get('/dashboard', authenticateToken, asyncHandler(dealerDashboardController.getDashboard.bind(dealerDashboardController)));

/**
 * @route   POST /api/v1/dealer-claims
 * @desc    Create a new dealer claim request
 * @access  Private
 */
router.post('/', authenticateToken, asyncHandler(dealerClaimController.createClaimRequest.bind(dealerClaimController)));

/**
 * @route   GET /api/v1/dealer-claims/:requestId
 * @desc    Get claim details
 * @access  Private
 */
router.get('/:requestId', authenticateToken, validateParams(requestIdParamsSchema), asyncHandler(dealerClaimController.getClaimDetails.bind(dealerClaimController)));

/**
 * @route   POST /api/v1/dealer-claims/:requestId/proposal
 * @desc    Submit dealer proposal (Step 1)
 * @access  Private
 */
router.post('/:requestId/proposal', authenticateToken, validateParams(requestIdParamsSchema), upload.single('proposalDocument'), asyncHandler(malwareScanMiddleware), asyncHandler(dealerClaimController.submitProposal.bind(dealerClaimController)));

/**
 * @route   POST /api/v1/dealer-claims/:requestId/completion
 * @desc    Submit completion documents (Step 5)
 * @access  Private
 */
router.post('/:requestId/completion', authenticateToken, uploadLimiter, validateParams(requestIdParamsSchema), upload.fields([
  { name: 'completionDocuments', maxCount: 10 },
  { name: 'activityPhotos', maxCount: 10 },
  { name: 'invoicesReceipts', maxCount: 10 },
  { name: 'attendanceSheet', maxCount: 1 },
]), asyncHandler(malwareScanMultipleMiddleware), asyncHandler(dealerClaimController.submitCompletion.bind(dealerClaimController)));

/**
 * @route   GET /api/v1/dealer-claims/:requestId/io/validate
 * @desc    Validate/Fetch IO details from SAP (returns dummy data for now)
 * @access  Private
 */
router.get('/:requestId/io/validate', authenticateToken, sapLimiter, validateParams(requestIdParamsSchema), asyncHandler(dealerClaimController.validateIO.bind(dealerClaimController)));

/**
 * @route   PUT /api/v1/dealer-claims/:requestId/io
 * @desc    Block IO amount in SAP and store in database
 * @access  Private
 */
router.put('/:requestId/io', authenticateToken, sapLimiter, validateParams(requestIdParamsSchema), validateBody(updateIOSchema), asyncHandler(dealerClaimController.updateIODetails.bind(dealerClaimController)));

/**
 * @route   PUT /api/v1/dealer-claims/:requestId/e-invoice
 * @desc    Update e-invoice details (Step 7)
 * @access  Private
 */
router.put('/:requestId/e-invoice', authenticateToken, sapLimiter, validateParams(requestIdParamsSchema), validateBody(updateEInvoiceSchema), asyncHandler(dealerClaimController.updateEInvoice.bind(dealerClaimController)));
router.get('/:requestId/e-invoice/pdf', authenticateToken, validateParams(requestIdParamsSchema), asyncHandler(dealerClaimController.downloadInvoicePdf.bind(dealerClaimController)));
router.post('/:requestId/wfm/retrigger', authenticateToken, validateParams(requestIdParamsSchema), asyncHandler(dealerClaimController.retriggerWFMPush.bind(dealerClaimController)));

/**
 * @route   PUT /api/v1/dealer-claims/:requestId/credit-note
 * @desc    Update credit note details (Step 8)
 * @access  Private
 */
router.get('/:requestId/e-invoice/csv', authenticateToken, validateParams(requestIdParamsSchema), asyncHandler(dealerClaimController.downloadInvoiceCsv.bind(dealerClaimController)));
router.post('/:requestId/credit-note', authenticateToken, validateParams(requestIdParamsSchema), upload.single('creditNoteFile'), asyncHandler(malwareScanMiddleware), asyncHandler(dealerClaimController.updateCreditNote.bind(dealerClaimController)));
router.get('/:requestId/credit-note-wfm', authenticateToken, validateParams(requestIdParamsSchema), asyncHandler(dealerClaimController.fetchCreditNoteWfm.bind(dealerClaimController)));

/**
 * @route   POST /api/v1/dealer-claims/:requestId/credit-note/send
 * @desc    Send credit note to dealer and auto-approve Step 8
 * @access  Private
 */
router.post('/:requestId/credit-note/send', authenticateToken, validateParams(requestIdParamsSchema), validateBody(sendCreditNoteSchema), asyncHandler(dealerClaimController.sendCreditNoteToDealer.bind(dealerClaimController)));

/**
 * @route   POST /api/v1/dealer-claims/test/sap-block
 * @desc    Test SAP budget blocking directly (for testing/debugging)
 * @access  Private
 * @body    { ioNumber: string, amount: number, requestNumber?: string }
 */
router.post('/test/sap-block', authenticateToken, sapLimiter, validateBody(testSapBlockSchema), asyncHandler(dealerClaimController.testSapBudgetBlock.bind(dealerClaimController)));

export default router;
