import { UIConfigField } from '@/lib/config/types';
import BaseModelProvider from '../../base/provider';
import { Model, ModelList, ProviderMetadata } from '../../types';
import BaseLLM from '../../base/llm';
import BaseEmbedding from '../../base/embedding';
import TimewebLLM from './timewebLLM';

interface TimewebConfig {
  baseURL: string;
  agentAccessId: string;
  apiKey: string;
  model: string;
  xProxySource?: string;
}

const providerConfigFields: UIConfigField[] = [
  {
    type: 'string',
    name: 'API Base URL',
    key: 'baseURL',
    description: 'Timeweb Cloud AI API base URL',
    required: true,
    placeholder: 'https://api.timeweb.cloud',
    env: 'TIMEWEB_API_BASE_URL',
    scope: 'server',
  },
  {
    type: 'string',
    name: 'Agent Access ID',
    key: 'agentAccessId',
    description: 'Agent access ID from Timeweb Cloud AI',
    required: true,
    placeholder: '',
    env: 'TIMEWEB_AGENT_ACCESS_ID',
    scope: 'server',
  },
  {
    type: 'password',
    name: 'API Key',
    key: 'apiKey',
    description: 'Bearer token for Timeweb Cloud AI',
    required: true,
    placeholder: '',
    env: 'TIMEWEB_API_KEY',
    scope: 'server',
  },
  {
    type: 'string',
    name: 'Model',
    key: 'model',
    description: 'Model key (e.g. gpt-4)',
    required: true,
    placeholder: 'gpt-4',
    env: 'LLM_CHAT_MODEL',
    scope: 'server',
  },
  {
    type: 'string',
    name: 'X-Proxy-Source',
    key: 'xProxySource',
    description: 'Optional header for Timeweb API',
    required: false,
    placeholder: '',
    env: 'TIMEWEB_X_PROXY_SOURCE',
    scope: 'server',
  },
];

class TimewebProvider extends BaseModelProvider<TimewebConfig> {
  constructor(id: string, name: string, config: TimewebConfig) {
    super(id, name, config);
  }

  getTimewebBaseURL(): string {
    const base = this.config.baseURL.replace(/\/$/, '');
    return `${base}/api/v1/cloud-ai/agents/${this.config.agentAccessId}/v1`;
  }

  async getDefaultModels(): Promise<ModelList> {
    try {
      const url = `${this.getTimewebBaseURL()}/models`;
      const res = await fetch(url, {
        headers: {
          Authorization: `Bearer ${this.config.apiKey}`,
          'Content-Type': 'application/json',
          ...(this.config.xProxySource && {
            'x-proxy-source': this.config.xProxySource,
          }),
        },
      });

      if (!res.ok) {
        throw new Error(`Timeweb API error: ${res.status} ${res.statusText}`);
      }

      const data = (await res.json()) as { data?: { id: string }[] };
      const models: Model[] = (data.data ?? []).map((m) => ({
        name: m.id,
        key: m.id,
      }));

      // Если API вернул пустой список — используем модель из конфигурации
      const chat =
        models.length > 0
          ? models
          : [{ name: this.config.model, key: this.config.model }];

      return {
        chat,
        embedding: [],
      };
    } catch (err) {
      return {
        chat: [{ name: this.config.model, key: this.config.model }],
        embedding: [],
      };
    }
  }

  async getModelList(): Promise<ModelList> {
    return this.getDefaultModels();
  }

  async loadChatModel(key: string): Promise<BaseLLM<unknown>> {
    return new TimewebLLM({
      apiKey: this.config.apiKey,
      baseURL: this.getTimewebBaseURL(),
      model: key,
      defaultHeaders: this.config.xProxySource
        ? { 'x-proxy-source': this.config.xProxySource }
        : undefined,
    });
  }

  async loadEmbeddingModel(_key: string): Promise<BaseEmbedding<unknown>> {
    throw new Error(
      'Timeweb Cloud AI does not provide embedding models. Use Ollama for embeddings.',
    );
  }

  static parseAndValidate(raw: unknown): TimewebConfig {
    if (!raw || typeof raw !== 'object')
      throw new Error('Invalid config provided. Expected object');

    const obj = raw as Record<string, unknown>;
    if (!obj.baseURL || !obj.agentAccessId || !obj.apiKey)
      throw new Error(
        'Invalid config. baseURL, agentAccessId and apiKey are required',
      );

    return {
      baseURL: String(obj.baseURL),
      agentAccessId: String(obj.agentAccessId),
      apiKey: String(obj.apiKey),
      model: String(obj.model || 'gpt-4'),
      xProxySource: obj.xProxySource ? String(obj.xProxySource) : undefined,
    };
  }

  static getProviderConfigFields(): UIConfigField[] {
    return providerConfigFields;
  }

  static getProviderMetadata(): ProviderMetadata {
    return {
      key: 'timeweb',
      name: 'Timeweb Cloud AI',
    };
  }
}

export default TimewebProvider;
