import { Router } from 'express';
import { body, param } from 'express-validator';
import multer from 'multer';
import path from 'path';
import fs from 'fs';
import crypto from 'crypto';
import { tendersController } from './tenders.controller';
import { authenticate, authorize } from '../../shared/middleware/auth';
import { validate } from '../../shared/middleware/validation';
import { config } from '../../config';

const router = Router();

const uploadDir = path.join(config.upload.path, 'tenders');
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, { recursive: true });
}

const storage = multer.diskStorage({
  destination: (_req, _file, cb) => cb(null, uploadDir),
  filename: (_req, file, cb) => {
    // Browsers send filenames in multipart/form-data as raw UTF-8 bytes,
    // but multer/busboy decode them as latin1 by default. Reverse it so
    // Arabic filenames are stored intact in the DB.
    try {
      const decoded = Buffer.from(file.originalname || '', 'latin1').toString('utf8');
      file.originalname = decoded;
    } catch {
      // keep as-is
    }
    const extName = path.extname(file.originalname || '') || '';
    cb(null, `${crypto.randomUUID()}${extName}`);
  },
});
const upload = multer({
  storage,
  limits: { fileSize: config.upload.maxFileSize },
});


// View attachment
router.get(
  '/attachments/:attachmentId/view',
  param('attachmentId').isUUID(),
  validate,
  tendersController.viewAttachment
)

router.use(authenticate);

// Enum/lookup routes (no resource id) - place before /:id routes
router.get(
  '/source-values',
  authorize('tenders', 'tenders', 'read'),
  tendersController.getSourceValues
);
router.get(
  '/announcement-type-values',
  authorize('tenders', 'tenders', 'read'),
  tendersController.getAnnouncementTypeValues
);
router.get(
  '/directive-type-values',
  authorize('tenders', 'tenders', 'read'),
  tendersController.getDirectiveTypeValues
);

// Minimal employee list for directive assignee dropdown.
// Guarded by directive-create permission so users who can issue directives
// can populate the dropdown WITHOUT being granted hr:employees:read
// (which would expose salaries, national IDs, and other sensitive HR data).
router.get(
  '/assignable-employees',
  authorize('tenders', 'directives', 'create'),
  tendersController.getAssignableEmployees
);

router.post(
  '/check-duplicates',
  authorize('tenders', 'tenders', 'create'),
  [
    body('issuingBodyName').optional().trim(),
    body('title').optional().trim(),
    body('tenderNumber').optional({ checkFalsy: true }).trim(),
    body('termsValue').optional({ checkFalsy: false }).isNumeric(),
    body('bondValue').optional({ checkFalsy: false }).isNumeric(),
    body('announcementDate').optional({ checkFalsy: true }).isISO8601(),
    body('closingDate').optional({ checkFalsy: true }).isISO8601(),
  ],
  validate,
  tendersController.checkDuplicates
);

// List & create tenders
router.get(
  '/',
  authorize('tenders', 'tenders', 'read'),
  tendersController.findAll
);
router.post(
  '/',
  authorize('tenders', 'tenders', 'create'),
  [
    body('tenderNumber').optional({ checkFalsy: true }).trim(),
    body('issueNumber').optional().trim(),
    body('issuingBodyName').notEmpty().trim(),
    body('title').notEmpty().trim(),
    body('termsValue').optional({ checkFalsy: false }).isNumeric(),
    body('bondValue').optional({ checkFalsy: false }).isNumeric(),
    body('announcementDate').optional({ checkFalsy: true }).isISO8601(),
    body('closingDate').optional({ checkFalsy: true }).isISO8601(),
    body('source').notEmpty(),
    body('announcementType').notEmpty(),
  ],
  validate,
  tendersController.create
);

// Tender by id
router.get(
  '/:id',
  authorize('tenders', 'tenders', 'read'),
  param('id').isUUID(),
  validate,
  tendersController.findById
);
router.put(
  '/:id',
  authorize('tenders', 'tenders', 'update'),
  param('id').isUUID(),
  validate,
  tendersController.update
);

router.delete(
  '/:id',
  authorize('tenders', 'tenders', 'delete'),
  param('id').isUUID(),
  validate,
  tendersController.delete
);

// Tender history
router.get(
  '/:id/history',
  authorize('tenders', 'tenders', 'read'),
  param('id').isUUID(),
  validate,
  tendersController.getHistory
);

// Convert to deal
router.post(
  '/:id/convert-to-deal',
  authorize('tenders', 'tenders', 'update'),
  [
    param('id').isUUID(),
    body('contactId').isUUID(),
    body('pipelineId').isUUID(),
    body('ownerId').optional().isUUID(),
  ],
  validate,
  tendersController.convertToDeal
);

// Directives
router.post(
  '/:id/directives',
  authorize('tenders', 'directives', 'create'),
  [
    param('id').isUUID(),
    body('type').isIn(['BUY_TERMS', 'VISIT_CLIENT', 'MEET_COMMITTEE', 'PREPARE_TO_BID']),
    body('assignedToEmployeeId').isUUID(),
    body('notes').optional().trim(),
  ],
  validate,
  tendersController.createDirective
);

// Update directive (e.g. complete task) - route with directiveId
router.put(
  '/directives/:directiveId',
  authorize('tenders', 'directives', 'update'),
  [
    param('directiveId').isUUID(),
    body('status').optional().isIn(['PENDING', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED']),
    body('completionNotes').optional().trim(),
  ],
  validate,
  tendersController.updateDirective
);

// File uploads
router.post(
  '/:id/attachments',
  authorize('tenders', 'tenders', 'update'),
  param('id').isUUID(),
  validate,
  upload.single('file'),
  tendersController.uploadTenderAttachment
);

router.post(
  '/directives/:directiveId/attachments',
  authorize('tenders', 'directives', 'update'),
  param('directiveId').isUUID(),
  validate,
  upload.single('file'),
  tendersController.uploadDirectiveAttachment
);

export default router;



// Delete attachment
router.delete(
  '/attachments/:attachmentId',
  authorize('tenders', 'tenders', 'update'),
  param('attachmentId').isUUID(),
  validate,
  tendersController.deleteAttachment
)
