/**
 * Tests for Review Validator Zod Schemas
 */

import {
  CreateReviewRequestSchema,
  BulkReviewRequestSchema,
  SubmitReviewWithQuestionsSchema,
  ToggleFeaturedSchema,
  ReorderFeaturedSchema,
  WidgetSettingsSchema,
  GenerateQuestionsSchema,
} from "@/lib/validators/reviews.validator";

// =============================================================================
// CreateReviewRequestSchema — includes new bookingId / source / questions fields
// =============================================================================

describe("CreateReviewRequestSchema", () => {
  const base = { customerName: "Ali Hassan", channel: "email" as const };

  it("accepts minimal valid input with defaults", () => {
    const result = CreateReviewRequestSchema.safeParse(base);
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.source).toBe("manual");
      expect(result.data.language).toBe("en");
      expect(result.data.channel).toBe("email");
    }
  });

  it("accepts bookingId and source=auto_booking", () => {
    const result = CreateReviewRequestSchema.safeParse({
      ...base,
      bookingId: "booking-abc",
      source: "auto_booking" as const,
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.bookingId).toBe("booking-abc");
      expect(result.data.source).toBe("auto_booking");
    }
  });

  it("accepts a questions array", () => {
    const result = CreateReviewRequestSchema.safeParse({
      ...base,
      questions: [
        { questionEn: "How was it?", questionAr: "كيف كانت؟" },
        { questionEn: "Would you recommend us?" },
      ],
    });
    expect(result.success).toBe(true);
    if (result.success) expect(result.data.questions).toHaveLength(2);
  });

  it("accepts null bookingId", () => {
    const result = CreateReviewRequestSchema.safeParse({
      ...base,
      bookingId: null,
    });
    expect(result.success).toBe(true);
  });

  it("accepts null questions", () => {
    const result = CreateReviewRequestSchema.safeParse({
      ...base,
      questions: null,
    });
    expect(result.success).toBe(true);
  });

  it("rejects invalid source value", () => {
    const result = CreateReviewRequestSchema.safeParse({
      ...base,
      source: "cron_magic",
    });
    expect(result.success).toBe(false);
  });

  it("rejects missing customerName", () => {
    const result = CreateReviewRequestSchema.safeParse({ channel: "email" });
    expect(result.success).toBe(false);
  });

  it("rejects invalid channel value", () => {
    const result = CreateReviewRequestSchema.safeParse({
      customerName: "Test",
      channel: "telegram",
    });
    expect(result.success).toBe(false);
  });

  it("rejects invalid email format", () => {
    const result = CreateReviewRequestSchema.safeParse({
      ...base,
      customerEmail: "not-an-email",
    });
    expect(result.success).toBe(false);
  });

  it("accepts language=ar", () => {
    const result = CreateReviewRequestSchema.safeParse({
      ...base,
      language: "ar" as const,
    });
    expect(result.success).toBe(true);
    if (result.success) expect(result.data.language).toBe("ar");
  });
});

describe("BulkReviewRequestSchema", () => {
  it("accepts a valid request array", () => {
    const input = {
      requests: [
        {
          customerName: "John",
          customerEmail: "john@test.com",
          channel: "email" as const,
        },
        {
          customerName: "Jane",
          customerPhone: "+97412345678",
          channel: "whatsapp" as const,
        },
      ],
      language: "en" as const,
    };
    const result = BulkReviewRequestSchema.safeParse(input);
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.requests).toHaveLength(2);
      expect(result.data.language).toBe("en");
    }
  });

  it("rejects an empty requests array", () => {
    const input = { requests: [], language: "en" };
    const result = BulkReviewRequestSchema.safeParse(input);
    expect(result.success).toBe(false);
  });

  it("rejects more than 100 items", () => {
    const requests = Array.from({ length: 101 }, (_, i) => ({
      customerName: `Customer ${i}`,
      channel: "email" as const,
    }));
    const result = BulkReviewRequestSchema.safeParse({
      requests,
      language: "en",
    });
    expect(result.success).toBe(false);
  });

  it("rejects items with missing required fields", () => {
    const input = {
      requests: [{ channel: "email" }], // missing customerName
      language: "en",
    };
    const result = BulkReviewRequestSchema.safeParse(input);
    expect(result.success).toBe(false);
  });

  it("rejects invalid channel values", () => {
    const input = {
      requests: [{ customerName: "John", channel: "telegram" }],
      language: "en",
    };
    const result = BulkReviewRequestSchema.safeParse(input);
    expect(result.success).toBe(false);
  });

  it("accepts optional fields as null", () => {
    const input = {
      requests: [
        {
          customerName: "John",
          customerEmail: null,
          customerPhone: null,
          channel: "email" as const,
          bookingId: null,
          customerId: null,
        },
      ],
      message: null,
      language: "ar" as const,
    };
    const result = BulkReviewRequestSchema.safeParse(input);
    expect(result.success).toBe(true);
  });
});

describe("SubmitReviewWithQuestionsSchema", () => {
  const baseInput = {
    rating: 5,
    customerName: "John Doe",
    language: "en" as const,
  };

  it("accepts valid input with questionResponses", () => {
    const input = {
      ...baseInput,
      questionResponses: [
        {
          questionEn: "How was it?",
          questionAr: "كيف كانت؟",
          answer: "Great!",
        },
        { questionEn: "Recommend?", answer: "Yes", rating: 5 },
      ],
    };
    const result = SubmitReviewWithQuestionsSchema.safeParse(input);
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.questionResponses).toHaveLength(2);
    }
  });

  it("accepts valid input without questionResponses (defaults to empty)", () => {
    const result = SubmitReviewWithQuestionsSchema.safeParse(baseInput);
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.questionResponses).toEqual([]);
    }
  });

  it("rejects invalid rating (0)", () => {
    const result = SubmitReviewWithQuestionsSchema.safeParse({
      ...baseInput,
      rating: 0,
    });
    expect(result.success).toBe(false);
  });

  it("rejects invalid rating (6)", () => {
    const result = SubmitReviewWithQuestionsSchema.safeParse({
      ...baseInput,
      rating: 6,
    });
    expect(result.success).toBe(false);
  });

  it("rejects invalid questionResponses shape", () => {
    const input = {
      ...baseInput,
      questionResponses: [{ wrongField: "value" }],
    };
    const result = SubmitReviewWithQuestionsSchema.safeParse(input);
    expect(result.success).toBe(false);
  });
});

describe("ToggleFeaturedSchema", () => {
  it("accepts valid toggle on", () => {
    const result = ToggleFeaturedSchema.safeParse({
      reviewId: "abc123",
      featured: true,
    });
    expect(result.success).toBe(true);
  });

  it("accepts valid toggle off", () => {
    const result = ToggleFeaturedSchema.safeParse({
      reviewId: "abc123",
      featured: false,
    });
    expect(result.success).toBe(true);
  });

  it("rejects missing reviewId", () => {
    const result = ToggleFeaturedSchema.safeParse({ featured: true });
    expect(result.success).toBe(false);
  });

  it("rejects missing featured", () => {
    const result = ToggleFeaturedSchema.safeParse({ reviewId: "abc123" });
    expect(result.success).toBe(false);
  });

  it("rejects empty reviewId", () => {
    const result = ToggleFeaturedSchema.safeParse({
      reviewId: "",
      featured: true,
    });
    expect(result.success).toBe(false);
  });
});

describe("ReorderFeaturedSchema", () => {
  it("accepts a valid array of IDs", () => {
    const result = ReorderFeaturedSchema.safeParse({
      orderedIds: ["id1", "id2", "id3"],
    });
    expect(result.success).toBe(true);
  });

  it("rejects an empty array", () => {
    const result = ReorderFeaturedSchema.safeParse({ orderedIds: [] });
    expect(result.success).toBe(false);
  });

  it("rejects non-string items", () => {
    const result = ReorderFeaturedSchema.safeParse({ orderedIds: [123, 456] });
    expect(result.success).toBe(false);
  });

  it("rejects empty string items", () => {
    const result = ReorderFeaturedSchema.safeParse({ orderedIds: [""] });
    expect(result.success).toBe(false);
  });
});

describe("WidgetSettingsSchema", () => {
  it("accepts valid full settings", () => {
    const input = {
      businessName: "My Business",
      businessNameAr: "عملي",
      logoUrl: "https://example.com/logo.png",
      primaryColor: "#10b981",
      backgroundColor: "#ffffff",
      textColor: "#1e293b",
      thankYouMessage: "Thanks!",
      thankYouMessageAr: "شكراً!",
      showPoweredBy: false,
      customCss: ".widget { color: red; }",
    };
    const result = WidgetSettingsSchema.safeParse(input);
    expect(result.success).toBe(true);
  });

  it("applies defaults for partial input", () => {
    const result = WidgetSettingsSchema.safeParse({});
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.primaryColor).toBe("#10b981");
      expect(result.data.backgroundColor).toBe("#ffffff");
      expect(result.data.textColor).toBe("#1e293b");
      expect(result.data.showPoweredBy).toBe(true);
    }
  });

  it("rejects invalid hex color", () => {
    const result = WidgetSettingsSchema.safeParse({ primaryColor: "red" });
    expect(result.success).toBe(false);
  });

  it("rejects hex color without hash", () => {
    const result = WidgetSettingsSchema.safeParse({ primaryColor: "10b981" });
    expect(result.success).toBe(false);
  });

  it("rejects invalid URL for logoUrl", () => {
    const result = WidgetSettingsSchema.safeParse({ logoUrl: "not-a-url" });
    expect(result.success).toBe(false);
  });
});

// =============================================================================
// WidgetSettingsSchema – customCss injection prevention
// =============================================================================

describe("WidgetSettingsSchema – customCss injection prevention", () => {
  const base = {
    primaryColor: "#10b981",
    backgroundColor: "#ffffff",
    textColor: "#1e293b",
    showPoweredBy: true,
  };

  it("rejects CSS containing </style> tag close", () => {
    const result = WidgetSettingsSchema.safeParse({
      ...base,
      customCss: "body { color: red; } </style><script>alert(1)</script>",
    });
    expect(result.success).toBe(false);
  });

  it("rejects CSS containing javascript: URI", () => {
    const result = WidgetSettingsSchema.safeParse({
      ...base,
      customCss: "body { background: url(javascript:alert(1)); }",
    });
    expect(result.success).toBe(false);
  });

  it("rejects CSS containing expression()", () => {
    const result = WidgetSettingsSchema.safeParse({
      ...base,
      customCss: "body { width: expression(alert(1)); }",
    });
    expect(result.success).toBe(false);
  });

  it("rejects CSS containing HTML tags", () => {
    const result = WidgetSettingsSchema.safeParse({
      ...base,
      customCss: "<style>body{}</style>",
    });
    expect(result.success).toBe(false);
  });

  it("accepts valid CSS", () => {
    const result = WidgetSettingsSchema.safeParse({
      ...base,
      customCss: ".card { border-radius: 8px; color: #333; font-size: 14px; }",
    });
    expect(result.success).toBe(true);
  });

  it("accepts null customCss", () => {
    const result = WidgetSettingsSchema.safeParse({ ...base, customCss: null });
    expect(result.success).toBe(true);
  });
});

describe("GenerateQuestionsSchema", () => {
  it("accepts valid input", () => {
    const result = GenerateQuestionsSchema.safeParse({
      industry: "healthcare",
      language: "en",
      count: 5,
    });
    expect(result.success).toBe(true);
  });

  it("applies default count", () => {
    const result = GenerateQuestionsSchema.safeParse({
      industry: "beauty",
      language: "ar",
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.count).toBe(5);
    }
  });

  it("rejects invalid language", () => {
    const result = GenerateQuestionsSchema.safeParse({
      industry: "beauty",
      language: "fr",
    });
    expect(result.success).toBe(false);
  });

  it("rejects count below 1", () => {
    const result = GenerateQuestionsSchema.safeParse({
      industry: "beauty",
      language: "en",
      count: 0,
    });
    expect(result.success).toBe(false);
  });

  it("rejects count above 10", () => {
    const result = GenerateQuestionsSchema.safeParse({
      industry: "beauty",
      language: "en",
      count: 11,
    });
    expect(result.success).toBe(false);
  });

  it("rejects missing industry", () => {
    const result = GenerateQuestionsSchema.safeParse({ language: "en" });
    expect(result.success).toBe(false);
  });

  it("rejects empty industry", () => {
    const result = GenerateQuestionsSchema.safeParse({
      industry: "",
      language: "en",
    });
    expect(result.success).toBe(false);
  });
});
