import {
  IsString,
  IsBoolean,
  IsOptional,
  IsInt,
  Min,
  Max,
  IsIn,
  IsNotEmpty,
  ValidateIf,
} from 'class-validator';
import { AiProvider } from '../ai-config.entity';

const PROVIDERS = [AiProvider.OPENAI, AiProvider.DEEPSEEK, AiProvider.OPENAI_COMPATIBLE] as const;

const DEFAULT_BASE_URLS: Record<AiProvider, string> = {
  [AiProvider.OPENAI]: 'https://api.openai.com/v1',
  [AiProvider.DEEPSEEK]: 'https://api.deepseek.com',
  [AiProvider.OPENAI_COMPATIBLE]: '',
};

/** DTO for PUT /api/ai/config — all fields required or validated */
export class SaveAiConfigDto {
  @IsIn(PROVIDERS)
  provider!: AiProvider;

  @ValidateIf((o: SaveAiConfigDto) => o.provider === AiProvider.OPENAI_COMPATIBLE || o.baseUrl !== undefined)
  @IsNotEmpty({ message: 'OPENAI_COMPATIBLE 模式必须提供 baseUrl' })
  @IsString()
  baseUrl?: string;

  /** Raw API key — never returned by GET; empty / undefined = keep existing */
  @IsOptional()
  @IsString()
  apiKey?: string;

  @IsOptional()
  @IsString()
  defaultModel?: string;

  @IsOptional()
  @IsBoolean()
  enabled?: boolean;

  @IsOptional()
  @IsInt()
  @Min(1000)
  @Max(120000)
  timeoutMs?: number;
}

/** DTO for POST /api/ai/config/test — all fields optional, validate only when provided */
export class TestAiConfigDto {
  @IsOptional()
  @IsIn(PROVIDERS)
  provider?: AiProvider;

  @IsOptional()
  @IsString()
  baseUrl?: string;

  @IsOptional()
  @IsString()
  apiKey?: string;

  @IsOptional()
  @IsString()
  defaultModel?: string;

  @IsOptional()
  @IsInt()
  @Min(1000)
  @Max(120000)
  timeoutMs?: number;
}

/** Response shape for GET /api/ai/config — NEVER includes plaintext key */
export interface AiConfigResponseDto {
  id: number;
  provider: AiProvider;
  baseUrl: string;
  hasApiKey: boolean;
  hasDatabaseKey: boolean;
  maskedApiKey: string | null;
  keySource: 'database' | 'environment' | 'none';
  defaultModel: string | null;
  enabled: boolean;
  timeoutMs: number;
  verified: boolean;
  lastTestedAt: string | null;
  lastTestLatencyMs: number | null;
  createdAt: string;
  updatedAt: string;
}

/** Response shape for POST /api/ai/config/test */
export interface AiConfigTestResultDto {
  success: boolean;
  latencyMs: number | null;
  modelCount: number | null;
  modelAvailable: boolean;
  testedAt: string;
  message: string;
}

/** Server-only runtime config — NEVER exported via controller DTO */
export interface AiRuntimeConfig {
  provider: AiProvider;
  baseUrl: string;
  apiKey: string;
  defaultModel: string;
  timeoutMs: number;
  enabled: boolean;
}

export { DEFAULT_BASE_URLS };
