import { Router } from 'express';
import { authenticate } from '../../middleware/auth.middleware';
import { validate } from '../../middleware/validate';
import { calendarService } from './calendar.service';
import {
  createLayerSchema,
  updateLayerSchema,
  createItemSchema,
  updateItemSchema,
  dateRangeSchema,
  seriesEditScopeSchema,
} from './calendar.schemas';
import type { SeriesEditScope } from './calendar.schemas';

const router = Router();

// All routes require authentication
router.use(authenticate);

// =========================================================================
// Layers
// =========================================================================

// GET /api/calendar/layers — get all user layers (ensures system layers exist)
router.get('/layers', async (req, res, next) => {
  try {
    const layers = await calendarService.ensureSystemLayers(req.user!.id);
    res.json({ layers });
  } catch (error) {
    next(error);
  }
});

// POST /api/calendar/layers — create a user layer
router.post('/layers', validate(createLayerSchema), async (req, res, next) => {
  try {
    const layer = await calendarService.createLayer(req.user!.id, req.body);
    res.status(201).json({ layer });
  } catch (error) {
    next(error);
  }
});

// PATCH /api/calendar/layers/:id — update a layer
router.patch('/layers/:id', validate(updateLayerSchema), async (req, res, next) => {
  try {
    const layer = await calendarService.updateLayer(
      req.user!.id,
      req.params.id as string,
      req.body
    );
    res.json({ layer });
  } catch (error) {
    next(error);
  }
});

// DELETE /api/calendar/layers/:id — delete a layer (USER/EXTERNAL only)
router.delete('/layers/:id', async (req, res, next) => {
  try {
    await calendarService.deleteLayer(req.user!.id, req.params.id as string);
    res.json({ success: true });
  } catch (error) {
    next(error);
  }
});

// =========================================================================
// Items
// =========================================================================

// GET /api/calendar/items?startDate=&endDate=&layerIds=
router.get('/items', validate(dateRangeSchema, 'query'), async (req, res, next) => {
  try {
    const { startDate, endDate } = req.query as { startDate: string; endDate: string };
    const layerIdsRaw = req.query.layerIds as string | undefined;
    const layerIds = layerIdsRaw ? layerIdsRaw.split(',').filter(Boolean) : undefined;

    const items = await calendarService.getItems(req.user!.id, startDate, endDate, layerIds);
    res.json({ items });
  } catch (error) {
    next(error);
  }
});

// POST /api/calendar/items — create item
router.post('/items', validate(createItemSchema), async (req, res, next) => {
  try {
    const item = await calendarService.createItem(req.user!.id, req.body);
    res.status(201).json({ item });
  } catch (error) {
    next(error);
  }
});

// PATCH /api/calendar/items/:id?scope=THIS_ONLY|THIS_AND_FUTURE|ALL
router.patch('/items/:id', validate(updateItemSchema), async (req, res, next) => {
  try {
    const scopeRaw = req.query.scope as string | undefined;
    let scope: SeriesEditScope | undefined;
    if (scopeRaw) {
      scope = seriesEditScopeSchema.parse(scopeRaw);
    }

    const item = await calendarService.updateItem(
      req.user!.id,
      req.params.id as string,
      req.body,
      scope
    );
    res.json({ item });
  } catch (error) {
    next(error);
  }
});

// DELETE /api/calendar/items/:id?scope=THIS_ONLY|THIS_AND_FUTURE|ALL
router.delete('/items/:id', async (req, res, next) => {
  try {
    const scopeRaw = req.query.scope as string | undefined;
    let scope: SeriesEditScope | undefined;
    if (scopeRaw) {
      scope = seriesEditScopeSchema.parse(scopeRaw);
    }

    await calendarService.deleteItem(
      req.user!.id,
      req.params.id as string,
      scope
    );
    res.json({ success: true });
  } catch (error) {
    next(error);
  }
});

// =========================================================================
// Personal calendar (merged view)
// =========================================================================

// GET /api/calendar/my?startDate=&endDate=
router.get('/my', validate(dateRangeSchema, 'query'), async (req, res, next) => {
  try {
    const { startDate, endDate } = req.query as { startDate: string; endDate: string };
    const result = await calendarService.getPersonalCalendar(req.user!.id, startDate, endDate);
    res.json(result);
  } catch (error) {
    next(error);
  }
});

export default router;
