import { describe, expect, it } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';

function readRepoFile(...segments: string[]): string {
  return fs.readFileSync(path.resolve(process.cwd(), '..', ...segments), 'utf8');
}

describe('frontend/backend websocket contract regressions', () => {
  it('android websocket commands use canonical backend command names', () => {
    const androidCommands = readRepoFile(
      'android',
      'app',
      'src',
      'main',
      'java',
      'com',
      'craigvg',
      'lichun_android',
      'utils',
      'WebSocketCommands.kt'
    );
    const androidWs = readRepoFile(
      'android',
      'app',
      'src',
      'main',
      'java',
      'com',
      'craigvg',
      'lichun_android',
      'network',
      'WebSocketManager.kt'
    );

    expect(androidCommands).toContain('"conversation"');
    expect(androidCommands).toContain('"swipeMatch"');
    expect(androidCommands).toContain('"startDate"');
    expect(androidCommands).toContain('"applyForExtracurricular"');
    expect(androidCommands).toContain('"quitExtracurricular"');
    expect(androidCommands).toContain('"getExtraCurriculars"');
    expect(androidCommands).toContain('"partnerGift"');
    expect(androidCommands).toContain('"purchaseInAppItem"');
    expect(androidCommands).toContain('"deviceToken"');
    expect(androidCommands).toContain('"focusUpdate"');
    expect(androidWs).toContain('WebSocketCommands.');
    expect(androidCommands).not.toContain('"getStoreItems"');
    expect(androidCommands).not.toContain('"updateAffinity"');
  });

  it('iOS websocket parser handles canonical data export and account deletion events', () => {
    const webSocketService = readRepoFile('ios', 'lichunWebsocket', 'WebSocketService.swift');

    expect(webSocketService).toContain('type == "dataExportComplete" || type == "dataExportReady"');
    expect(webSocketService).toContain('type == "accountDeletionScheduled" || type == "accountDeleted"');
    expect(webSocketService).toContain('type == "accountDeletionCancelled"');
  });

  it('retention payload parsing expects backend quest and reward shapes', () => {
    const iosRetention = readRepoFile('ios', 'lichunWebsocket', 'Core', 'Services', 'RetentionService.swift');
    const androidCommands = readRepoFile(
      'android',
      'app',
      'src',
      'main',
      'java',
      'com',
      'craigvg',
      'lichun_android',
      'utils',
      'WebSocketCommands.kt'
    );

    expect(iosRetention).toContain('data["quest"]');
    expect(androidCommands).toContain('"claimQuestReward"');

    expect(iosRetention).toContain('data["success"]');
    expect(androidCommands).toContain('"claimDailyReward"');
  });

  it('iOS in-app purchase command sends structured payload and parses completion event', () => {
    const monetizationService = readRepoFile('ios', 'lichunWebsocket', 'Core', 'Services', 'MonetizationService.swift');
    const constants = readRepoFile('ios', 'lichunWebsocket', 'Shared', 'Utilities', 'Constants.swift');
    const productGrid = readRepoFile(
      'ios',
      'lichunWebsocket',
      'Features',
      'Store',
      'Views',
      'ProductGridView.swift'
    );

    expect(constants).toContain('purchaseInAppItem');
    expect(constants).toContain('"productId"');
    expect(productGrid).toContain('WebSocketCommands.purchaseInAppItem');
    expect(monetizationService).toContain('case "inAppPurchaseComplete"');
    expect(monetizationService).toContain('handleInAppPurchaseComplete');
  });

  it('iOS websocket commands use canonical structured payloads', () => {
    const constants = readRepoFile('ios', 'lichunWebsocket', 'Shared', 'Utilities', 'Constants.swift');

    expect(constants).toContain('enum WebSocketCommands');
    expect(constants).toContain('quitHabit');
    expect(constants).toContain('applyForJob');
    expect(constants).toContain('purchaseItem');
    expect(constants).toContain('tooltipSeen');
    expect(constants).toContain('debugSetup');
    expect(constants).toContain('debugGrant');
  });

  it('Android websocket commands include debugGrant helper', () => {
    const commands = readRepoFile(
      'android',
      'app',
      'src',
      'main',
      'java',
      'com',
      'craigvg',
      'lichun_android',
      'utils',
      'WebSocketCommands.kt'
    );

    expect(commands).toContain('debugGrant');
    expect(commands).toContain('debugSetup');
  });
});
