import type { CalculatorDef } from '$lib/data/calculators';
import { categories, getCanonicalSlug, getEffectiveCategory, isIndexableCalculator } from '$lib/data/calculators';

export const SITE_URL = 'https://howdoyouconvert.com';
export const SITE_NAME = 'HowDoYouConvert.com';
export const DEFAULT_ROBOTS = 'index,follow';
export const DEFAULT_TWITTER_CARD = 'summary';

type OpenGraphType = 'website' | 'article';

type SeoInput = {
  title: string;
  description: string;
  pathname: string;
  type?: OpenGraphType;
  canonical?: string;
  robots?: string;
};

const normalizePathname = (pathname: string): string => {
  const pathWithSlash = pathname.startsWith('/') ? pathname : `/${pathname}`;
  const normalized = pathWithSlash.replace(/\/{2,}/g, '/');
  if (normalized.length > 1 && normalized.endsWith('/')) {
    return normalized.slice(0, -1);
  }
  return normalized;
};

export const canonicalUrl = (pathname: string): string => `${SITE_URL}${normalizePathname(pathname)}`;

export const buildSeoMeta = ({ title, description, pathname, type = 'website', canonical: canonicalOverride, robots = DEFAULT_ROBOTS }: SeoInput) => {
  const canonical = canonicalOverride ?? canonicalUrl(pathname);
  return {
    canonical,
    robots,
    og: {
      type,
      title,
      description,
      url: canonical,
      siteName: SITE_NAME,
    },
    twitter: {
      card: DEFAULT_TWITTER_CARD,
      title,
      description,
    },
  };
};

export const toJsonLd = (value: unknown): string => JSON.stringify(value).replace(/</g, '\\u003c');

export const escapeXml = (value: string): string =>
  value
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&apos;');

export const calculatorDescription = (calc: CalculatorDef): string => {
  const category = categories[getEffectiveCategory(calc)]?.label ?? 'unit';
  if (['3col', '3col-mul'].includes(calc.type)) {
    return `Compute ${calc.labels.in3 ?? 'the derived value'} using ${calc.labels.in1} and ${calc.labels.in2}. Enter any two fields to solve the third.`;
  }
  return `Convert ${calc.labels.in1} to ${calc.labels.in2} with a fast ${category.toLowerCase()} calculator. Includes a bidirectional converter, formula notes, examples, and reference values.`;
};

export const calculatorSeo = (calc: CalculatorDef) => {
  const canonicalSlug = getCanonicalSlug(calc);
  const noindex = canonicalSlug !== calc.slug || !isIndexableCalculator(calc);
  const title = `${calc.name} — ${SITE_NAME}`;
  const description = calculatorDescription(calc);
  const canonical = canonicalUrl(`/${canonicalSlug}`);

  return {
    ...buildSeoMeta({
      title,
      description,
      pathname: `/${calc.slug}`,
      canonical,
      robots: noindex ? 'noindex,follow' : DEFAULT_ROBOTS,
    }),
    title,
    description,
    canonicalUrl: canonical,
    canonicalSlug,
    noindex,
  };
};

export const calculatorJsonLd = (calc: CalculatorDef, url: string) => ({
  '@context': 'https://schema.org',
  '@type': 'WebApplication',
  name: `${calc.name} Converter`,
  url,
  applicationCategory: 'UtilitiesApplication',
  operatingSystem: 'Any',
  isAccessibleForFree: true,
  description: calculatorDescription(calc),
});
