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

export const SMS_SERVICE = 'SmsService';

const SMS_RU_SEND_URL = 'https://sms.ru/sms/send';

/** Ответ API sms.ru (фрагмент для одного номера). */
interface SmsRuSmsItem {
  status: string;
  status_code: number;
  sms_id?: string;
  status_text?: string;
}

/** Ответ API sms.ru при json=1. */
interface SmsRuResponse {
  status: string;
  status_code: number;
  sms?: Record<string, SmsRuSmsItem>;
  balance?: number;
}

/** Интерфейс для отправки SMS. В проде подставьте реализацию (SMS.ru, Twilio и т.д.). */
export interface ISmsSender {
  sendVerificationCode(phone: string, code: string): Promise<void>;
}

@Injectable()
export class SmsService implements ISmsSender {
  private readonly logger = new Logger(SmsService.name);
  private readonly apiId: string | undefined;
  private readonly isDev: boolean;

  constructor(private readonly configService: ConfigService) {
    this.apiId = this.configService.get<string>('SMS_RU_API_ID');
    this.isDev = this.configService.get<string>('NODE_ENV') === 'development';
    if (!this.apiId && !this.isDev) {
      this.logger.warn(
        'SMS_RU_API_ID не задан — SMS не отправляются, код верификации только логируется',
      );
    }
  }

  async sendVerificationCode(phone: string, code: string): Promise<void> {
    if (this.isDev) {
      this.logger.log(`[dev] Код верификации для ${phone}: ${code}`);
      return;
    }

    const msg = `Ваш код: ${code}`;
    const to = this.toSmsRuPhone(phone);

    if (!this.apiId) {
      this.logger.log(`[SMS stub] Код для ${phone}: ${code}`);
      return;
    }

    const url = new URL(SMS_RU_SEND_URL);
    url.searchParams.set('api_id', this.apiId);
    url.searchParams.set('to', to);
    url.searchParams.set('msg', msg);
    url.searchParams.set('json', '1');

    try {
      const res = await fetch(url.toString());
      const data = (await res.json()) as SmsRuResponse;

      if (data.status !== 'OK' || data.status_code !== 100) {
        this.logger.error(`SMS.ru: ошибка запроса status=${data.status} status_code=${data.status_code}`);
        throw new Error(`SMS.ru: ${data.status_code}`);
      }

      const item = data.sms?.[to];
      if (item?.status !== 'OK') {
        const text = item?.status_text ?? 'неизвестная ошибка';
        this.logger.error(`SMS.ru: не удалось отправить на ${to}: ${text}`);
        throw new Error(`SMS.ru: ${text}`);
      }

      this.logger.log(`SMS отправлен на ${phone}, код=${code}, sms_id=${item.sms_id ?? '—'}`);
    } catch (err) {
      this.logger.error(`Ошибка отправки SMS на ${phone}:`, err);
      throw err;
    }
  }

  /** Номер в формате sms.ru: только цифры, например 79255070602. */
  private toSmsRuPhone(phone: string): string {
    const digits = phone.replace(/\D/g, '');
    if (digits.length === 10 && digits.startsWith('9')) return '7' + digits;
    if (digits.length === 11 && digits.startsWith('7')) return digits;
    return digits;
  }
}
