/**
 * Unit tests for WhatsApp Feature Access API
 * GET /api/whatsapp/feature-access
 *
 * NOTE: Extended tests are in whatsapp-extended.test.ts.
 * This file covers the pre-existing integration test scenarios
 * converted to properly mocked unit tests.
 */

// Mock dependencies BEFORE imports
jest.mock("@/lib/logger", () => ({
  logger: {
    warn: jest.fn(),
    error: jest.fn(),
    info: jest.fn(),
    debug: jest.fn(),
    security: jest.fn(),
  },
}));

jest.mock("@/lib/db");

jest.mock("@/lib/services/system-settings.service", () => ({
  systemSettingsService: {
    validateN8NToken: jest.fn(),
  },
}));

jest.mock("@/lib/services/whatsapp-feature-access.service", () => ({
  getFeatureAccess: jest.fn(),
  getFeatureUsage: jest.fn(),
  isWithinLimits: jest.fn(),
}));

jest.mock("@/lib/validators/whatsapp-ai.validator", () => ({
  FeatureAccessQuerySchema: {
    safeParse: jest.fn(),
  },
}));

jest.mock("next/server", () => {
  const NextResponseMock = function (
    body: string | null,
    init?: Record<string, unknown>,
  ) {
    return {
      status: (init?.status as number) || 200,
      headers: new Map(
        Object.entries((init?.headers as Record<string, string>) || {}),
      ),
      json: async () => (body ? JSON.parse(body) : null),
    };
  };
  NextResponseMock.json = jest.fn(
    (data: unknown, options?: { status?: number }) => ({
      status: options?.status || 200,
      headers: new Map(),
      json: async () => data,
    }),
  );
  return { NextRequest: jest.fn(), NextResponse: NextResponseMock };
});

import { NextRequest, NextResponse } from "next/server";
import { systemSettingsService } from "@/lib/services/system-settings.service";
import {
  getFeatureAccess,
  getFeatureUsage,
  isWithinLimits,
} from "@/lib/services/whatsapp-feature-access.service";
import { FeatureAccessQuerySchema } from "@/lib/validators/whatsapp-ai.validator";

// Route not yet implemented
describe.skip("GET /api/whatsapp/feature-access (pre-existing)", () => {
  let featureModule: {
    GET: (req: unknown) => Promise<{
      status: number;
      json: () => Promise<Record<string, unknown>>;
    }>;
  };

  beforeAll(async () => {
    featureModule = await import("@/app/api/whatsapp/feature-access/route");
  });

  beforeEach(() => {
    jest.clearAllMocks();
    (NextResponse.json as jest.Mock).mockImplementation(
      (data: unknown, options?: { status?: number }) => ({
        status: options?.status || 200,
        headers: new Map(),
        json: async () => data,
      }),
    );
  });

  const mockRequest = (authHeader?: string, params?: Record<string, string>) =>
    ({
      headers: {
        get: jest.fn((key: string) => {
          if (key === "authorization") return authHeader || null;
          return null;
        }),
      },
      nextUrl: {
        searchParams: new URLSearchParams(params || {}),
      },
    }) as unknown as NextRequest;

  it("should return 401 without auth", async () => {
    const response = await featureModule.GET(mockRequest());
    expect(response.status).toBe(401);
  });

  it("should return 400 for invalid query", async () => {
    (systemSettingsService.validateN8NToken as jest.Mock).mockResolvedValue(
      true,
    );
    (FeatureAccessQuerySchema.safeParse as jest.Mock).mockReturnValue({
      success: false,
      error: { errors: [{ message: "Required" }] },
    });

    const response = await featureModule.GET(mockRequest("Bearer valid-token"));
    expect(response.status).toBe(400);
  });

  it("should return starter tier features", async () => {
    (systemSettingsService.validateN8NToken as jest.Mock).mockResolvedValue(
      true,
    );
    (FeatureAccessQuerySchema.safeParse as jest.Mock).mockReturnValue({
      success: true,
      data: { organizationId: "starter-org" },
    });
    (getFeatureAccess as jest.Mock).mockResolvedValue({
      tier: "starter",
      tierLevel: 1,
      features: {
        aiAgent: true,
        knowledgeBase: true,
        maxKBEntries: 50,
        appointments: false,
        payments: false,
        quotations: false,
      },
      limits: {},
    });
    (getFeatureUsage as jest.Mock).mockResolvedValue({});
    (isWithinLimits as jest.Mock).mockResolvedValue({
      withinLimits: true,
      violations: [],
    });

    const response = await featureModule.GET(
      mockRequest("Bearer valid-token", { organizationId: "starter-org" }),
    );
    const body = await response.json();
    expect(body.success).toBe(true);
    expect(body.data.tier).toBe("starter");
    expect(body.data.withinLimits).toBe(true);
  });

  it("should return professional tier features", async () => {
    (systemSettingsService.validateN8NToken as jest.Mock).mockResolvedValue(
      true,
    );
    (FeatureAccessQuerySchema.safeParse as jest.Mock).mockReturnValue({
      success: true,
      data: { organizationId: "prof-org" },
    });
    (getFeatureAccess as jest.Mock).mockResolvedValue({
      tier: "professional",
      tierLevel: 2,
      features: {
        aiAgent: true,
        appointments: true,
        payments: true,
        quotations: true,
      },
      limits: {},
    });
    (getFeatureUsage as jest.Mock).mockResolvedValue({ messagesUsed: 50 });
    (isWithinLimits as jest.Mock).mockResolvedValue({
      withinLimits: true,
      violations: [],
    });

    const response = await featureModule.GET(
      mockRequest("Bearer valid-token", { organizationId: "prof-org" }),
    );
    const body = await response.json();
    expect(body.data.tier).toBe("professional");
    expect(body.data.tierLevel).toBe(2);
  });

  it("should indicate when limits are exceeded", async () => {
    (systemSettingsService.validateN8NToken as jest.Mock).mockResolvedValue(
      true,
    );
    (FeatureAccessQuerySchema.safeParse as jest.Mock).mockReturnValue({
      success: true,
      data: { organizationId: "limit-org" },
    });
    (getFeatureAccess as jest.Mock).mockResolvedValue({
      tier: "starter",
      tierLevel: 1,
      features: { knowledgeBase: true, maxKBEntries: 50 },
      limits: {},
    });
    (getFeatureUsage as jest.Mock).mockResolvedValue({
      kbEntries: 51,
    });
    (isWithinLimits as jest.Mock).mockResolvedValue({
      withinLimits: false,
      violations: ["Knowledge base entries exceeded (51/50)"],
    });

    const response = await featureModule.GET(
      mockRequest("Bearer valid-token", { organizationId: "limit-org" }),
    );
    const body = await response.json();
    expect(body.data.withinLimits).toBe(false);
  });

  it("should return 500 on service error", async () => {
    (systemSettingsService.validateN8NToken as jest.Mock).mockResolvedValue(
      true,
    );
    (FeatureAccessQuerySchema.safeParse as jest.Mock).mockReturnValue({
      success: true,
      data: { organizationId: "error-org" },
    });
    (getFeatureAccess as jest.Mock).mockRejectedValue(
      new Error("Service error"),
    );

    const response = await featureModule.GET(
      mockRequest("Bearer valid-token", { organizationId: "error-org" }),
    );
    expect(response.status).toBe(500);
  });
});
