import { Request, Response, NextFunction } from 'express';
import { VaultService } from '../../services/VaultService';
import { z } from 'zod';

const saveVaultSchema = z.object({
  platform: z.string().min(1),
  credentialType: z.enum(['PASSWORD', 'API_KEY', 'COOKIE', 'TOKEN']),
  accountName: z.string().min(1),
  plainText: z.string().min(1),
  expiresAt: z.string().datetime().optional().transform(v => v ? new Date(v) : undefined),
  metadata: z.record(z.string(), z.any()).optional(),
});

/**
 * [CORE_SEC_01] 凭证保险库控制器
 * 实现凭证的加密存储、列表展示与按需解密
 */
export class VaultController {
  /**
   * 保存/更新凭证
   */
  static async save(req: Request, res: Response, next: NextFunction) {
    try {
      const validated = saveVaultSchema.parse(req.body);
      const { tenantId, userId, traceId, shopId } = (req as any).traceContext;

      const id = await VaultService.saveCredential(
        { tenantId, userId, traceId, shopId },
        validated as any
      );

      res.json({ success: true, data: { id } });
    } catch (err: any) {
      if (err instanceof z.ZodError) {
        return res.status(400).json({ success: false, error: err.issues[0].message });
      }
      next(err);
    }
  }

  /**
   * 获取凭证列表 (脱敏)
   */
  static async list(req: Request, res: Response, next: NextFunction) {
    try {
      const { tenantId, shopId } = (req as any).traceContext;
      const list = await VaultService.listCredentials(tenantId, shopId);
      res.json({ success: true, data: list });
    } catch (err: any) {
      next(err);
    }
  }

  /**
   * 解密并获取凭证 (JIT)
   */
  static async decrypt(req: Request, res: Response, next: NextFunction) {
    try {
      const id = parseInt(String(req.params.id));
      const { tenantId, userId, traceId } = (req as any).traceContext;

      const decrypted = await VaultService.getDecryptedCredential(
        { tenantId, userId, traceId },
        id
      );

      if (!decrypted) {
        return res.status(404).json({ success: false, error: 'Credential not found' });
      }

      res.json({ success: true, data: { decrypted } });
    } catch (err: any) {
      next(err);
    }
  }
}
