import { Router, Response, Request } from 'express';
import { body, validationResult, query } from 'express-validator';
import { Page } from '../models/index.js';
import { authenticate, requireRole, AuthRequest } from '../middleware/auth.js';

const router = Router();

// GET /api/pages - Public: Get all published pages
router.get('/', async (req: Request, res: Response): Promise<void> => {
  try {
    const pages = await Page.find({ status: 'published' })
      .select('title slug excerpt featuredImage template publishedAt')
      .sort({ publishedAt: -1 });

    res.json(pages);
  } catch (error) {
    res.status(500).json({ error: 'Server error' });
  }
});

// GET /api/pages/admin - Admin: Get all pages
router.get('/admin', authenticate, async (req: AuthRequest, res: Response): Promise<void> => {
  try {
    const { status, page = 1, limit = 10 } = req.query;
    
    const query: Record<string, unknown> = {};
    if (status) query.status = status;

    const pages = await Page.find(query)
      .populate('author', 'name email')
      .sort({ updatedAt: -1 })
      .skip((Number(page) - 1) * Number(limit))
      .limit(Number(limit));

    const total = await Page.countDocuments(query);

    res.json({
      pages,
      pagination: {
        page: Number(page),
        limit: Number(limit),
        total,
        pages: Math.ceil(total / Number(limit)),
      },
    });
  } catch (error) {
    res.status(500).json({ error: 'Server error' });
  }
});

// GET /api/pages/admin/:id - Admin: Get page by ID
router.get('/admin/:id', authenticate, async (req: AuthRequest, res: Response): Promise<void> => {
  try {
    const page = await Page.findById(req.params.id).populate('author', 'name email');
    if (!page) {
      res.status(404).json({ error: 'Page not found' });
      return;
    }
    res.json(page);
  } catch (error) {
    res.status(500).json({ error: 'Server error' });
  }
});

// GET /api/pages/:slug - Public: Get page by slug
router.get('/:slug', async (req: Request, res: Response): Promise<void> => {
  try {
    const page = await Page.findOne({
      slug: req.params.slug,
      status: 'published',
    }).populate('author', 'name');

    if (!page) {
      res.status(404).json({ error: 'Page not found' });
      return;
    }

    res.json(page);
  } catch (error) {
    res.status(500).json({ error: 'Server error' });
  }
});

// POST /api/pages - Admin: Create page
router.post(
  '/',
  authenticate,
  requireRole('admin', 'editor'),
  [
    body('title.en').trim().notEmpty().withMessage('English title is required'),
    body('template').optional().isIn(['default', 'landing', 'about', 'services', 'contact', 'custom']),
  ],
  async (req: AuthRequest, res: Response): Promise<void> => {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        res.status(400).json({ errors: errors.array() });
        return;
      }

      const page = new Page({
        ...req.body,
        author: req.user!._id,
      });

      await page.save();
      res.status(201).json(page);
    } catch (error: unknown) {
      if (error && typeof error === 'object' && 'code' in error && (error as { code: number }).code === 11000) {
        res.status(400).json({ error: 'A page with this slug already exists' });
        return;
      }
      res.status(500).json({ error: 'Server error' });
    }
  }
);

// PUT /api/pages/:id - Admin: Update page
router.put(
  '/:id',
  authenticate,
  requireRole('admin', 'editor'),
  async (req: AuthRequest, res: Response): Promise<void> => {
    try {
      const page = await Page.findByIdAndUpdate(
        req.params.id,
        { $set: req.body },
        { new: true, runValidators: true }
      );

      if (!page) {
        res.status(404).json({ error: 'Page not found' });
        return;
      }

      res.json(page);
    } catch (error: unknown) {
      if (error && typeof error === 'object' && 'code' in error && (error as { code: number }).code === 11000) {
        res.status(400).json({ error: 'A page with this slug already exists' });
        return;
      }
      res.status(500).json({ error: 'Server error' });
    }
  }
);

// DELETE /api/pages/:id - Admin: Delete page
router.delete(
  '/:id',
  authenticate,
  requireRole('admin'),
  async (req: AuthRequest, res: Response): Promise<void> => {
    try {
      const page = await Page.findByIdAndDelete(req.params.id);

      if (!page) {
        res.status(404).json({ error: 'Page not found' });
        return;
      }

      res.json({ message: 'Page deleted successfully' });
    } catch (error) {
      res.status(500).json({ error: 'Server error' });
    }
  }
);

export default router;
