// チャンク設定サービス - チャンク設定の制限の取得と検証に使用

export interface ChunkConfigLimits {
  maxChunkSize: number;        // 最大チャンクサイズ (tokens)
  maxOverlapSize: number;      // 最大重複サイズ (tokens)
  minOverlapSize: number;      // 最小重複サイズ (tokens)
  defaultChunkSize: number;    // デフォルトチャンクサイズ
  defaultOverlapSize: number;  // デフォルト重複サイズ
  modelInfo: EmbeddingModelLimit; // モデル情報
}

export interface EmbeddingModelLimit {
  name: string;              // モデル名
  maxInputTokens: number;    // モデル入力制限
  maxBatchSize: number;      // モデルバッチ制限
  expectedDimensions: number; // 期待されるベクトル次元数
}

export const chunkConfigService = {
  /**
   * チャンク設定の制限を取得
   * @param embeddingModelId 埋め込みモデルID
   * @param authToken 認証トークン
   * @returns 設定制限情報
   */
  async getLimits(
    embeddingModelId: string,
    authToken: string
  ): Promise<ChunkConfigLimits> {
    const params = new URLSearchParams({
      embeddingModelId,
    });

    const response = await fetch(
      `/api/knowledge-bases/chunk-config/limits?${params.toString()}`,
      {
        method: 'GET',
        headers: {
          'Authorization': `Bearer ${authToken}`,
          'Content-Type': 'application/json',
        },
      }
    );

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.message || 'loadLimitsFailed');
    }

    return response.json();
  },

  /**
   * チャンク設定が有効かどうかを検証
   * @param chunkSize チャンクサイズ
   * @param chunkOverlap 重複サイズ
   * @param limits 設定制限
   * @returns 検証結果とエラー情報
   */
  validateConfig(
    chunkSize: number,
    chunkOverlap: number,
    limits: ChunkConfigLimits
  ): {
    isValid: boolean;
    errors: string[];
    adjustedChunkSize: number;
    adjustedOverlapSize: number;
  } {
    const errors: string[] = [];
    let adjustedChunkSize = chunkSize;
    let adjustedOverlapSize = chunkOverlap;

    // チャンクサイズの検証
    if (chunkSize > limits.maxChunkSize) {
      errors.push(`チャンクサイズ ${chunkSize} が上限 ${limits.maxChunkSize} を超えています`);
      adjustedChunkSize = limits.maxChunkSize;
    }

    if (chunkSize < 50) {
      errors.push(`チャンクサイズ ${chunkSize} が最小値 50 未満です`);
      adjustedChunkSize = 50;
    }

    // 重複サイズの検証
    const maxOverlapByRatio = Math.floor(adjustedChunkSize * 0.5);
    if (chunkOverlap > limits.maxOverlapSize) {
      errors.push(`重複サイズ ${chunkOverlap} が上限 ${limits.maxOverlapSize} を超えています`);
      adjustedOverlapSize = limits.maxOverlapSize;
    }

    if (chunkOverlap > maxOverlapByRatio) {
      errors.push(`重複サイズ ${chunkOverlap} がチャンクサイズの50% (${maxOverlapByRatio}) を超えています`);
      adjustedOverlapSize = maxOverlapByRatio;
    }

    if (chunkOverlap < limits.minOverlapSize) {
      adjustedOverlapSize = limits.minOverlapSize;
    }

    return {
      isValid: errors.length === 0,
      errors,
      adjustedChunkSize,
      adjustedOverlapSize,
    };
  },

  /**
   * 表示用に制限情報をフォーマット
   */
  formatLimits(limits: ChunkConfigLimits): string {
    return [
      `モデル: ${limits.modelInfo.name}`,
      `チャンク上限: ${limits.maxChunkSize} tokens`,
      `重複上限: ${limits.maxOverlapSize} tokens`,
      `バッチ制限: ${limits.modelInfo.maxBatchSize}`,
      `ベクトル次元: ${limits.modelInfo.expectedDimensions}`,
    ].join(' | ');
  },
};
