import { Router, Request, Response } from 'express';
import {
  getAnnotations,
  createAnnotation,
  getAnnotation,
  updateAnnotation,
  deleteAnnotation,
} from '../services/storage';
import type { CreateAnnotationInput, UpdateAnnotationInput } from '@abcvideo/shared';

const router = Router({ mergeParams: true });

// GET /api/annotations/:videoId
router.get('/', (req: Request, res: Response) => {
  const annotations = getAnnotations(req.params.videoId);
  res.json(annotations);
});

// POST /api/annotations/:videoId
router.post('/', (req: Request, res: Response) => {
  const input: CreateAnnotationInput = { ...req.body, videoId: req.params.videoId };
  if (!input.type || input.timeStart === undefined || input.timeEnd === undefined) {
    res.status(400).json({ error: 'Missing required fields: type, timeStart, timeEnd' });
    return;
  }
  const annotation = createAnnotation(input);
  res.status(201).json(annotation);
});

// GET /api/annotations/:videoId/export?format=vtt|srt|json|csv
// NOTE: this must be registered before /:id to avoid "export" matching as an id
router.get('/export', (req: Request, res: Response) => {
  const { format = 'json' } = req.query as { format?: string };
  const annotations = getAnnotations(req.params.videoId);

  const toTimecode = (s: number, sep = '.') => {
    const h = Math.floor(s / 3600).toString().padStart(2, '0');
    const m = Math.floor((s % 3600) / 60).toString().padStart(2, '0');
    const sec = Math.floor(s % 60).toString().padStart(2, '0');
    const ms = Math.round((s % 1) * 1000).toString().padStart(3, '0');
    return `${h}:${m}:${sec}${sep}${ms}`;
  };

  if (format === 'vtt') {
    const lines = ['WEBVTT', ''];
    annotations
      .filter(a => a.type === 'subtitle')
      .forEach((a, i) => {
        lines.push(`${i + 1}`);
        lines.push(`${toTimecode(a.timeStart)} --> ${toTimecode(a.timeEnd)}`);
        lines.push(a.text, '');
      });
    res.setHeader('Content-Type', 'text/vtt');
    res.setHeader('Content-Disposition', `attachment; filename="annotations.vtt"`);
    res.send(lines.join('\n'));
  } else if (format === 'srt') {
    const lines: string[] = [];
    annotations
      .filter(a => a.type === 'subtitle')
      .forEach((a, i) => {
        lines.push(`${i + 1}`);
        lines.push(`${toTimecode(a.timeStart, ',')} --> ${toTimecode(a.timeEnd, ',')}`);
        lines.push(a.text, '');
      });
    res.setHeader('Content-Type', 'text/plain');
    res.setHeader('Content-Disposition', `attachment; filename="annotations.srt"`);
    res.send(lines.join('\n'));
  } else if (format === 'csv') {
    const header = 'id,type,timeStart,timeEnd,text,posX,posY\n';
    const rows = annotations.map(a =>
      `${a.id},${a.type},${a.timeStart},${a.timeEnd},"${a.text.replace(/"/g, '""')}",${a.position.x},${a.position.y}`
    ).join('\n');
    res.setHeader('Content-Type', 'text/csv');
    res.setHeader('Content-Disposition', `attachment; filename="annotations.csv"`);
    res.send(header + rows);
  } else {
    res.setHeader('Content-Disposition', `attachment; filename="annotations.json"`);
    res.json(annotations);
  }
});

// PUT /api/annotations/:videoId/:id
router.put('/:id', (req: Request, res: Response) => {
  const input: UpdateAnnotationInput = req.body;
  const updated = updateAnnotation(req.params.id, input);
  if (!updated) {
    res.status(404).json({ error: 'Annotation not found' });
    return;
  }
  res.json(updated);
});

// DELETE /api/annotations/:videoId/:id
router.delete('/:id', (req: Request, res: Response) => {
  const success = deleteAnnotation(req.params.id);
  if (!success) {
    res.status(404).json({ error: 'Annotation not found' });
    return;
  }
  res.json({ success: true });
});

export default router;
