import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { OpenRouter } from '@openrouter/sdk';

export interface ChatMessageDto {
  role: 'user' | 'assistant' | 'system';
  content: string;
}

@Injectable()
export class AiService {
  private readonly logger = new Logger(AiService.name);

  constructor(private readonly configService: ConfigService) {}

  private getOpenRouterClient(): OpenRouter {
    const apiKey =
      this.configService.get<string>('OPENROUTER_API_KEY') ||
      process.env.OPENROUTER_API_KEY ||
      '';

    return new OpenRouter({ apiKey });
  }

  async chat(
    messages: ChatMessageDto[],
    model = 'openai/gpt-oss-20b:free',
  ): Promise<{ text: string; reasoningTokens?: number }> {
    const openrouter = this.getOpenRouterClient();

    try {
      const stream = (await openrouter.chat.send({
        chatRequest: {
          model: model || 'openai/gpt-oss-20b:free',
          messages: messages as any,
          stream: true,
        },
      })) as any;

      let responseText = '';
      let reasoningTokens: number | undefined;

      for await (const chunk of stream) {
        const content = chunk.choices?.[0]?.delta?.content;
        if (content) {
          responseText += content;
        }

        if (chunk.usage?.completionTokensDetails?.reasoningTokens) {
          reasoningTokens = chunk.usage.completionTokensDetails.reasoningTokens;
          this.logger.log(`Reasoning tokens: ${reasoningTokens}`);
        }
      }

      return { text: responseText, reasoningTokens };
    } catch (error) {
      this.logger.error('OpenRouter API request failed:', error);
      throw error;
    }
  }

  async streamChat(
    messages: ChatMessageDto[],
    res: any,
    model = 'openai/gpt-oss-20b:free',
  ): Promise<void> {
    const openrouter = this.getOpenRouterClient();

    try {
      const stream = (await openrouter.chat.send({
        chatRequest: {
          model: model || 'openai/gpt-oss-20b:free',
          messages: messages as any,
          stream: true,
        },
      })) as any;

      res.setHeader('Content-Type', 'text/plain; charset=utf-8');
      res.setHeader('Transfer-Encoding', 'chunked');

      for await (const chunk of stream) {
        const content = chunk.choices?.[0]?.delta?.content;
        if (content) {
          res.write(content);
        }

        if (chunk.usage?.completionTokensDetails?.reasoningTokens) {
          this.logger.log(
            `Reasoning tokens: ${chunk.usage.completionTokensDetails.reasoningTokens}`,
          );
        }
      }

      res.end();
    } catch (error) {
      this.logger.error('OpenRouter streaming failed:', error);
      if (!res.headersSent) {
        res.status(500).json({ message: 'OpenRouter streaming failed', error: error.message });
      } else {
        res.end();
      }
    }
  }
}
