import { Request, Response } from 'express';
import prisma from '../config/database';
import { sendSuccess, sendError } from '../utils/response.utils';
import { AuthenticatedRequest } from '../middleware/auth.middleware';

// 1. Get List of Published Blog Posts
export const getBlogs = async (req: Request, res: Response) => {
  try {
    const { category, tag, search, status = 'PUBLISHED', limit = 10, page = 1 } = req.query;

    const take = Number(limit);
    const skip = (Number(page) - 1) * take;

    const where: any = {};
    if (status) where.status = String(status) as any;
    if (category) where.category = String(category);
    if (search) {
      where.OR = [
        { title: { contains: String(search) } },
        { content: { contains: String(search) } },
      ];
    }

    const [blogs, total] = await Promise.all([
      prisma.blog.findMany({
        where,
        take,
        skip,
        include: {
          _count: { select: { comments: true } },
        },
        orderBy: { publishedAt: 'desc' },
      }),
      prisma.blog.count({ where }),
    ]);

    return sendSuccess(res, 'Blogs retrieved successfully', {
      blogs,
      pagination: {
        total,
        page: Number(page),
        limit: take,
        totalPages: Math.ceil(total / take),
      },
    });
  } catch (error: any) {
    return sendError(res, 'Error fetching blogs', error.message, 500);
  }
};

// 2. Get Single Blog Detail by Slug (Increments Views & Fetches Related Posts)
export const getBlogBySlug = async (req: Request, res: Response) => {
  try {
    const { slug } = req.params;

    const blog = await prisma.blog.findUnique({
      where: { slug },
      include: {
        comments: {
          where: { isApproved: true },
          orderBy: { createdAt: 'desc' },
        },
      },
    });

    if (!blog) {
      return sendError(res, 'Blog post not found', null, 404);
    }

    // Increment View Counter asynchronously
    await prisma.blog.update({
      where: { id: blog.id },
      data: { viewsCount: { increment: 1 } },
    }).catch(() => null);

    // Fetch 3 Related Blogs in Same Category
    const relatedBlogs = await prisma.blog.findMany({
      where: {
        category: blog.category,
        id: { not: blog.id },
        status: 'PUBLISHED',
      },
      take: 3,
      orderBy: { publishedAt: 'desc' },
    });

    // Social Share Links metadata generator
    const shareUrl = `${process.env.FRONTEND_URL || 'http://localhost:3000'}/blog/${blog.slug}`;
    const socialShares = {
      twitter: `https://twitter.com/intent/tweet?text=${encodeURIComponent(blog.title)}&url=${encodeURIComponent(shareUrl)}`,
      facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareUrl)}`,
      linkedin: `https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(shareUrl)}&title=${encodeURIComponent(blog.title)}`,
      whatsapp: `https://api.whatsapp.com/send?text=${encodeURIComponent(`${blog.title} - ${shareUrl}`)}`,
    };

    return sendSuccess(res, 'Blog detail retrieved', {
      blog,
      relatedBlogs,
      socialShares,
    });
  } catch (error: any) {
    return sendError(res, 'Error fetching blog detail', error.message, 500);
  }
};

// 3. Create Blog Post (Admin)
export const createBlog = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const {
      title,
      slug,
      content,
      excerpt,
      coverImage,
      authorName = 'IBW Editorial',
      authorAvatar,
      category = 'Literary News',
      tags = [],
      status = 'PUBLISHED',
      metaTitle,
      metaDescription,
      publishedAt,
    } = req.body;

    const generatedSlug = slug || title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)+/g, '');

    const blog = await prisma.blog.create({
      data: {
        title,
        slug: generatedSlug,
        content,
        excerpt: excerpt || content.substring(0, 150),
        coverImage,
        authorName,
        authorAvatar,
        category,
        tags,
        status: status as any,
        metaTitle: metaTitle || title,
        metaDescription: metaDescription || excerpt || content.substring(0, 160),
        publishedAt: publishedAt ? new Date(publishedAt) : new Date(),
      },
    });

    return sendSuccess(res, 'Blog post created successfully', blog, 201);
  } catch (error: any) {
    return sendError(res, 'Error creating blog post', error.message, 500);
  }
};

// 4. Update Blog Post (Admin)
export const updateBlog = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { id } = req.params;
    const updateData = req.body;

    const updatedBlog = await prisma.blog.update({
      where: { id },
      data: updateData,
    });

    return sendSuccess(res, 'Blog post updated successfully', updatedBlog);
  } catch (error: any) {
    return sendError(res, 'Error updating blog post', error.message, 500);
  }
};

// 5. Delete Blog Post (Admin)
export const deleteBlog = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { id } = req.params;
    await prisma.blog.delete({ where: { id } });
    return sendSuccess(res, 'Blog post deleted successfully');
  } catch (error: any) {
    return sendError(res, 'Error deleting blog post', error.message, 500);
  }
};

// 6. Post Comment on Blog
export const addBlogComment = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { blogId, authorName, content } = req.body;
    const userId = req.user?.userId;

    const comment = await prisma.blogComment.create({
      data: {
        blogId,
        userId,
        authorName,
        content,
        isApproved: true,
      },
    });

    return sendSuccess(res, 'Comment published successfully', comment, 201);
  } catch (error: any) {
    return sendError(res, 'Failed to post comment', error.message, 500);
  }
};
