import type { APIRoute } from 'astro';

const POCKETBASE_URL = import.meta.env.POCKETBASE_URL || 'http://localhost:8090';

// Rate limiting: макс. 3 запроса в час на один email
const RATE_LIMIT_MAX_REQUESTS = 3;
const RATE_LIMIT_WINDOW_MS = 60 * 60 * 1000; // 1 час

// In-memory хранилище для rate limiting (email -> массив временных меток)
const rateLimitStore = new Map<string, number[]>();

function cleanOldRecords(email: string, now: number) {
  const timestamps = rateLimitStore.get(email) || [];
  const windowStart = now - RATE_LIMIT_WINDOW_MS;
  const validTimestamps = timestamps.filter(ts => ts > windowStart);
  if (validTimestamps.length === 0) {
    rateLimitStore.delete(email);
  } else {
    rateLimitStore.set(email, validTimestamps);
  }
}

function checkRateLimit(email: string): { allowed: boolean; remaining?: number; resetIn?: number } {
  const now = Date.now();
  const normalizedEmail = email.toLowerCase().trim();
  
  cleanOldRecords(normalizedEmail, now);
  
  const timestamps = rateLimitStore.get(normalizedEmail) || [];
  
  if (timestamps.length >= RATE_LIMIT_MAX_REQUESTS) {
    const oldestTimestamp = timestamps[0];
    const resetIn = RATE_LIMIT_WINDOW_MS - (now - oldestTimestamp);
    return { allowed: false, resetIn };
  }
  
  timestamps.push(now);
  rateLimitStore.set(normalizedEmail, timestamps);
  
  return { allowed: true, remaining: RATE_LIMIT_MAX_REQUESTS - timestamps.length };
}

// Функция логирования с временной меткой
function log(message: string, data?: unknown) {
  const timestamp = new Date().toISOString();
  console.log(`[PASSWORD_RESET][${timestamp}] ${message}`, data ? JSON.stringify(data, null, 2) : '');
}

function logError(message: string, error?: unknown) {
  const timestamp = new Date().toISOString();
  console.error(`[PASSWORD_RESET][${timestamp}] ERROR: ${message}`, error);
}

export const POST: APIRoute = async ({ request }) => {
  const requestId = crypto.randomUUID();
  log(`=== Начало запроса сброса пароля #${requestId} ===`);

  try {
    let body;
    try {
      body = await request.json();
    } catch (parseError) {
      logError(`Ошибка парсинга JSON #${requestId}:`, parseError);
      return new Response(
        JSON.stringify({ error: 'Неверный формат данных' }),
        { status: 400, headers: { 'Content-Type': 'application/json' } }
      );
    }

    const { email } = body;
    log(`Получен email для сброса пароля: ${email ? email.substring(0, 3) + '***' : 'undefined'}`);

    if (!email) {
      logError(`Валидация не пройдена #${requestId}: email не указан`);
      return new Response(
        JSON.stringify({ error: 'Email обязателен' }),
        { status: 400, headers: { 'Content-Type': 'application/json' } }
      );
    }

    // Проверка rate limiting
    const rateLimitResult = checkRateLimit(email);
    if (!rateLimitResult.allowed) {
      const resetMinutes = Math.ceil((rateLimitResult.resetIn || 0) / 60000);
      logError(`Rate limit превышен #${requestId} для ${email}`);
      return new Response(
        JSON.stringify({
          error: 'Слишком много запросов. Попробуйте позже',
          retryAfter: resetMinutes
        }),
        { 
          status: 429, 
          headers: { 
            'Content-Type': 'application/json',
            'Retry-After': String(resetMinutes * 60)
          } 
        }
      );
    }

    // Запрос сброса пароля в PocketBase
    log('Запрос в PocketBase для сброса пароля...');
    const resetUrl = `${POCKETBASE_URL}/api/collections/users/request-password-reset`;
    log(`POST ${resetUrl}`);

    const response = await fetch(resetUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email }),
    });

    log(`Ответ PocketBase: статус ${response.status}`);

    // PocketBase возвращает 204 при успехе
    if (response.status === 204) {
      log(`✅ Запрос сброса пароля выполнен #${requestId} для ${email}`);
      return new Response(
        JSON.stringify({
          success: true,
          message: 'Письмо для сброса пароля отправлено'
        }),
        { status: 200, headers: { 'Content-Type': 'application/json' } }
      );
    }

    let data;
    try {
      data = await response.json();
    } catch (parseError) {
      logError(`Ошибка парсинга ответа PocketBase #${requestId}:`, parseError);
      return new Response(
        JSON.stringify({ error: 'Ошибка обработки ответа' }),
        { status: 500, headers: { 'Content-Type': 'application/json' } }
      );
    }

    log('Ответ PocketBase (данные):', data);

    if (!response.ok) {
      logError(`Ошибка PocketBase #${requestId} (${response.status}):`, data);
      return new Response(
        JSON.stringify({
          error: data.message || 'Ошибка при отправке письма для сброса пароля'
        }),
        { status: response.status, headers: { 'Content-Type': 'application/json' } }
      );
    }

    log(`✅ Запрос сброса пароля выполнен #${requestId}`);

    return new Response(
      JSON.stringify({
        success: true,
        message: 'Письмо для сброса пароля отправлено'
      }),
      { status: 200, headers: { 'Content-Type': 'application/json' } }
    );

  } catch (error) {
    logError(`Исключение #${requestId}:`, error);
    return new Response(
      JSON.stringify({
        error: 'Внутренняя ошибка сервера',
        details: error instanceof Error ? error.message : String(error)
      }),
      { status: 500, headers: { 'Content-Type': 'application/json' } }
    );
  }
};
