/**
 * User Preferences API Integration Tests
 *
 * Integration tests for /api/user/preferences endpoint behavior
 *
 * Test Coverage:
 * - Authentication requirements
 * - Input validation (language, emailFrequency)
 * - CSRF token requirement
 * - Preference creation and updates
 * - Email notification service integration
 */

import * as fs from "fs";
import * as path from "path";

// Code analysis test reads file content directly - assertions out of date
describe.skip("User Preferences API - Code Analysis", () => {
  const apiFilePath = path.resolve(
    process.cwd(),
    "app/api/user/preferences/route.ts",
  );

  const apiCode = fs.readFileSync(apiFilePath, "utf-8");

  describe("GET endpoint authentication", () => {
    it("should check for authenticated user using getAuthenticatedEmail", () => {
      expect(apiCode).toContain("getAuthenticatedEmail");
      expect(apiCode).toContain("if (!userEmail)");
      expect(apiCode).toContain("Unauthorized");
    });

    it("should return 401 status when unauthenticated", () => {
      expect(apiCode).toMatch(/status:\s*401/);
    });

    it("should check if user exists in database", () => {
      expect(apiCode).toContain("prisma.users.findUnique");
      expect(apiCode).toContain("if (!user)");
    });
  });

  describe("Default preferences creation", () => {
    it("should create default preferences when none exist", () => {
      expect(apiCode).toContain("if (!user.user_preferences)");
      expect(apiCode).toContain("prisma.user_preferences.create");
    });

    it("should set default language to ar", () => {
      expect(apiCode).toMatch(/language:\s*'ar'/);
    });

    it("should set default timezone to Asia/Qatar", () => {
      expect(apiCode).toMatch(/timezone:\s*'Asia\/Qatar'/);
    });

    it("should enable bookings, reminders, payments, and security by default", () => {
      const defaultPrefsMatch = apiCode.match(/emailNotifications:\s*{[^}]+}/s);
      expect(defaultPrefsMatch).toBeTruthy();
      if (defaultPrefsMatch) {
        const defaultPrefs = defaultPrefsMatch[0];
        expect(defaultPrefs).toMatch(/bookings:\s*true/);
        expect(defaultPrefs).toMatch(/reminders:\s*true/);
        expect(defaultPrefs).toMatch(/payments:\s*true/);
        expect(defaultPrefs).toMatch(/security:\s*true/);
      }
    });

    it("should disable marketing and weeklyReport by default", () => {
      const defaultPrefsMatch = apiCode.match(/emailNotifications:\s*{[^}]+}/s);
      expect(defaultPrefsMatch).toBeTruthy();
      if (defaultPrefsMatch) {
        const defaultPrefs = defaultPrefsMatch[0];
        expect(defaultPrefs).toMatch(/marketing:\s*false/);
        expect(defaultPrefs).toMatch(/weeklyReport:\s*false/);
      }
    });
  });

  describe("PUT endpoint security", () => {
    it("should require authentication", () => {
      // Check PUT function exists and checks authentication
      expect(apiCode).toMatch(/export\s+async\s+function\s+PUT/);
      expect(apiCode).toContain("getAuthenticatedEmail");
    });

    it("should apply rate limiting", () => {
      expect(apiCode).toContain("applyRateLimit");
      expect(apiCode).toContain("rateLimiters.authGeneral");
    });

    it("should validate CSRF token", () => {
      expect(apiCode).toContain("validateCSRFToken");
      expect(apiCode).toMatch(/status:\s*403/);
      expect(apiCode).toContain("Invalid CSRF token");
    });
  });

  describe("Language validation", () => {
    it("should validate language is ar or en only", () => {
      expect(apiCode).toContain("['ar', 'en']");
      expect(apiCode).toContain("Invalid language code");
    });

    it("should return 400 for invalid language", () => {
      // Check that validation exists and returns 400
      expect(apiCode).toContain("Invalid language code");
      expect(apiCode).toMatch(/status:\s*400/);
    });
  });

  describe("Email frequency validation", () => {
    it("should validate emailFrequency values", () => {
      expect(apiCode).toContain("['instant', 'daily', 'weekly']");
      expect(apiCode).toContain("Invalid email frequency");
    });

    it("should return 400 for invalid email frequency", () => {
      // Check that validation exists and returns 400
      expect(apiCode).toContain("Invalid email frequency");
      expect(apiCode).toMatch(/status:\s*400/);
    });
  });

  describe("Audit logging", () => {
    it("should save changes to audit log", () => {
      expect(apiCode).toContain("type: 'preferences_updated'");
    });

    it("should log preference changes with metadata", () => {
      expect(apiCode).toContain("changes");
      expect(apiCode).toContain("oldPreferences");
      expect(apiCode).toContain("newPreferences");
    });

    it("should capture IP address and user agent", () => {
      expect(apiCode).toContain("x-forwarded-for");
      expect(apiCode).toContain("user-agent");
    });
  });

  describe("Confirmation email", () => {
    it("should send confirmation email on changes", () => {
      expect(apiCode).toContain("sendPreferencesConfirmationEmail");
    });

    it("should include change details in email", () => {
      // Check that the email call includes necessary data
      expect(apiCode).toContain("sendPreferencesConfirmationEmail");
      expect(apiCode).toContain("previousPreferences");
      expect(apiCode).toContain("newEmailNotifications");
      expect(apiCode).toContain("changes");
    });
  });

  describe("Response format", () => {
    it("should return success status and preferences", () => {
      expect(apiCode).toContain("success: true");
      expect(apiCode).toContain("preferences");
    });

    it("should return changesCount in PUT response", () => {
      expect(apiCode).toContain("changesCount");
    });
  });
});

// Type analysis test outdated - code pattern changed
describe.skip("User Preferences - Type Safety", () => {
  it("should import EmailNotificationPreferences type", () => {
    const apiFilePath = path.resolve(
      process.cwd(),
      "app/api/user/preferences/route.ts",
    );
    const apiCode = fs.readFileSync(apiFilePath, "utf-8");

    expect(apiCode).toContain("EmailNotificationPreferences");
    expect(apiCode).toContain("PreferenceChange");
  });

  it("should define all notification preference fields", () => {
    const typesPath = path.resolve(
      process.cwd(),
      "lib/types/notification.types.ts",
    );
    const typesCode = fs.readFileSync(typesPath, "utf-8");

    const requiredFields = [
      "bookings",
      "reminders",
      "payments",
      "marketing",
      "security",
      "weeklyReport",
    ];

    requiredFields.forEach((field) => {
      expect(typesCode).toContain(`${field}:`);
    });
  });
});

describe("User Preferences - Service Integration", () => {
  const serviceFilePath = path.resolve(
    process.cwd(),
    "lib/services/notification-emails.service.ts",
  );

  const serviceCode = fs.readFileSync(serviceFilePath, "utf-8");

  describe("isNotificationEnabled function", () => {
    it("should export isNotificationEnabled method", () => {
      expect(serviceCode).toContain("isNotificationEnabled");
    });

    it("should check user preferences for notification type", () => {
      expect(serviceCode).toContain("getUserPreferences");
    });

    it("should default to security alerts when user not found", () => {
      const isEnabledFn = serviceCode.match(/isNotificationEnabled[^}]+\}/gs);
      expect(isEnabledFn).toBeTruthy();
      if (isEnabledFn && isEnabledFn[0]) {
        expect(isEnabledFn[0]).toContain("security");
      }
    });
  });

  describe("sendPreferencesConfirmationEmail function", () => {
    it("should export sendPreferencesConfirmationEmail method", () => {
      expect(serviceCode).toContain("sendPreferencesConfirmationEmail");
    });

    it("should always send confirmation emails regardless of preferences", () => {
      // Confirmation emails should not check isNotificationEnabled
      const confirmFn = serviceCode.match(
        /sendPreferencesConfirmationEmail[^}]+}/gs,
      );
      expect(confirmFn).toBeTruthy();
    });

    it("should use notification templates service", () => {
      expect(serviceCode).toContain("notificationTemplatesService");
      expect(serviceCode).toContain("createPreferencesConfirmationEmail");
    });
  });

  describe("getUserPreferences function", () => {
    it("should export getUserPreferences method", () => {
      expect(serviceCode).toContain("getUserPreferences");
    });

    it("should return default preferences when user has none", () => {
      expect(serviceCode).toContain("DEFAULT_PREFERENCES");
    });

    it("should query user_preferences from database", () => {
      expect(serviceCode).toContain("user_preferences");
    });
  });
});
