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

// Create a test context
function createTestContext(): TrpcContext {
  return {
    user: null,
    req: {
      protocol: "https",
      headers: {},
    } as TrpcContext["req"],
    res: {
      clearCookie: () => {},
    } as TrpcContext["res"],
  };
}

describe("tRPC Routers", () => {
  describe("services", () => {
    it("should fetch all services", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      const services = await caller.services.getAll();
      
      expect(Array.isArray(services)).toBe(true);
      if (services.length > 0) {
        expect(services[0]).toHaveProperty("id");
        expect(services[0]).toHaveProperty("name");
        expect(services[0]).toHaveProperty("slug");
        expect(services[0]).toHaveProperty("shortDescription");
      }
    }, 15000);

    it("should fetch service by slug", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      const service = await caller.services.getBySlug({ slug: "daily-personal-activities" });
      
      if (service) {
        expect(service.slug).toBe("daily-personal-activities");
        expect(service.name).toBe("Daily Personal Activities");
      }
    }, 15000);
  });

  describe("faqs", () => {
    it("should fetch all FAQs", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      const faqs = await caller.faqs.getAll();
      
      expect(Array.isArray(faqs)).toBe(true);
      if (faqs.length > 0) {
        expect(faqs[0]).toHaveProperty("id");
        expect(faqs[0]).toHaveProperty("category");
        expect(faqs[0]).toHaveProperty("question");
        expect(faqs[0]).toHaveProperty("answer");
      }
    });

    it("should fetch FAQs by category", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      const faqs = await caller.faqs.getByCategory({ category: "Services" });
      
      expect(Array.isArray(faqs)).toBe(true);
      if (faqs.length > 0) {
        expect(faqs[0].category).toBe("Services");
      }
    });
  });

  describe("testimonials", () => {
    it("should fetch all testimonials", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      const testimonials = await caller.testimonials.getAll();
      
      expect(Array.isArray(testimonials)).toBe(true);
      if (testimonials.length > 0) {
        expect(testimonials[0]).toHaveProperty("id");
        expect(testimonials[0]).toHaveProperty("clientName");
        expect(testimonials[0]).toHaveProperty("content");
      }
    });
  });

  describe("gallery", () => {
    it("should fetch all gallery images", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      const images = await caller.gallery.getAll();
      
      expect(Array.isArray(images)).toBe(true);
    });
  });

  describe("blog", () => {
    it("should fetch all published blog posts", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      const posts = await caller.blog.getAllPublished();
      
      expect(Array.isArray(posts)).toBe(true);
      if (posts.length > 0) {
        expect(posts[0]).toHaveProperty("id");
        expect(posts[0]).toHaveProperty("title");
        expect(posts[0]).toHaveProperty("slug");
        expect(posts[0].isPublished).toBe(true);
      }
    });

    it("should fetch blog post by slug", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      const post = await caller.blog.getBySlug({ slug: "understanding-ndis-plan-beginners-guide" });
      
      if (post) {
        expect(post.slug).toBe("understanding-ndis-plan-beginners-guide");
        expect(post.isPublished).toBe(true);
      }
    });
  });

  describe("contact", () => {
    it("should validate contact form submission", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      
      try {
        await caller.contact.submit({
          name: "John Doe",
          email: "john@example.com",
          phone: "0212345678",
          message: "This is a test message",
          serviceInterest: "Daily Personal Activities",
        });
      } catch (error) {
        // Expected to fail if database is not available, but validation should pass
        expect(error).toBeDefined();
      }
    });

    it("should reject invalid email", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      
      try {
        await caller.contact.submit({
          name: "John Doe",
          email: "invalid-email",
          phone: "0212345678",
          message: "This is a test message",
        });
        expect.fail("Should have thrown validation error");
      } catch (error) {
        expect(error).toBeDefined();
      }
    });

    it("should reject short message", async () => {
      const ctx = createTestContext();
      const caller = appRouter.createCaller(ctx);
      
      try {
        await caller.contact.submit({
          name: "John Doe",
          email: "john@example.com",
          phone: "0212345678",
          message: "short",
        });
        expect.fail("Should have thrown validation error");
      } catch (error) {
        expect(error).toBeDefined();
      }
    });
  });
});
