/**
 * Blog Management API Tests
 * Tests for staff dashboard blog CRUD operations
 */

import { describe, it, expect, beforeAll, afterAll } from "@jest/globals";
import {
  validateCreateBlogPost,
  calculateReadingTime,
  generateSlugFromTitle,
} from "@/lib/validators/blog-management.validator";
import { sanitizeCreateBlogPostInput } from "@/lib/sanitizers/blog-management.sanitizer";
import type { CreateBlogPostInput } from "@/lib/types/blog-management.types";

describe("Blog Management Validators", () => {
  describe("validateCreateBlogPost", () => {
    it("should validate correct blog post input", () => {
      const validInput: CreateBlogPostInput = {
        title: "Test Blog Post Title",
        slug: "test-blog-post",
        lang: "en",
        excerpt: "This is a test excerpt for the blog post",
        content: "This is test content. ".repeat(20), // > 100 chars
        author: "Test Author",
        tags: ["test", "blog"],
        status: "DRAFT",
      };

      expect(() => validateCreateBlogPost(validInput)).not.toThrow();
    });

    it("should reject title that is too short", () => {
      const invalidInput: CreateBlogPostInput = {
        title: "Test",
        slug: "test",
        lang: "en",
        excerpt: "This is a test excerpt for the blog post",
        content: "Content ".repeat(20),
        author: "Test",
      };

      expect(() => validateCreateBlogPost(invalidInput)).toThrow(
        "Title must be between 5 and 200 characters",
      );
    });

    it("should reject invalid slug format", () => {
      const invalidInput: CreateBlogPostInput = {
        title: "Valid Title Here",
        slug: "Invalid Slug With Spaces",
        lang: "en",
        excerpt: "This is a test excerpt for the blog post",
        content: "Content ".repeat(20),
        author: "Test",
      };

      expect(() => validateCreateBlogPost(invalidInput)).toThrow(
        "Slug must contain only lowercase letters",
      );
    });

    it("should reject content that is too short", () => {
      const invalidInput: CreateBlogPostInput = {
        title: "Valid Title",
        slug: "valid-slug",
        lang: "en",
        excerpt: "This is a valid excerpt for testing",
        content: "Too short",
        author: "Test",
      };

      expect(() => validateCreateBlogPost(invalidInput)).toThrow(
        "Content must be at least 100 characters",
      );
    });

    it("should reject too many tags", () => {
      const invalidInput: CreateBlogPostInput = {
        title: "Valid Title",
        slug: "valid-slug",
        lang: "en",
        excerpt: "This is a valid excerpt for testing",
        content: "Content ".repeat(20),
        author: "Test",
        tags: [
          "tag1",
          "tag2",
          "tag3",
          "tag4",
          "tag5",
          "tag6",
          "tag7",
          "tag8",
          "tag9",
          "tag10",
          "tag11",
        ],
      };

      expect(() => validateCreateBlogPost(invalidInput)).toThrow(
        "Maximum 10 tags allowed",
      );
    });

    it("should reject invalid status", () => {
      const invalidInput: any = {
        title: "Valid Title",
        slug: "valid-slug",
        lang: "en",
        excerpt: "This is a valid excerpt for testing",
        content: "Content ".repeat(20),
        author: "Test",
        status: "INVALID_STATUS",
      };

      expect(() => validateCreateBlogPost(invalidInput)).toThrow(
        "Status must be one of",
      );
    });
  });

  describe("calculateReadingTime", () => {
    it("should calculate reading time for short content", () => {
      const content =
        "This is a short blog post with about fifty words. ".repeat(1);
      const readingTime = calculateReadingTime(content);
      expect(readingTime).toBeGreaterThanOrEqual(1);
    });

    it("should calculate reading time for long content", () => {
      const content = "Word ".repeat(400); // 400 words = ~2 minutes
      const readingTime = calculateReadingTime(content);
      expect(readingTime).toBeGreaterThanOrEqual(2);
      expect(readingTime).toBeLessThanOrEqual(3);
    });

    it("should return minimum 1 minute for very short content", () => {
      const content = "Just a few words here";
      const readingTime = calculateReadingTime(content);
      expect(readingTime).toBe(1);
    });
  });

  describe("generateSlugFromTitle", () => {
    it("should generate slug from English title", () => {
      const title = "How to Improve Patient Experience";
      const slug = generateSlugFromTitle(title, "en");
      expect(slug).toBe("how-to-improve-patient-experience");
    });

    it("should handle special characters", () => {
      const title = "5 Ways to Optimize Your Clinic's Workflow!";
      const slug = generateSlugFromTitle(title, "en");
      expect(slug).toBe("5-ways-to-optimize-your-clinics-workflow");
    });

    it("should handle Arabic titles with timestamp", () => {
      const title = "كيفية تحسين تجربة المرضى";
      const slug = generateSlugFromTitle(title, "ar");
      expect(slug).toMatch(/^blog-\d+$/);
    });

    it("should remove multiple consecutive hyphens", () => {
      const title = "Test    Multiple    Spaces";
      const slug = generateSlugFromTitle(title, "en");
      expect(slug).toBe("test-multiple-spaces");
    });
  });
});

describe("Blog Management Sanitizers", () => {
  it("should sanitize HTML from title", () => {
    const input: CreateBlogPostInput = {
      title: '<script>alert("xss")</script>Safe Title',
      slug: "test",
      lang: "en",
      excerpt: "Test excerpt for sanitization",
      content: "Content ".repeat(20),
      author: "Test",
    };

    const sanitized = sanitizeCreateBlogPostInput(input);
    expect(sanitized.title).not.toContain("<script>");
    expect(sanitized.title).toContain("Safe Title");
  });

  it("should preserve safe HTML in content", () => {
    const input: CreateBlogPostInput = {
      title: "Test Title",
      slug: "test",
      lang: "en",
      excerpt: "Test excerpt",
      content:
        '<p>Safe paragraph</p><strong>Bold text</strong><script>alert("bad")</script>',
      author: "Test",
    };

    const sanitized = sanitizeCreateBlogPostInput(input);
    expect(sanitized.content).toContain("<p>");
    expect(sanitized.content).toContain("<strong>");
    expect(sanitized.content).not.toContain("<script>");
  });

  it("should sanitize and normalize tags", () => {
    const input: CreateBlogPostInput = {
      title: "Test Title",
      slug: "test",
      lang: "en",
      excerpt: "Test excerpt for the blog post",
      content: "Content ".repeat(20),
      author: "Test",
      tags: ["  TAG1  ", "Tag2", "<script>xss</script>", "NORMAL"],
    };

    const sanitized = sanitizeCreateBlogPostInput(input);
    expect(sanitized.tags).toEqual(["tag1", "tag2", "normal"]);
  });

  it("should limit tags to 10", () => {
    const input: CreateBlogPostInput = {
      title: "Test Title",
      slug: "test",
      lang: "en",
      excerpt: "Test excerpt for the blog post",
      content: "Content ".repeat(20),
      author: "Test",
      tags: Array.from({ length: 15 }, (_, i) => `tag${i}`),
    };

    const sanitized = sanitizeCreateBlogPostInput(input);
    expect(sanitized.tags?.length).toBeLessThanOrEqual(10);
  });
});
