import { getConfiguredAssetBaseUrl } from './backendUrl';

const WIKIMEDIA_FILEPATH_SEGMENT = 'Special:FilePath/';
const WIKIMEDIA_REDIRECT_BASE = 'https://commons.wikimedia.org/wiki/Special:FilePath/';

export const DEFAULT_PLANT_IMAGE_URI =
  'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Monstera_deliciosa2.jpg/330px-Monstera_deliciosa2.jpg';

// Verified working fallback images per category (from main database URLs)
const CATEGORY_FALLBACK_IMAGES: Record<string, string> = {
  succulent: 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Aloe_Vera_houseplant.jpg/330px-Aloe_Vera_houseplant.jpg',
  flowering: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/8b/AnthuriumAndraenum.jpg/330px-AnthuriumAndraenum.jpg',
  medicinal: 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Lavandula_angustifolia_-_K%C3%B6hler%E2%80%93s_Medizinal-Pflanzen-087.jpg/330px-Lavandula_angustifolia_-_K%C3%B6hler%E2%80%93s_Medizinal-Pflanzen-087.jpg',
  tree: 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/25/Ficus_benjamina.jpg/330px-Ficus_benjamina.jpg',
  hanging: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Money_Plant_%28Epipremnum_aureum%29_4.jpg/330px-Money_Plant_%28Epipremnum_aureum%29_4.jpg',
  patterned: 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Starr_080716-9470_Calathea_crotalifera.jpg/330px-Starr_080716-9470_Calathea_crotalifera.jpg',
  pet_friendly: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Chlorophytum_comosum_01.jpg/330px-Chlorophytum_comosum_01.jpg',
  high_humidity: 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/Spathiphyllum_cochlearispathum_RTBG.jpg/330px-Spathiphyllum_cochlearispathum_RTBG.jpg',
  air_purifier: 'https://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Snake_Plant_%28Sansevieria_trifasciata_%27Laurentii%27%29.jpg/330px-Snake_Plant_%28Sansevieria_trifasciata_%27Laurentii%27%29.jpg',
  sun: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Echeveria_elegans_-_1.jpg/330px-Echeveria_elegans_-_1.jpg',
  low_light: 'https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Zamioculcas_zamiifolia_1.jpg/330px-Zamioculcas_zamiifolia_1.jpg',
  easy: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Pilea_peperomioides_Chinese_money_plant.jpg/330px-Pilea_peperomioides_Chinese_money_plant.jpg',
  large: 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Strelitzia_nicolai_3.jpg/330px-Strelitzia_nicolai_3.jpg',
};

const CATEGORY_PRIORITY = [
  'succulent', 'flowering', 'medicinal', 'tree', 'hanging',
  'patterned', 'pet_friendly', 'high_humidity', 'air_purifier',
  'sun', 'low_light', 'easy', 'large',
];

export const getCategoryFallbackImage = (categories: string[]): string => {
  for (const cat of CATEGORY_PRIORITY) {
    if (categories.includes(cat) && CATEGORY_FALLBACK_IMAGES[cat]) {
      return CATEGORY_FALLBACK_IMAGES[cat];
    }
  }
  return DEFAULT_PLANT_IMAGE_URI;
};

const tryDecode = (value: string): string => {
  try {
    return decodeURIComponent(value);
  } catch {
    return value;
  }
};

const decodeRepeatedly = (value: string, rounds = 3): string => {
  let current = value;
  for (let index = 0; index < rounds; index += 1) {
    const decoded = tryDecode(current);
    if (decoded === current) break;
    current = decoded;
  }
  return current;
};

type PlantManifestItem = {
  localImageUri?: string;
  sourceUri?: string;
};

let manifestSourceByLocalUriCache: Map<string, string> | null = null;
let wikimediaSearchCache: Record<string, string | null> | null = null;

const normalizePlantAssetPath = (value?: string | null): string | null => {
  const trimmed = String(value || '').trim();
  if (!trimmed) return null;

  const withoutQuery = trimmed.split(/[?#]/)[0].replace(/\\/g, '/');
  const normalizedPath = withoutQuery.startsWith('/') ? withoutQuery : `/${withoutQuery}`;
  if (!normalizedPath.startsWith('/plants/')) return null;
  if (normalizedPath.includes('..')) return null;
  return normalizedPath;
};

const loadManifestSourceByLocalUri = (): Map<string, string> => {
  if (manifestSourceByLocalUriCache) return manifestSourceByLocalUriCache;

  const nextCache = new Map<string, string>();
  try {
    const manifest = require('../server/public/plants/manifest.json') as { items?: PlantManifestItem[] };
    const items = Array.isArray(manifest?.items) ? manifest.items : [];
    for (const item of items) {
      const localImageUri = normalizePlantAssetPath(item?.localImageUri);
      const sourceUri = String(item?.sourceUri || '').trim();
      if (!localImageUri || !sourceUri) continue;
      nextCache.set(localImageUri, sourceUri);
    }
  } catch {
    // Keep empty cache when manifest is unavailable.
  }

  manifestSourceByLocalUriCache = nextCache;
  return nextCache;
};

const loadWikimediaSearchCache = (): Record<string, string | null> => {
  if (wikimediaSearchCache) return wikimediaSearchCache;

  try {
    wikimediaSearchCache = require('../server/public/plants/wikimedia-search-cache.json') as Record<string, string | null>;
  } catch {
    wikimediaSearchCache = {};
  }

  return wikimediaSearchCache;
};

const resolveServerAssetPath = (rawPath: string): string | null => {
  const normalizedPath = normalizePlantAssetPath(rawPath);
  if (!normalizedPath) return null;

  return `${getConfiguredAssetBaseUrl()}${normalizedPath}`;
};

const unwrapMarkdownLink = (value: string): string => {
  const markdownLink = value.match(/^\[[^\]]+]\((https?:\/\/[^)]+)\)(.*)$/i);
  if (!markdownLink) return value;
  const [, url, suffix] = markdownLink;
  return `${url}${suffix || ''}`;
};

const convertWikimediaFilePathUrl = (value: string): string | null => {
  const segmentIndex = value.indexOf(WIKIMEDIA_FILEPATH_SEGMENT);
  if (segmentIndex < 0) return null;

  const fileNameStart = segmentIndex + WIKIMEDIA_FILEPATH_SEGMENT.length;
  const rawFileName = value.slice(fileNameStart).split(/[?#]/)[0].trim();
  if (!rawFileName) return null;

  const decodedFileName = tryDecode(rawFileName).replace(/\s+/g, ' ').trim();
  const encodedFileName = encodeURIComponent(decodedFileName).replace(/%2F/g, '/');
  return `${WIKIMEDIA_REDIRECT_BASE}${encodedFileName}`;
};

export const getWikimediaFilePathFromThumbnailUrl = (url: string): string | null => {
  if (!url.includes('upload.wikimedia.org/wikipedia/commons/thumb/')) return null;

  // Example: https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Monstera_deliciosa2.jpg/330px-Monstera_deliciosa2.jpg
  // The filename is the segment between the second-to-last and last slash (in many cases)
  // or use a more robust regex
  const parts = url.split('/');
  // Filter out empty parts from trailing slashes
  const filtered = parts.filter(p => !!p);
  if (filtered.length < 5) return null;

  // For thumb URLs, the filename is typically the part before the last part (which is the px-filename)
  // but let's be careful.
  const lastName = filtered[filtered.length - 1];
  const secondLastName = filtered[filtered.length - 2];

  // In thumb URLs, the last part is usually "330px-Filename.jpg"
  // The second to last is "Filename.jpg"
  if (lastName.includes('px-') && lastName.endsWith(secondLastName)) {
    try {
      return decodeURIComponent(secondLastName);
    } catch {
      return secondLastName;
    }
  }

  return null;
};

export const getPlantImageSourceFallbackUri = (rawUri?: string | null): string | null => {
  const localImageUri = normalizePlantAssetPath(rawUri);
  if (!localImageUri) return null;

  const sourceUri = loadManifestSourceByLocalUri().get(localImageUri);
  if (!sourceUri) return null;

  if (/^https?:\/\//i.test(sourceUri)) {
    return tryResolveImageUri(sourceUri);
  }

  if (!sourceUri.startsWith('wikimedia-search:')) {
    return null;
  }

  const rawQuery = sourceUri.slice('wikimedia-search:'.length).trim();
  const decodedQuery = decodeRepeatedly(rawQuery);
  if (!decodedQuery) return null;

  const searchCache = loadWikimediaSearchCache();
  const cachedUrl = searchCache[decodedQuery]
    || searchCache[rawQuery]
    || searchCache[encodeURIComponent(decodedQuery)]
    || null;

  return cachedUrl ? tryResolveImageUri(cachedUrl) : null;
};

export const tryResolveImageUri = (rawUri?: string | null): string | null => {
  if (!rawUri) return null;

  const trimmed = rawUri.trim();
  if (!trimmed) return null;

  const localAssetUri = resolveServerAssetPath(trimmed);
  if (localAssetUri) return localAssetUri;

  const normalized = unwrapMarkdownLink(trimmed);
  const converted = convertWikimediaFilePathUrl(normalized);
  const candidate = (converted || normalized).replace(/^http:\/\//i, 'https://');

  if (!/^(https?:\/\/|file:\/\/|content:\/\/|data:image\/|blob:)/i.test(candidate)) {
    return null;
  }

  return candidate;
};

export const resolveImageUri = (rawUri?: string | null): string => {
  return tryResolveImageUri(rawUri) || DEFAULT_PLANT_IMAGE_URI;
};
