import { Injectable, ServiceUnavailableException } from '@nestjs/common';
import { createLogger } from '@core/observability/logging/config/winston.config';
import type { StorageAdapter } from './storage.types';

const logger = createLogger('OneDriveStorageAdapter');

/**
 * PR10.5 OneDrive adapter 骨架。
 *
 * **跑通需要外部基础设施**：
 *   - Microsoft Azure AD 应用注册（client_id + client_secret + tenant_id）
 *   - Graph API permission：Files.ReadWrite.All
 *   - 用户走 OAuth2 authorization code flow 拿到 refresh_token
 *   - refresh_token 用 envelope encryption 包好存 `storage_bindings.encryptedSecret`
 *
 * 当前未配 → `isConfigured()` 永远 false。Storage service 会跳到下一个可用 binding，
 * 或者 fallback 到 LocalAdapter。
 */
@Injectable()
export class OneDriveStorageAdapter implements StorageAdapter {
  readonly kind = 'ONEDRIVE' as const;

  isConfigured(config: Record<string, unknown>, encryptedSecret: string | null): boolean {
    const hasAzureApp = !!(process.env.AZURE_CLIENT_ID && process.env.AZURE_CLIENT_SECRET);
    const hasToken = !!encryptedSecret;
    const driveId = config.driveId;
    return hasAzureApp && hasToken && typeof driveId === 'string';
  }

  async upload(_args: {
    config: Record<string, unknown>;
    encryptedSecret: string | null;
    path: string;
    content: Buffer;
  }): Promise<{ externalId?: string }> {
    if (!this.isConfigured(_args.config, _args.encryptedSecret)) {
      throw new ServiceUnavailableException(
        'OneDrive adapter not configured — need Azure AD app + per-user OAuth refresh_token',
      );
    }
    // TODO: PUT /drives/{driveId}/root:/{path}:/content
    //   - 用 refresh_token 换 access_token（缓存 50min）
    //   - envelope encryption: 把 access_token 解密后短暂用、不落库
    //   - 大文件走 createUploadSession 分片上传
    logger.warn('OneDrive upload stub — real Graph API integration pending');
    throw new Error('not yet implemented — needs @microsoft/microsoft-graph-client');
  }

  async download(_args: {
    config: Record<string, unknown>;
    encryptedSecret: string | null;
    path: string;
    externalId?: string;
  }): Promise<Buffer> {
    if (!this.isConfigured(_args.config, _args.encryptedSecret)) {
      throw new ServiceUnavailableException('OneDrive adapter not configured');
    }
    throw new Error('not yet implemented');
  }
}
