/**
 * Test utilities for integration tests
 *
 * Shared helper functions for API testing
 */

import { INestApplication } from '@nestjs/common';
import request from 'supertest';
import { TEST_CREDENTIALS } from '../../../config/test-credentials';

/**
 * Login and get auth token
 */
export async function getAuthToken(
  app: INestApplication,
  username = TEST_CREDENTIALS.admin.username,
  password = TEST_CREDENTIALS.admin.password,
): Promise<string | null> {
  const loginResponse = await request(app.getHttpServer())
    .post('/api/v1/auth/login')
    .send({ username, password });

  if (loginResponse.status === 200 || loginResponse.status === 201) {
    return (
      loginResponse.body.data?.token?.accessToken ||
      loginResponse.body.data?.accessToken ||
      loginResponse.body.accessToken
    );
  }
  return null;
}

/**
 * Get first user from the system
 */
export async function getFirstUserId(
  app: INestApplication,
  authToken: string,
): Promise<string | null> {
  const response = await request(app.getHttpServer())
    .get('/api/v1/users')
    .set('Authorization', `Bearer ${authToken}`);

  if (response.body.data?.items?.length > 0) {
    return response.body.data.items[0].id;
  }
  if (response.body.data?.length > 0) {
    return response.body.data[0].id;
  }
  return null;
}

/**
 * Generate unique test data
 */
export function generateTestData(prefix: string) {
  const timestamp = Date.now();
  return {
    username: `${prefix}_${timestamp}`,
    email: `${prefix}_${timestamp}@test.com`,
    code: `${prefix.toUpperCase()}_${timestamp}`,
    name: `Test ${prefix} ${timestamp}`,
  };
}

/**
 * Verify API response format
 */
export function verifySuccessResponse(body: any) {
  expect(body.success).toBe(true);
  expect(body).toHaveProperty('data');
  expect(body).toHaveProperty('timestamp');
}

/**
 * Verify error response format
 */
export function verifyErrorResponse(body: any) {
  expect(body.success).toBe(false);
  expect(body).toHaveProperty('error');
  expect(body.error).toHaveProperty('code');
  expect(body.error).toHaveProperty('message');
}

/**
 * Verify paginated response format
 */
export function verifyPaginatedResponse(body: any) {
  expect(body.success).toBe(true);
  expect(body.data).toHaveProperty('items');
  expect(body.data).toHaveProperty('total');
  expect(body.data).toHaveProperty('page');
  expect(body.data).toHaveProperty('limit');
  expect(body.data).toHaveProperty('totalPages');
  expect(body.data).toHaveProperty('hasNext');
  expect(body.data).toHaveProperty('hasPrev');
  expect(Array.isArray(body.data.items)).toBe(true);
}

/**
 * Common test timeout values
 */
export const TEST_TIMEOUT = {
  INIT: 60000,      // App initialization
  CLEANUP: 30000,   // Cleanup operations
  STANDARD: 10000,  // Standard test
  SYNC: 120000,     // Sync operations
};

/**
 * API error codes as defined in docs
 */
export const IAM_ERROR_CODES = {
  INVALID_CREDENTIALS: 'IAM_INVALID_CREDENTIALS',
  USER_SUSPENDED: 'IAM_USER_SUSPENDED',
  USER_TERMINATED: 'IAM_USER_TERMINATED',
  USER_LOCKED: 'IAM_USER_LOCKED',
  PASSWORD_TOO_WEAK: 'IAM_PASSWORD_TOO_WEAK',
  USER_EMAIL_EXISTS: 'IAM_USER_EMAIL_EXISTS',
  USERNAME_EXISTS: 'IAM_USERNAME_EXISTS',
  EMPLOYEE_ID_EXISTS: 'IAM_EMPLOYEE_ID_EXISTS',
  MANAGER_LOOP_DETECTED: 'IAM_MANAGER_LOOP_DETECTED',
  MANAGER_SELF_REFERENCE: 'IAM_MANAGER_SELF_REFERENCE',
  DEPARTMENT_CODE_EXISTS: 'IAM_DEPARTMENT_CODE_EXISTS',
  DEPARTMENT_HAS_CHILDREN: 'IAM_DEPARTMENT_HAS_CHILDREN',
  DEPARTMENT_HAS_USERS: 'IAM_DEPARTMENT_HAS_USERS',
  SYSTEM_ROLE_PROTECTED: 'IAM_SYSTEM_ROLE_PROTECTED',
  ROLE_HAS_USERS: 'IAM_ROLE_HAS_USERS',
  WORKFLOW_ROLE_RESOLVE_EMPTY: 'IAM_WORKFLOW_ROLE_RESOLVE_EMPTY',
  SYNC_IN_PROGRESS: 'IAM_SYNC_IN_PROGRESS',
  EXTERNAL_ID_MISMATCH: 'IAM_EXTERNAL_ID_MISMATCH',
  USER_ALREADY_ACTIVE: 'IAM_USER_ALREADY_ACTIVE',
  TERMINATED_USER_CANNOT_ACTIVATE: 'IAM_TERMINATED_USER_CANNOT_ACTIVATE',
  TOKEN_EXPIRED: 'IAM_TOKEN_EXPIRED',
  TOKEN_REVOKED: 'IAM_TOKEN_REVOKED',
};

/**
 * AI Assistant API error codes
 */
export const AI_ASSISTANT_ERROR_CODES = {
  // 对话相关
  CONVERSATION_NOT_FOUND: 'CONVERSATION_NOT_FOUND',
  CONVERSATION_ACCESS_DENIED: 'CONVERSATION_ACCESS_DENIED',
  CONVERSATION_CLOSED: 'CONVERSATION_CLOSED',
  MESSAGE_TOO_LONG: 'MESSAGE_TOO_LONG',
  MESSAGE_NOT_FOUND: 'MESSAGE_NOT_FOUND',
  // 反馈相关
  FEEDBACK_EXISTS: 'FEEDBACK_EXISTS',
  FEEDBACK_NOT_FOUND: 'FEEDBACK_NOT_FOUND',
  // 工单相关
  TICKET_NOT_FOUND: 'TICKET_NOT_FOUND',
  TICKET_ACCESS_DENIED: 'TICKET_ACCESS_DENIED',
  TICKET_NOT_CONFIRMED: 'TICKET_NOT_CONFIRMED',
  TICKET_ALREADY_RESOLVED: 'TICKET_ALREADY_RESOLVED',
  // 知识补充相关
  KNOWLEDGE_FIX_EXISTS: 'KNOWLEDGE_FIX_EXISTS',
  KNOWLEDGE_FIX_NOT_FOUND: 'KNOWLEDGE_FIX_NOT_FOUND',
  // Prompt 模板相关
  PROMPT_TEMPLATE_NOT_FOUND: 'PROMPT_TEMPLATE_NOT_FOUND',
  // 安全相关
  PII_DETECTED: 'PII_DETECTED',
  PROMPT_INJECTION_DETECTED: 'PROMPT_INJECTION_DETECTED',
  // LLM 服务相关
  LLM_SERVICE_ERROR: 'LLM_SERVICE_ERROR',
  LLM_RATE_LIMIT: 'LLM_RATE_LIMIT',
};

/**
 * Ticket API error codes
 */
export const TICKET_ERROR_CODES = {
  NOT_FOUND: 'TICKET_NOT_FOUND',
  ACCESS_DENIED: 'TICKET_ACCESS_DENIED',
  INVALID_STATUS_TRANSITION: 'TICKET_INVALID_STATUS_TRANSITION',
  ALREADY_ASSIGNED: 'TICKET_ALREADY_ASSIGNED',
  NOT_ASSIGNED: 'TICKET_NOT_ASSIGNED',
  REOPEN_EXPIRED: 'TICKET_REOPEN_EXPIRED',
  ATTACHMENT_LIMIT_EXCEEDED: 'TICKET_ATTACHMENT_LIMIT_EXCEEDED',
  ATTACHMENT_SIZE_EXCEEDED: 'TICKET_ATTACHMENT_SIZE_EXCEEDED',
  ATTACHMENT_TYPE_INVALID: 'TICKET_ATTACHMENT_TYPE_INVALID',
  CATEGORY_NOT_FOUND: 'TICKET_CATEGORY_NOT_FOUND',
  CATEGORY_INACTIVE: 'TICKET_CATEGORY_INACTIVE',
  CATEGORY_CODE_EXISTS: 'TICKET_CATEGORY_CODE_EXISTS',
  CATEGORY_HAS_CHILDREN: 'TICKET_CATEGORY_HAS_CHILDREN',
  CATEGORY_HAS_TICKETS: 'TICKET_CATEGORY_HAS_TICKETS',
  GROUP_NOT_FOUND: 'TICKET_GROUP_NOT_FOUND',
  GROUP_CODE_EXISTS: 'TICKET_GROUP_CODE_EXISTS',
  GROUP_NO_AVAILABLE_MEMBER: 'TICKET_GROUP_NO_AVAILABLE_MEMBER',
  COMMENT_NOT_FOUND: 'TICKET_COMMENT_NOT_FOUND',
  COMMENT_DELETE_EXPIRED: 'TICKET_COMMENT_DELETE_EXPIRED',
  SLA_NOT_FOUND: 'TICKET_SLA_NOT_FOUND',
  SLA_IN_USE: 'TICKET_SLA_IN_USE',
  NOT_RESOLVED_FOR_RATING: 'TICKET_NOT_RESOLVED_FOR_RATING',
  ALREADY_RATED: 'TICKET_ALREADY_RATED',
  RATING_NOT_CREATOR: 'TICKET_RATING_NOT_CREATOR',
};

/**
 * Audit API error codes
 */
export const AUDIT_ERROR_CODES = {
  PERMISSION_DENIED: 'AUDIT_PERMISSION_DENIED',
  LOG_NOT_FOUND: 'AUDIT_LOG_NOT_FOUND',
  QUERY_INVALID_PARAMS: 'AUDIT_QUERY_INVALID_PARAMS',
  QUERY_TIME_RANGE_TOO_LARGE: 'AUDIT_QUERY_TIME_RANGE_TOO_LARGE',
  EXPORT_TOO_LARGE: 'AUDIT_EXPORT_TOO_LARGE',
  INTEGRITY_CHECK_IN_PROGRESS: 'AUDIT_INTEGRITY_CHECK_IN_PROGRESS',
  INTEGRITY_CHECK_NOT_FOUND: 'AUDIT_INTEGRITY_CHECK_NOT_FOUND',
};
