import { Router, Request, Response, NextFunction } from 'express';
import { galleryAdsService } from './gallery-ads.service';
import { createAdSchema, updateAdSchema, listAdsSchema, reorderAdsSchema, adAnalyticsQuerySchema } from './gallery-ads.schemas';
import { validate } from '../../middleware/validate';
import { authenticate } from '../../middleware/auth.middleware';
import { requireRole } from '../../middleware/rbac.middleware';
import { PAYMENTS_ROLES } from '../../utils/roles';

const router = Router();

router.use(authenticate);
router.use(requireRole(...PAYMENTS_ROLES));

// GET /api/gallery-ads/admin — list all ads (paginated)
router.get(
  '/',
  validate(listAdsSchema, 'query'),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const result = await galleryAdsService.listAll(req.query as any);
      res.json(result);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/gallery-ads/admin/analytics/aggregate — aggregate analytics across all ads
router.get(
  '/analytics/aggregate',
  validate(adAnalyticsQuerySchema, 'query'),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { days } = req.query as any;
      const analytics = await galleryAdsService.getAggregateAnalytics(days);
      res.json(analytics);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/gallery-ads/admin/:id/analytics — per-ad time-series analytics
router.get(
  '/:id/analytics',
  validate(adAnalyticsQuerySchema, 'query'),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = parseInt(req.params.id as string, 10);
      const { days } = req.query as any;
      const analytics = await galleryAdsService.getAdAnalytics(id, days);
      res.json(analytics);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/gallery-ads/admin/:id — get single ad
router.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const id = parseInt(req.params.id as string, 10);
    const ad = await galleryAdsService.getById(id);
    if (!ad) {
      res.status(404).json({ error: 'Ad not found' });
      return;
    }
    res.json(ad);
  } catch (err) {
    next(err);
  }
});

// POST /api/gallery-ads/admin — create ad
router.post(
  '/',
  validate(createAdSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const ad = await galleryAdsService.create(req.body);
      res.status(201).json(ad);
    } catch (err) {
      next(err);
    }
  }
);

// PUT /api/gallery-ads/admin/reorder — bulk reorder
router.put(
  '/reorder',
  validate(reorderAdsSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      await galleryAdsService.reorder(req.body.ids);
      res.json({ success: true });
    } catch (err) {
      next(err);
    }
  }
);

// PUT /api/gallery-ads/admin/:id — update ad
router.put(
  '/:id',
  validate(updateAdSchema),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = parseInt(req.params.id as string, 10);
      const ad = await galleryAdsService.update(id, req.body);
      if (!ad) {
        res.status(404).json({ error: 'Ad not found' });
        return;
      }
      res.json(ad);
    } catch (err) {
      if (err instanceof Error && err.message.includes('Cannot change type')) {
        res.status(400).json({ error: err.message });
        return;
      }
      next(err);
    }
  }
);

// DELETE /api/gallery-ads/admin/:id — delete ad
router.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {
  try {
    const id = parseInt(req.params.id as string, 10);
    await galleryAdsService.delete(id);
    res.json({ success: true });
  } catch (err) {
    if (err instanceof Error && err.message.includes('Cannot delete')) {
      res.status(400).json({ error: err.message });
      return;
    }
    next(err);
  }
});

export { router as galleryAdsAdminRouter };
