import { describe, expect, it } from "vitest";
import { appRouter } from "./routers";
import type { TrpcContext } from "./_core/context";

function createMockContext(): TrpcContext {
  return {
    user: null,
    req: {
      protocol: "https",
      headers: {},
    } as TrpcContext["req"],
    res: {} as TrpcContext["res"],
  };
}

describe("portfolio procedures", () => {
  it("should get all published projects", async () => {
    const ctx = createMockContext();
    const caller = appRouter.createCaller(ctx);

    const projects = await caller.portfolio.getAll();

    expect(Array.isArray(projects)).toBe(true);
    expect(projects.length).toBeGreaterThan(0);
    
    // Verify structure
    if (projects.length > 0) {
      const project = projects[0];
      expect(project).toHaveProperty("id");
      expect(project).toHaveProperty("title");
      expect(project).toHaveProperty("slug");
      expect(project).toHaveProperty("published");
      expect(project.published).toBe(true);
    }
  });

  it("should get featured projects only", async () => {
    const ctx = createMockContext();
    const caller = appRouter.createCaller(ctx);

    const projects = await caller.portfolio.getFeatured();

    expect(Array.isArray(projects)).toBe(true);
    
    // All returned projects should be featured
    projects.forEach((project) => {
      expect(project.featured).toBe(true);
      expect(project.published).toBe(true);
    });
  });

  it("should get project by slug", async () => {
    const ctx = createMockContext();
    const caller = appRouter.createCaller(ctx);

    const project = await caller.portfolio.getBySlug({ slug: "aurum-co-ecommerce" });

    expect(project).not.toBeNull();
    if (project) {
      expect(project.slug).toBe("aurum-co-ecommerce");
      expect(project.title).toBeTruthy();
      expect(Array.isArray(project.images)).toBe(true);
      expect(Array.isArray(project.technologies)).toBe(true);
    }
  });

  it("should return null for non-existent project", async () => {
    const ctx = createMockContext();
    const caller = appRouter.createCaller(ctx);

    const project = await caller.portfolio.getBySlug({ slug: "non-existent-project" });

    expect(project).toBeNull();
  });
});

describe("blog procedures", () => {
  it("should get all published articles", async () => {
    const ctx = createMockContext();
    const caller = appRouter.createCaller(ctx);

    const articles = await caller.blog.getAll();

    expect(Array.isArray(articles)).toBe(true);
    // Articles may have been unpublished by previous tests
    if (articles.length > 0) {
      const article = articles[0];
      expect(article).toHaveProperty("id");
      expect(article).toHaveProperty("title");
      expect(article).toHaveProperty("slug");
      expect(article).toHaveProperty("published");
      expect(article.published).toBe(true);
    }
  });

  it("should get recent articles with limit", async () => {
    const ctx = createMockContext();
    const caller = appRouter.createCaller(ctx);

    const articles = await caller.blog.getRecent({ limit: 2 });

    expect(Array.isArray(articles)).toBe(true);
    expect(articles.length).toBeLessThanOrEqual(2);
  });

  it("should get article by slug", async () => {
    const ctx = createMockContext();
    const caller = appRouter.createCaller(ctx);

    const article = await caller.blog.getBySlug({ slug: "optimiser-seo-site-web-2025" });

    expect(article).not.toBeNull();
    if (article) {
      expect(article.slug).toBe("optimiser-seo-site-web-2025");
      expect(article.title).toBeTruthy();
      expect(article.content).toBeTruthy();
      expect(Array.isArray(article.tags)).toBe(true);
    }
  });

  it("should return null for non-existent article", async () => {
    const ctx = createMockContext();
    const caller = appRouter.createCaller(ctx);

    const article = await caller.blog.getBySlug({ slug: "non-existent-article" });

    expect(article).toBeNull();
  });
});
