import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import { prisma } from '@shieldai/db';

interface CreatePostBody {
  slug: string;
  title: string;
  excerpt?: string;
  content: string;
  authorName?: string;
  coverImageUrl?: string;
  tags?: string[];
  published?: boolean;
  publishedAt?: string;
}

export async function blogAdminRoutes(fastify: FastifyInstance) {
  fastify.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as FastifyRequest & { user?: { id: string; role?: string } };
    const user = authReq.user;

    if (!user) {
      return reply.code(401).send({ error: 'Unauthorized' });
    }

    if (user.role !== 'support') {
      return reply.code(403).send({ error: 'Admin access required' });
    }
  });

  fastify.post('/admin/blog', async (request: FastifyRequest, reply: FastifyReply) => {
    const body = request.body as CreatePostBody;

    if (!body.slug || !/^[a-z0-9-]+$/.test(body.slug)) {
      return reply.code(400).send({ error: 'Invalid slug: must be lowercase alphanumeric with hyphens' });
    }
    if (!body.title || body.title.length > 200) {
      return reply.code(400).send({ error: 'Title is required (max 200 chars)' });
    }
    if (!body.content) {
      return reply.code(400).send({ error: 'Content is required' });
    }

    const existing = await prisma.blogPost.findUnique({
      where: { slug: body.slug },
    });

    if (existing) {
      return reply.code(409).send({ error: 'A post with this slug already exists' });
    }

    const post = await prisma.blogPost.create({
      data: {
        slug: body.slug,
        title: body.title,
        excerpt: body.excerpt || null,
        content: body.content,
        authorName: body.authorName || null,
        coverImageUrl: body.coverImageUrl || null,
        tags: body.tags || [],
        published: body.published || false,
        publishedAt: body.publishedAt
          ? new Date(body.publishedAt)
          : body.published
            ? new Date()
            : null,
      },
    });

    return reply.code(201).send({ post });
  });

  fastify.put('/admin/blog/:id', async (request: FastifyRequest, reply: FastifyReply) => {
    const { id } = request.params as { id: string };
    const body = request.body as Partial<CreatePostBody>;

    const existing = await prisma.blogPost.findUnique({ where: { id } });
    if (!existing) {
      return reply.code(404).send({ error: 'Post not found' });
    }

    if (body.slug && body.slug !== existing.slug) {
      const slugExists = await prisma.blogPost.findUnique({ where: { slug: body.slug } });
      if (slugExists) {
        return reply.code(409).send({ error: 'A post with this slug already exists' });
      }
    }

    const post = await prisma.blogPost.update({
      where: { id },
      data: {
        ...(body.slug !== undefined && { slug: body.slug }),
        ...(body.title !== undefined && { title: body.title }),
        ...(body.excerpt !== undefined && { excerpt: body.excerpt }),
        ...(body.content !== undefined && { content: body.content }),
        ...(body.authorName !== undefined && { authorName: body.authorName }),
        ...(body.coverImageUrl !== undefined && { coverImageUrl: body.coverImageUrl }),
        ...(body.tags !== undefined && { tags: body.tags }),
        ...(body.published !== undefined && { published: body.published }),
        publishedAt: body.publishedAt
          ? new Date(body.publishedAt)
          : body.published === true && !existing.published
            ? new Date()
            : undefined,
      },
    });

    return reply.send({ post });
  });

  fastify.delete('/admin/blog/:id', async (request: FastifyRequest, reply: FastifyReply) => {
    const { id } = request.params as { id: string };
    await prisma.blogPost.delete({ where: { id } });
    return reply.code(204).send();
  });

  fastify.get('/admin/blog', async (request: FastifyRequest, reply: FastifyReply) => {
    const query = request.query as { page?: string; limit?: string };
    const page = Math.max(1, parseInt(query.page || '1', 10));
    const limit = Math.min(50, Math.max(1, parseInt(query.limit || '20', 10)));
    const skip = (page - 1) * limit;

    const [posts, total] = await Promise.all([
      prisma.blogPost.findMany({
        orderBy: { createdAt: 'desc' },
        skip,
        take: limit,
      }),
      prisma.blogPost.count(),
    ]);

    return reply.send({
      posts,
      pagination: { page, limit, total, totalPages: Math.ceil(total / limit) },
    });
  });
}
