import { Router, Request, Response } from 'express';
import multer from 'multer';
import bcrypt from 'bcryptjs';
import { prisma } from '../models';
import { authMiddleware, signToken } from '../middleware/auth';
import { requireLegal, requireMd } from '../middleware/rbac';
import { verifyMdOtp } from '../lib/md-otp';
import { GPSLockMiddleware } from '../middleware/gps-lock';
import { licenseController } from '../controllers/license.controller';
import { pitController } from '../controllers/pit.controller';
import { jvPartnerController } from '../controllers/jv-partner.controller';
import { documentController } from '../controllers/document.controller';
import { gpsController } from '../controllers/gps.controller';
import { killSwitchController } from '../controllers/kill-switch.controller';
import { dashboardController } from '../controllers/dashboard.controller';
import { blockModelController } from '../controllers/block-model.controller';
import { reverseEconomicsController } from '../controllers/reverse-economics.controller';
import { excavatorController } from '../controllers/excavator.controller';
import { gradeControlController } from '../controllers/grade-control.controller';
import { blendingController } from '../controllers/blending.controller';
import { maxPpmController } from '../controllers/max-ppm.controller';

const upload = multer({
  storage: multer.memoryStorage(),
  limits: { fileSize: 52 * 1024 * 1024 },
});

export function buildRouter(): Router {
  const router = Router();

  router.post('/auth/login', async (req: Request, res: Response) => {
    const { email, password } = req.body as { email?: string; password?: string };
    if (!email || !password) {
      res.status(400).json({ success: false, error: 'email and password required' });
      return;
    }
    try {
      const user = await prisma.user.findUnique({ where: { email } });
      if (!user || !(await bcrypt.compare(password, user.password_hash))) {
        res.status(401).json({ success: false, error: 'Invalid credentials' });
        return;
      }
      if (user.is_suspended) {
        res.status(403).json({ success: false, error: 'Account suspended' });
        return;
      }
      const token = signToken(user.id, user.email, user.role);
      res.json({
        success: true,
        data: {
          token,
          user: {
            id: user.id,
            email: user.email,
            role: user.role,
            full_name: user.full_name,
          },
        },
      });
    } catch (err) {
      console.error('POST /auth/login', err);
      res.status(503).json({
        success: false,
        error:
          'Database unavailable. Check DATABASE_URL, PostgreSQL/PostGIS, and run migrations and seed (see wm-ims README).',
      });
    }
  });

  router.get('/pits/scan/:guid', pitController.scanByGuid);

  router.post('/cron/check-expiry', licenseController.cronCheck);

  router.use(authMiddleware);

  router.get('/licenses', licenseController.list);
  router.get('/licenses/:id', licenseController.getOne);
  router.post(
    '/licenses',
    upload.fields([
      { name: 'pml_certificate', maxCount: 1 },
      { name: 'jv_contract', maxCount: 1 },
    ]),
    licenseController.create
  );
  router.put('/licenses/:id', licenseController.update);
  router.delete('/licenses/:id', verifyMdOtp, licenseController.softDelete);
  router.post('/licenses/:id/suspend', requireMd, licenseController.suspend);
  router.post('/licenses/:id/renew', licenseController.renew);
  router.post('/licenses/:id/restore', verifyMdOtp, licenseController.restore);

  router.get('/licenses/:id/pits', pitController.listByLicense);
  router.post('/licenses/:id/pits', pitController.create);
  router.get('/pits/:id', pitController.getOne);
  router.put('/pits/:id', pitController.update);
  router.delete('/pits/:id', pitController.softDelete);
  router.post('/pits/:id/generate-qr', pitController.generateQr);

  router.get('/licenses/:id/jv-partners', jvPartnerController.list);
  router.post('/licenses/:id/jv-partners', jvPartnerController.create);
  router.put('/jv-partners/:id', jvPartnerController.update);
  router.delete('/jv-partners/:id', jvPartnerController.remove);
  router.post('/jv-partners/:id/verify-nida', jvPartnerController.verifyNida);
  router.post('/jv-partners/:id/lock-equity', requireMd, jvPartnerController.lockEquity);
  router.post('/jv-partners/:id/unlock-equity-request', jvPartnerController.unlockEquityRequest);

  router.get('/licenses/:id/documents', documentController.list);
  router.post(
    '/licenses/:id/documents',
    upload.single('file'),
    documentController.upload
  );
  router.get('/documents/:id/download', documentController.download);
  router.delete('/documents/:id', verifyMdOtp, documentController.softDelete);
  router.post('/documents/:id/verify', requireLegal, documentController.verify);

  router.post('/gps/verify-location', gpsController.verifyLocation);
  router.post('/gps/report-submission', GPSLockMiddleware.verifyReportLocation.bind(GPSLockMiddleware), gpsController.reportSubmission);
  router.get('/gps/pit-distance/:pitId', gpsController.pitDistance);

  router.post('/kill-switch/:licenseId', requireMd, verifyMdOtp, killSwitchController.trigger);
  router.get('/kill-switch/logs', killSwitchController.logs);

  router.get('/dashboard/license-stats', dashboardController.licenseStats);
  router.get('/reports/license-summary', dashboardController.licenseSummaryPdf);
  router.get('/reports/expiring-licenses', dashboardController.expiringLicenses);

  const uploadCsv = multer({
    storage: multer.memoryStorage(),
    limits: { fileSize: 20 * 1024 * 1024 },
  });

  router.post('/block-model/import-csv', uploadCsv.single('file'), blockModelController.importCsv);
  router.post('/block-model/kriging-interpolate', blockModelController.krigingInterpolate);
  router.get('/block-model/query', blockModelController.query);
  router.get('/block-model/heatmap', blockModelController.heatmap);
  router.get('/block-model/reserves', blockModelController.reserves);

  router.post('/reverse-economics/target-profit', reverseEconomicsController.targetProfit);
  router.get('/reverse-economics/coordinates/:lat/:lon', reverseEconomicsController.coordinates);

  router.post('/excavators', excavatorController.create);
  router.get('/excavators', excavatorController.list);
  router.get('/excavators/:id/telemetry', excavatorController.telemetry);
  router.post('/excavators/:id/telemetry-ingest', excavatorController.ingestTelemetry);
  router.post('/excavators/:id/assign-pit', excavatorController.assignPit);
  router.post('/excavators/:id/shutoff', requireMd, verifyMdOtp, excavatorController.shutoff);
  router.get('/excavators/:id/route', excavatorController.route);

  router.post('/grade-control/validate-truck', gradeControlController.validateTruck);
  router.post('/grade-control/waste-call', gradeControlController.wasteCall);
  router.post('/grade-control/jv-auto-switch', gradeControlController.jvAutoSwitch);
  router.get('/grade-control/dilution-alert/:pitId', gradeControlController.dilutionAlert);
  router.get('/grade-control/dilution-alerts', gradeControlController.dilutionList);
  router.get('/grade-control/jv-auto-switch-log', gradeControlController.jvSwitchHistory);

  router.post('/blending/calculate', blendingController.calculate);
  router.post('/blending/generate-manifest/:id', blendingController.generateManifest);
  router.get('/blending/history/:plant', blendingController.history);

  router.get('/max-ppm/find-highest', maxPpmController.findHighest);
  router.get('/max-ppm/hotspots', maxPpmController.hotspots);

  return router;
}
