import { Router } from 'express';
import { authenticate } from '../../middleware/auth.middleware';
import { validate } from '../../middleware/validate';
import { feedService } from './feed.service';
import { createFeedSchema, updateFeedSchema, createExportTokenSchema } from './feed.schemas';

const router = Router();

// =========================================================================
// Public routes (no auth)
// =========================================================================

// GET /api/calendar/feed/:token.ics — serve ICS export feed
router.get('/feed/:token.ics', async (req, res, next) => {
  try {
    const token = req.params.token as string;
    const icsData = await feedService.getExportFeed(token);

    if (!icsData) {
      res.status(404).json({ error: { message: 'Feed not found', code: 'NOT_FOUND' } });
      return;
    }

    res.set('Content-Type', 'text/calendar; charset=utf-8');
    res.set('Content-Disposition', 'inline; filename="calendar.ics"');
    res.send(icsData);
  } catch (error) {
    next(error);
  }
});

// =========================================================================
// Authenticated routes
// =========================================================================

router.use(authenticate);

// GET /api/calendar/feeds — list user's feeds
router.get('/feeds', async (req, res, next) => {
  try {
    const feeds = await feedService.listFeeds(req.user!.id);
    res.json({ feeds });
  } catch (error) {
    next(error);
  }
});

// POST /api/calendar/feeds — create a new ICS feed subscription
router.post('/feeds', validate(createFeedSchema), async (req, res, next) => {
  try {
    const feed = await feedService.createFeed(req.user!.id, req.body);
    res.status(201).json({ feed });
  } catch (error) {
    next(error);
  }
});

// PATCH /api/calendar/feeds/:id — update feed settings
router.patch('/feeds/:id', validate(updateFeedSchema), async (req, res, next) => {
  try {
    const feed = await feedService.updateFeed(req.user!.id, req.params.id as string, req.body);
    res.json({ feed });
  } catch (error) {
    next(error);
  }
});

// DELETE /api/calendar/feeds/:id — delete a feed subscription
router.delete('/feeds/:id', async (req, res, next) => {
  try {
    await feedService.deleteFeed(req.user!.id, req.params.id as string);
    res.json({ success: true });
  } catch (error) {
    next(error);
  }
});

// POST /api/calendar/feeds/:id/refresh — force refresh a feed
router.post('/feeds/:id/refresh', async (req, res, next) => {
  try {
    const feed = await feedService.listFeeds(req.user!.id);
    const owned = feed.find((f) => f.id === (req.params.id as string));
    if (!owned) {
      res.status(404).json({ error: { message: 'Feed not found', code: 'NOT_FOUND' } });
      return;
    }

    await feedService.refreshFeed(req.params.id as string);
    const updated = await feedService.listFeeds(req.user!.id);
    const refreshed = updated.find((f) => f.id === (req.params.id as string));
    res.json({ feed: refreshed });
  } catch (error) {
    next(error);
  }
});

// GET /api/calendar/export/tokens — list export tokens
router.get('/export/tokens', async (req, res, next) => {
  try {
    const tokens = await feedService.listExportTokens(req.user!.id);
    res.json({ tokens });
  } catch (error) {
    next(error);
  }
});

// POST /api/calendar/export/tokens — create an export token
router.post('/export/tokens', validate(createExportTokenSchema), async (req, res, next) => {
  try {
    const token = await feedService.createExportToken(req.user!.id, req.body);
    res.status(201).json({ token });
  } catch (error) {
    next(error);
  }
});

// DELETE /api/calendar/export/tokens/:id — revoke an export token
router.delete('/export/tokens/:id', async (req, res, next) => {
  try {
    await feedService.revokeExportToken(req.user!.id, req.params.id as string);
    res.json({ success: true });
  } catch (error) {
    next(error);
  }
});

export default router;
