import { existsSync, statSync } from 'fs';
import { basename, extname, isAbsolute, relative, resolve } from 'path';

const imageExtensions = ['.jpg', '.jpeg', '.png', '.webp', '.gif', '.svg'];
const fileManagerRoot = resolve(process.cwd(), 'storage', 'file-manager');

export function resolveProductImageUrl(code: unknown, inch: unknown) {
  return resolveFileManagerImageUrl({
    code,
    folder: formatImageFolder(inch),
  });
}

export function resolveRootImageUrl(code: unknown, name?: unknown, fallbackPath?: unknown) {
  return resolveFileManagerImageUrl({ code, name, fallbackPath });
}

export function fileManagerContentUrl(relativePath: string) {
  return `/api/file-manager/content?path=${encodeURIComponent(relativePath)}`;
}

function resolveFileManagerImageUrl(options: {
  code?: unknown;
  name?: unknown;
  folder?: unknown;
  fallbackPath?: unknown;
}) {
  const folder = normalizePath(options.folder);
  const directPath = fileManagerPathFromUrl(options.fallbackPath);
  if (directPath && fileExists(directPath)) {
    return fileManagerContentUrl(directPath);
  }

  const bases = unique([
    imageBase(options.code),
    imageBase(options.fallbackPath),
    imageBase(options.name),
  ]);

  for (const base of bases) {
    for (const candidate of imageCandidates(base)) {
      const relativePath = [folder, candidate].filter(Boolean).join('/');
      if (fileExists(relativePath)) {
        return fileManagerContentUrl(relativePath);
      }
    }
  }

  return '';
}

function fileExists(relativePath: string) {
  const fullPath = resolve(fileManagerRoot, relativePath);
  const distance = relative(fileManagerRoot, fullPath);
  if (distance.startsWith('..') || isAbsolute(distance)) {
    return false;
  }

  try {
    return existsSync(fullPath) && statSync(fullPath).isFile();
  } catch {
    return false;
  }
}

function fileManagerPathFromUrl(value: unknown) {
  const text = clean(value);
  if (!text) return '';

  const marker = '/api/file-manager/content?';
  const markerIndex = text.indexOf(marker);
  if (markerIndex < 0) return '';

  try {
    const query = text.slice(markerIndex + marker.length);
    const params = new URLSearchParams(query);
    return normalizePath(params.get('path') || '');
  } catch {
    return '';
  }
}

function imageBase(value: unknown) {
  const text = clean(value)
    .split(/[?#]/)[0]
    .replace(/\\/g, '/');
  if (!text) return '';

  const name = basename(text);
  const extension = extname(name);
  return extension ? name.slice(0, -extension.length) : name;
}

function imageCandidates(base: string) {
  if (!base) return [];
  return imageExtensions.flatMap((extension) => [
    `${base}${extension}`,
    `${base}${extension.toUpperCase()}`,
  ]);
}

function formatImageFolder(value: unknown) {
  const text = clean(value);
  if (!text) return '';

  const numeric = Number(text);
  if (Number.isFinite(numeric)) {
    return Number.isInteger(numeric) ? String(numeric) : String(numeric);
  }

  return text;
}

function normalizePath(value: unknown) {
  return clean(value)
    .replace(/\\/g, '/')
    .split('/')
    .map((segment) => segment.trim())
    .filter((segment) => segment && segment !== '.' && segment !== '..')
    .join('/');
}

function unique(values: string[]) {
  return [...new Set(values.filter(Boolean))];
}

function clean(value: unknown) {
  return String(value ?? '').trim();
}
