import { Injectable, Logger } from '@nestjs/common';
import {
  ActivityReportEntry,
  ActivityReportName,
  GraphClient,
  GraphSubscribedSku,
  GraphUser,
} from './graph-client.interface';

/**
 * Stub GraphClient — 用于本地开发（OPS_CENTER_M365_STUB=true）和 L1 集成测试
 *
 * 返回硬编码 fixture 数据，模拟 5 个用户场景：
 * - alice：活跃，3 个 license，最近登录
 * - bob：长期未登录（210 天），有 license
 * - carol：从未登录，license 不足（signInActivity null）
 * - dave：禁用账号
 * - eve：上次同步可见、本次缺失（用于测试 missingFromLatestSync）
 */
@Injectable()
export class StubGraphClient implements GraphClient {
  private readonly logger = new Logger(StubGraphClient.name);

  async listSubscribedSkus(): Promise<GraphSubscribedSku[]> {
    this.logger.debug('[stub] listSubscribedSkus');
    return [
      { skuId: '11111111-1111-1111-1111-111111111111', skuPartNumber: 'ENTERPRISEPACK' },
      { skuId: '22222222-2222-2222-2222-222222222222', skuPartNumber: 'EMS' },
      { skuId: '33333333-3333-3333-3333-333333333333', skuPartNumber: 'POWER_BI_PRO' },
    ];
  }

  async listUsers(): Promise<GraphUser[]> {
    this.logger.debug('[stub] listUsers');
    const now = new Date();
    const daysAgo = (n: number) => new Date(now.getTime() - n * 24 * 3600 * 1000).toISOString();

    return [
      {
        id: 'graph-user-alice',
        userPrincipalName: 'alice@stub.local',
        displayName: 'Alice (stub)',
        mail: 'alice@stub.local',
        department: 'Engineering',
        jobTitle: 'Developer',
        accountEnabled: true,
        createdDateTime: daysAgo(365),
        signInActivity: {
          lastSignInDateTime: daysAgo(2),
          lastNonInteractiveSignInDateTime: daysAgo(1),
        },
        assignedLicenses: [
          { skuId: '11111111-1111-1111-1111-111111111111' },
          { skuId: '22222222-2222-2222-2222-222222222222' },
          { skuId: '33333333-3333-3333-3333-333333333333' },
        ],
      },
      {
        id: 'graph-user-bob',
        userPrincipalName: 'BOB@stub.local', // mixed-case to test JOIN normalization
        displayName: 'Bob (stub)',
        mail: 'bob@stub.local',
        department: 'Sales',
        jobTitle: 'Account Manager',
        accountEnabled: true,
        createdDateTime: daysAgo(365),
        signInActivity: {
          lastSignInDateTime: daysAgo(210),
          lastNonInteractiveSignInDateTime: daysAgo(200),
        },
        assignedLicenses: [{ skuId: '11111111-1111-1111-1111-111111111111' }],
      },
      {
        id: 'graph-user-carol',
        userPrincipalName: 'carol@stub.local',
        displayName: 'Carol (stub)',
        mail: 'carol@stub.local',
        department: null,
        jobTitle: null,
        accountEnabled: true,
        createdDateTime: daysAgo(15), // 新账号未登录场景
        signInActivity: null,
        assignedLicenses: [],
      },
      {
        id: 'graph-user-dave',
        userPrincipalName: 'dave@stub.local',
        displayName: 'Dave (stub)',
        mail: 'dave@stub.local',
        department: 'Operations',
        jobTitle: null,
        accountEnabled: false, // 禁用
        createdDateTime: daysAgo(800),
        signInActivity: {
          lastSignInDateTime: daysAgo(400),
          lastNonInteractiveSignInDateTime: null,
        },
        assignedLicenses: [{ skuId: '11111111-1111-1111-1111-111111111111' }],
      },
    ];
  }

  async getActivityReport(report: ActivityReportName): Promise<ActivityReportEntry[]> {
    this.logger.debug(`[stub] getActivityReport ${report}`);
    const now = new Date();
    const daysAgo = (n: number) => new Date(now.getTime() - n * 24 * 3600 * 1000);

    // Alice 在所有 4 份报告里都有最近活动
    const aliceDays: Record<ActivityReportName, number> = {
      EmailActivity: 1,
      OneDriveActivity: 3,
      TeamsUserActivity: 2,
      SharePointActivity: 5,
    };

    // Bob 只有 Email 活动（120 天前），其他都没有
    const bobDays: Record<ActivityReportName, number | null> = {
      EmailActivity: 120,
      OneDriveActivity: null,
      TeamsUserActivity: null,
      SharePointActivity: null,
    };

    const entries: ActivityReportEntry[] = [
      {
        userPrincipalNameLower: 'alice@stub.local',
        lastActivityDate: daysAgo(aliceDays[report]),
      },
    ];
    if (bobDays[report] !== null) {
      entries.push({
        userPrincipalNameLower: 'bob@stub.local',
        lastActivityDate: daysAgo(bobDays[report] as number),
      });
    }
    return entries;
  }
}
