const express = require('express');
const { v4: uuidv4 } = require('uuid');
const router = express.Router();

module.exports = (pool, query, authMiddleware) => {
  // Get all published blog posts (public)
  router.get('/', async (req, res, next) => {
    try {
      const { category, tag, search, page = 1, limit = 10 } = req.query;
      const offset = (page - 1) * limit;
      
      let whereConditions = ["b.status = 'published'"];
      const params = [];
      let paramIndex = 1;
      
      // Filter by category
      if (category) {
        params.push(category);
        whereConditions.push(`bc.name = $${paramIndex}`);
        paramIndex++;
      }
      
      // Filter by tag 
      if (tag) {
        params.push(tag);
        whereConditions.push(`t.name = $${paramIndex}`);
        paramIndex++;
      }
      
      // Search functionality
      if (search) {
        params.push(`%${search}%`);
        whereConditions.push(`(b.title ILIKE $${paramIndex} OR b.excerpt ILIKE $${paramIndex} OR b.content ILIKE $${paramIndex})`);
        paramIndex++;
      }
      
      // Prepare WHERE clause
      const whereClause = whereConditions.length > 0 
        ? `WHERE ${whereConditions.join(' AND ')}` 
        : '';
      
      // Get total count for pagination
      const countQuery = `
        SELECT COUNT(DISTINCT b.id) 
        FROM blog_posts b
        LEFT JOIN blog_categories bc ON b.category_id = bc.id
        LEFT JOIN blog_post_tags bpt ON b.id = bpt.post_id
        LEFT JOIN tags t ON bpt.tag_id = t.id
        ${whereClause}
      `;
      
      const countResult = await query(countQuery, params);
      const total = parseInt(countResult.rows[0].count);
      
      // Query posts with all related data
      const postsQuery = `
        SELECT 
          b.id, b.title, b.slug, b.excerpt, b.featured_image_path,
          b.published_at, b.created_at, b.updated_at,
          u.id as author_id, u.first_name as author_first_name, u.last_name as author_last_name,
          bc.id as category_id, bc.name as category_name,
          ARRAY_AGG(DISTINCT t.name) FILTER (WHERE t.name IS NOT NULL) AS tags,
          COUNT(DISTINCT c.id) as comment_count
        FROM blog_posts b
        LEFT JOIN users u ON b.author_id = u.id
        LEFT JOIN blog_categories bc ON b.category_id = bc.id
        LEFT JOIN blog_post_tags bpt ON b.id = bpt.post_id
        LEFT JOIN tags t ON bpt.tag_id = t.id
        LEFT JOIN blog_comments c ON b.id = c.post_id AND c.is_approved = true
        ${whereClause}
        GROUP BY b.id, u.id, bc.id
        ORDER BY b.published_at DESC
        LIMIT $${paramIndex} OFFSET $${paramIndex + 1}
      `;
      
      params.push(parseInt(limit), parseInt(offset));
      const result = await query(postsQuery, params);
      
      res.json({
        posts: result.rows,
        pagination: {
          page: parseInt(page),
          limit: parseInt(limit),
          total,
          pages: Math.ceil(total / limit)
        }
      });
    } catch (error) {
      next(error);
    }
  });
  
  // Get single blog post by slug (public)
  router.get('/:slug', async (req, res, next) => {
    try {
      const { slug } = req.params;
      
      // Get post with author, category, and tags
      const postQuery = `
        SELECT 
          b.id, b.title, b.slug, b.content, b.excerpt, 
          b.featured_image_path, b.status, b.published_at, 
          b.created_at, b.updated_at,
          u.id as author_id, u.first_name as author_first_name, u.last_name as author_last_name,
          bc.id as category_id, bc.name as category_name,
          ARRAY_AGG(DISTINCT t.name) FILTER (WHERE t.name IS NOT NULL) AS tags
        FROM blog_posts b
        LEFT JOIN users u ON b.author_id = u.id
        LEFT JOIN blog_categories bc ON b.category_id = bc.id
        LEFT JOIN blog_post_tags bpt ON b.id = bpt.post_id
        LEFT JOIN tags t ON bpt.tag_id = t.id
        WHERE b.slug = $1 AND b.status = 'published'
        GROUP BY b.id, u.id, bc.id
      `;
      
      const postResult = await query(postQuery, [slug]);
      
      if (postResult.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Blog post not found'
        });
      }
      
      const post = postResult.rows[0];
      
      // Get post images
      const imagesQuery = `
        SELECT id, image_path, caption, display_order
        FROM blog_post_images
        WHERE post_id = $1
        ORDER BY display_order
      `;
      
      const imagesResult = await query(imagesQuery, [post.id]);
      
      // Get approved comments
      const commentsQuery = `
        SELECT 
          c.id, c.content, c.created_at,
          c.parent_id,
          u.id as user_id, u.first_name, u.last_name
        FROM blog_comments c
        JOIN users u ON c.user_id = u.id
        WHERE c.post_id = $1 AND c.is_approved = true
        ORDER BY c.created_at
      `;
      
      const commentsResult = await query(commentsQuery, [post.id]);
      
      // Organize comments into threads
      const commentThreads = [];
      const commentMap = {};
      
      commentsResult.rows.forEach(comment => {
        commentMap[comment.id] = {
          ...comment,
          replies: []
        };
      });
      
      // Then, organize into threads
      commentsResult.rows.forEach(comment => {
        if (comment.parent_id) {
          // This is a reply
          if (commentMap[comment.parent_id]) {
            commentMap[comment.parent_id].replies.push(commentMap[comment.id]);
          }
        } else {
          // This is a top-level comment
          commentThreads.push(commentMap[comment.id]);
        }
      });
      
      res.json({
        ...post,
        images: imagesResult.rows,
        comments: commentThreads
      });
    } catch (error) {
      next(error);
    }
  });
  
  // Get blog categories (public)
  router.get('/categories/all', async (req, res, next) => {
    try {
      const result = await query('SELECT * FROM blog_categories ORDER BY name');
      res.json(result.rows);
    } catch (error) {
      next(error);
    }
  });
  
  router.use(authMiddleware);
  // Add comment to a blog post (authenticated users only)
  router.post('/:postId/comments', async (req, res, next) => {
    try {
      const { postId } = req.params;
      const { content, parentId, userId } = req.body;
      // Check if user is authenticated
      if (req.user.id !== userId) {
        return res.status(401).json({
          error: true,
          message: 'You must be logged in to comment'
        });
      }
      
      
      // Validate content
      if (!content || content.trim() === '') {
        return res.status(400).json({
          error: true,
          message: 'Comment content is required'
        });
      }
      
      // Check if post exists and is published
      const postCheck = await query(
        "SELECT id FROM blog_posts WHERE id = $1 AND status = 'published'",
        [postId]
      );
      
      if (postCheck.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Blog post not found or not published'
        });
      }
      
      // If this is a reply, check if parent comment exists
      if (parentId) {
        const parentCheck = await query(
          'SELECT id FROM blog_comments WHERE id = $1 AND post_id = $2',
          [parentId, postId]
        );
        
        if (parentCheck.rows.length === 0) {
          return res.status(404).json({
            error: true,
            message: 'Parent comment not found'
          });
        }
      }
      
      const isApproved = req.user.is_admin ? true : false;
      
      // Insert comment
      const result = await query(
        `INSERT INTO blog_comments 
         (id, post_id, user_id, parent_id, content, is_approved) 
         VALUES ($1, $2, $3, $4, $5, $6)
         RETURNING *`,
        [uuidv4(), postId, userId, parentId || null, content, isApproved]
      );
      
      // Get user info for the response
      const userResult = await query(
        'SELECT first_name, last_name FROM users WHERE id = $1',
        [userId]
      );
      
      const comment = {
        ...result.rows[0],
        first_name: userResult.rows[0].first_name,
        last_name: userResult.rows[0].last_name,
        replies: []
      };
      
      res.status(201).json({
        message: isApproved 
          ? 'Comment added successfully' 
          : 'Comment submitted and awaiting approval',
        comment
      });
    } catch (error) {
      next(error);
    }
  });
  
  return router;
};