const axios = require('axios');
const config = require('./config');
const logger = require('./logger');

const forecastCache = new Map();

function normalizeImageUrl(imageUrl) {
  if (!imageUrl) return null;

  try {
    return new URL(imageUrl, config.baseUrl).toString();
  } catch {
    return null;
  }
}

function pickForecastImage(item) {
  if (!Array.isArray(item?.images)) return null;

  for (const candidate of item.images) {
    const normalized = normalizeImageUrl(candidate);
    if (normalized) {
      return normalized;
    }
  }

  return null;
}

function normalizeForecastText(value) {
  if (!value) return null;

  const normalized = String(value)
    .replace(/\s+/g, ' ')
    .replace(/\s+([),.:])/g, '$1')
    .replace(/([(])\s+/g, '$1')
    .trim();

  return normalized || null;
}

async function recognizeForecastText(item) {
  if (!config.forecastOcrEnabled || !config.forecastOcrUrl) {
    return { forecast: null, imageUrl: null, source: 'disabled' };
  }

  const imageUrl = pickForecastImage(item);
  if (!imageUrl) {
    return { forecast: null, imageUrl: null, source: 'no-image' };
  }

  if (forecastCache.has(imageUrl)) {
    return {
      forecast: forecastCache.get(imageUrl),
      imageUrl,
      source: 'cache'
    };
  }

  try {
    const imageResponse = await axios.get(imageUrl, {
      responseType: 'arraybuffer',
      timeout: config.requestTimeoutMs,
      headers: {
        'User-Agent': config.httpUserAgent,
        Referer: config.baseUrl
      }
    });
    const imageBuffer = Buffer.from(imageResponse.data);
    const imageFileName = (() => {
      try {
        const pathname = new URL(imageUrl).pathname;
        const parts = pathname.split('/').filter(Boolean);
        return parts[parts.length - 1] || 'forecast-image';
      } catch {
        return 'forecast-image';
      }
    })();
    const formData = new FormData();
    formData.append('image', new Blob([imageBuffer]), imageFileName);

    const response = await axios.post(
      `${config.forecastOcrUrl.replace(/\/$/, '')}/ocr/forecast`,
      formData,
      {
        timeout: config.forecastOcrTimeoutMs,
        headers: {
          Accept: 'application/json'
        }
      }
    );

    const forecast = normalizeForecastText(response.data?.forecast);
    const rawForecast = normalizeForecastText(response.data?.rawForecast);
    forecastCache.set(imageUrl, forecast);

    return {
      forecast,
      rawForecast,
      imageUrl,
      source: response.data?.cached ? 'service-cache' : 'service'
    };
  } catch (error) {
    logger.warn(`Forecast OCR failed for ${imageUrl}: ${error.message}`);
    return { forecast: null, rawForecast: null, imageUrl, source: 'error' };
  }
}

module.exports = {
  recognizeForecastText
};
