const db = require('../db');
const logger = require('../utils/logger');

class VerificationService {
  constructor() {
    this.codeLength = 6;
    this.expirationMinutes = 15;
  }

  // Генерация кода
  generateCode() {
    const code = Math.random()
      .toString(36)
      .substring(2, 2 + this.codeLength)
      .toUpperCase();
    logger.info(`Generated verification code: ${code}`);
    return code;
  }

  // Создание кода верификации
  async createVerificationCode(provider, providerId, userId) {
    const code = this.generateCode();
    const expiresAt = new Date(Date.now() + this.expirationMinutes * 60 * 1000);

    try {
      logger.info(
        `Creating verification code for ${provider}:${providerId}, userId: ${userId || 'null'}`
      );

      // Если userId не указан, добавляем запись без ссылки на пользователя
      if (userId === null || userId === undefined) {
        await db.getQuery()(
          `INSERT INTO verification_codes 
           (code, provider, provider_id, expires_at) 
           VALUES ($1, $2, $3, $4)`,
          [code, provider, providerId, expiresAt]
        );
      } else {
        await db.getQuery()(
          `INSERT INTO verification_codes 
           (code, provider, provider_id, user_id, expires_at) 
           VALUES ($1, $2, $3, $4, $5)`,
          [code, provider, providerId, userId, expiresAt]
        );
      }

      logger.info(`Verification code created successfully for ${provider}:${providerId}`);
      return code;
    } catch (error) {
      logger.error('Error creating verification code:', {
        error: error.message,
        provider,
        providerId,
        userId,
      });
      throw error;
    }
  }

  // Проверка кода
  async verifyCode(code, provider, providerId) {
    try {
      logger.info(`Verifying code for ${provider}:${providerId}`);

      // Преобразуем код в верхний регистр для сравнения
      const normalizedCode = code.toUpperCase();
      logger.info(`Normalized code: ${normalizedCode}`);

      // Проверим, есть ли такой код в базе (для отладки)
      const checkResult = await db.getQuery()(
        `SELECT code FROM verification_codes 
         WHERE provider = $1 
         AND provider_id = $2 
         AND used = false 
         AND expires_at > NOW()`,
        [provider, providerId]
      );

      if (checkResult.rows.length > 0) {
        logger.info(
          `Found codes for ${provider}:${providerId}: ${JSON.stringify(checkResult.rows.map((r) => r.code))}`
        );
      } else {
        logger.warn(`No active codes found for ${provider}:${providerId}`);
      }

      const result = await db.getQuery()(
        `SELECT * FROM verification_codes 
         WHERE code = $1 
         AND provider = $2 
         AND provider_id = $3 
         AND used = false 
         AND expires_at > NOW()`,
        [normalizedCode, provider, providerId]
      );

      if (result.rows.length === 0) {
        logger.warn(
          `Invalid or expired code for ${provider}:${providerId}. Input: ${normalizedCode}`
        );
        return { success: false, error: 'Неверный или истекший код' };
      }

      const verification = result.rows[0];

      // Отмечаем код как использованный
      await db.getQuery()(
        'UPDATE verification_codes SET used = true WHERE id = $1',
        [verification.id]
      );

      logger.info(`Code verified successfully for ${provider}:${providerId}`);
      return {
        success: true,
        userId: verification.user_id,
        providerId: verification.provider_id,
      };
    } catch (error) {
      logger.error('Error verifying code:', {
        error: error.message,
        code,
        provider,
        providerId,
      });
      throw error;
    }
  }

  // Очистка истекших кодов
  async cleanupExpiredCodes() {
    try {
      const result = await db.getQuery()(
        'DELETE FROM verification_codes WHERE expires_at <= NOW() RETURNING id'
      );
      logger.info(`Cleaned up ${result.rowCount} expired verification codes`);
    } catch (error) {
      logger.error('Error cleaning up expired codes:', error);
    }
  }
}

const verificationService = new VerificationService();
module.exports = verificationService;
