/**
 * Nomadic Studios — Remix SEO Utility
 * app/utils/seo.ts
 *
 * Usage in any route:
 *
 *   import { getSeo } from '~/utils/seo';
 *   import { fetchSeoForPage } from '~/utils/seo.server';
 *   import type { MetaFunction, LoaderFunctionArgs } from '@remix-run/node';
 *
 *   export async function loader({ request }: LoaderFunctionArgs) {
 *     const seo = await fetchSeoForPage('about', request.url);
 *     return Response.json({ seo });
 *   }
 *
 *   export const meta: MetaFunction<typeof loader> = ({ data }) =>
 *     getSeo('about', {}, data?.seo);
 *
 * The third argument (apiData) takes priority over the hardcoded fallbacks.
 */

const BASE_URL = 'https://nomadicstudios.net';
const DEFAULT_IMAGE = `${BASE_URL}/images/og-default.jpg`;

// ─────────────────────────────────────────────────────────────────────────────
// Types
// ─────────────────────────────────────────────────────────────────────────────

interface SeoDefinition {
  path: string;
  title: string;
  description: string;
  ogImage?: string;
  schemaType?: 'organization' | 'service';
  serviceName?: string;
  serviceDesc?: string;
}

interface SeoOverrides {
  title?: string;
  description?: string;
  image?: string;
  canonical?: string;
}

export interface SeoApiData {
  page_key: string;
  path: string;
  title: string;
  description: string;
  og_image?: string | null;
  schema_type?: 'organization' | 'service';
  service_name?: string | null;
  service_desc?: string | null;
}

type MetaDescriptor =
  | { title: string }
  | { name: string; content: string }
  | { property: string; content: string }
  | { tagName: 'link'; rel: string; href: string }
  | { 'script:ld+json': Record<string, unknown> };

// ─────────────────────────────────────────────────────────────────────────────
// Static fallback page definitions (used when API is unavailable)
// ─────────────────────────────────────────────────────────────────────────────

const pages: Record<string, SeoDefinition> = {
  home: {
    path: '/',
    title: 'Nomadic Studios — Professional Creative Spaces in NYC & Bangkok',
    description:
      'Rent professional music, video, photo, art, fashion, and maker studios by the hour. One membership. Multiple cities. Nomadic Studios is the infrastructure for serious creators.',
    ogImage: `${BASE_URL}/images/og-home.jpg`,
    schemaType: 'organization',
  },
  services: {
    path: '/services',
    title: 'Studio Memberships & Services | Nomadic Studios NYC & Bangkok',
    description:
      'Explore Nomadic Studios memberships: access professional studios, rent equipment, book creative professionals, and attend workshops. One platform for every creative need.',
    ogImage: `${BASE_URL}/images/og-home.jpg`,
    schemaType: 'organization',
  },
  'studios.video': {
    path: '/studios/video',
    title: 'Video Studio Rental NYC & Bangkok | Film, Livestream & Podcast',
    description:
      'Rent professional video studios with lighting grids, green screens, streaming encoders, and editing workstations. Hourly booking. No long-term commitment. Nomadic Studios.',
    ogImage: `${BASE_URL}/images/og-video-studio.jpg`,
    schemaType: 'service',
    serviceName: 'Video Studio Rental',
    serviceDesc:
      'Professional video studios for filming, livestreaming, and podcast production. Configurable as full stage or intimate pods.',
  },
  'studios.music': {
    path: '/studios/music',
    title: 'Music Studio Rental NYC & Bangkok | Recording & Production',
    description:
      'Acoustically treated recording studios with professional interfaces, backline on request, and hourly booking. No long-term lease. Just book and create. Nomadic Studios.',
    ogImage: `${BASE_URL}/images/og-music-studio.jpg`,
    schemaType: 'service',
    serviceName: 'Music Studio Rental',
    serviceDesc:
      'Professional recording studios with acoustic treatment, pro interfaces, and optional backline. Hourly rates with no long-term commitment.',
  },
  'studios.photo': {
    path: '/studios/photo',
    title: 'Photo Studio Rental NYC & Bangkok | Professional Photography',
    description:
      'Rent fully-equipped photo studios with professional lighting, backdrops, and cyclorama walls. Hourly and half-day rates. Perfect for fashion, product, and portrait shoots.',
    ogImage: `${BASE_URL}/images/og-photo-studio.jpg`,
    schemaType: 'service',
    serviceName: 'Photography Studio Rental',
    serviceDesc:
      'Professional photo studios with lighting rigs, backdrops, and cyclorama walls for fashion, product, and portrait photography.',
  },
  'studios.art': {
    path: '/studios/art',
    title: 'Art Studio Rental NYC & Bangkok | Painting, Pottery & Jewelry',
    description:
      'Shared and private art studio spaces for painting, pottery, and jewelry making. Materials and equipment provided. Drop-in sessions and monthly memberships available.',
    ogImage: `${BASE_URL}/images/og-art-studio.jpg`,
    schemaType: 'service',
    serviceName: 'Art Studio Rental',
    serviceDesc:
      'Multidisciplinary art studios for painting, ceramics, and jewelry. Open shared sessions and private buyouts available.',
  },
  'studios.fashion': {
    path: '/studios/fashion',
    title: 'Fashion Studio Rental NYC & Bangkok | Design, Shoot & Produce',
    description:
      'Professional fashion studios with fitting rooms, sewing equipment, rack storage, and photo backdrops. Book by the hour for design work, shoots, and fittings.',
    ogImage: `${BASE_URL}/images/og-fashion-studio.jpg`,
    schemaType: 'service',
    serviceName: 'Fashion Studio Rental',
    serviceDesc:
      'Fashion studios with fitting rooms, production equipment, and shoot-ready backdrops. Bookable by the hour.',
  },
  'studios.maker': {
    path: '/studios/maker',
    title: 'Makerspace Rental NYC & Bangkok | Fabrication & 3D Printing',
    description:
      'Access professional fabrication tools including 3D printers, laser cutters, and CNC machines. Hourly and membership rates. Nomadic Studios makerspace in NYC and Bangkok.',
    ogImage: `${BASE_URL}/images/og-makerspace.jpg`,
    schemaType: 'service',
    serviceName: 'Makerspace & Fabrication Studio',
    serviceDesc:
      'Professional makerspace with 3D printing, laser cutting, and CNC fabrication equipment. Hourly access and monthly memberships.',
  },
  equipment: {
    path: '/equipment',
    title: 'Professional Equipment Rental | Cameras, Lights, Audio & More',
    description:
      'Rent professional cameras, lighting rigs, audio gear, and production equipment by the day. Available to Nomadic Studios members and non-members in NYC and Bangkok.',
    ogImage: `${BASE_URL}/images/og-equipment.jpg`,
    schemaType: 'service',
    serviceName: 'Creative Equipment Rental',
    serviceDesc:
      'Professional camera, audio, and lighting equipment rental by the day. Available in NYC and Bangkok.',
  },
  people: {
    path: '/people',
    title: 'Hire Creative Professionals | Photographers, Engineers & More',
    description:
      'Book vetted photographers, videographers, sound engineers, art directors, and creative professionals by the project or day. On-demand creative teams. Nomadic Studios.',
    ogImage: `${BASE_URL}/images/og-people.jpg`,
    schemaType: 'service',
    serviceName: 'Creative Professional Booking',
    serviceDesc:
      'On-demand creative professionals bookable by the day or project. Photographers, videographers, engineers, and more.',
  },
  events: {
    path: '/events',
    title: 'Creative Workshops & Networking Events | Nomadic Studios',
    description:
      'Join photography workshops, music production masterclasses, and creative networking events in NYC and Bangkok. Open to members and non-members. Nomadic Studios.',
    ogImage: `${BASE_URL}/images/og-events.jpg`,
    schemaType: 'organization',
  },
  about: {
    path: '/about',
    title: 'About Nomadic Studios | The Infrastructure for Creators',
    description:
      'Nomadic Studios is a global network of creative spaces giving serious creators access to professional studios, gear, and teams in NYC and Bangkok. Our story.',
    ogImage: `${BASE_URL}/images/og-home.jpg`,
    schemaType: 'organization',
  },
  partners: {
    path: '/partners',
    title: 'Partners & Investors | Nomadic Studios',
    description:
      'Partner with Nomadic Studios — the global creative infrastructure network expanding across NYC, Bangkok, and beyond. Learn about partnership and investment opportunities.',
    ogImage: `${BASE_URL}/images/og-home.jpg`,
    schemaType: 'organization',
  },
  'join-us': {
    path: '/join-us',
    title: 'Join Our Team | Nomadic Studios Careers',
    description:
      'Work at the intersection of creativity and technology. Nomadic Studios is building creative infrastructure for serious creators worldwide. See open roles.',
    ogImage: `${BASE_URL}/images/og-home.jpg`,
    schemaType: 'organization',
  },
};

// ─────────────────────────────────────────────────────────────────────────────
// Schema builders
// ─────────────────────────────────────────────────────────────────────────────

function buildOrganizationSchema(): Record<string, unknown> {
  return {
    '@context': 'https://schema.org',
    '@graph': [
      {
        '@type': 'Organization',
        '@id': `${BASE_URL}/#organization`,
        name: 'Nomadic Studios',
        url: BASE_URL,
        logo: { '@type': 'ImageObject', url: `${BASE_URL}/images/logo.png` },
        sameAs: [
          'https://www.facebook.com/MadeAtNomadic/',
          'https://www.linkedin.com/company/made-at-nomadic',
          'https://www.instagram.com/made.at.nomadic',
          'https://bsky.app/profile/nomadicstudios.net',
        ],
      },
      {
        '@type': 'WebSite',
        '@id': `${BASE_URL}/#website`,
        url: BASE_URL,
        name: 'Nomadic Studios',
        publisher: { '@id': `${BASE_URL}/#organization` },
      },
    ],
  };
}

function buildServiceSchema(def: SeoDefinition): Record<string, unknown> {
  return {
    '@context': 'https://schema.org',
    '@type': 'Service',
    name: def.serviceName ?? def.title,
    description: def.serviceDesc ?? def.description,
    url: `${BASE_URL}${def.path}`,
    provider: { '@id': `${BASE_URL}/#organization` },
    areaServed: [
      { '@type': 'City', name: 'New York City' },
      { '@type': 'City', name: 'Bangkok' },
    ],
  };
}

// ─────────────────────────────────────────────────────────────────────────────
// Main export
// ─────────────────────────────────────────────────────────────────────────────

/**
 * Build Remix meta descriptors for a page.
 *
 * @param pageKey   - Key into the static fallback map (e.g. "home", "studios.video")
 * @param overrides - Manual overrides (title, description, image, canonical)
 * @param apiData   - Data fetched from the backend seo_metatags table (takes priority over static fallback)
 */
export function getSeo(
  pageKey: string,
  overrides: SeoOverrides = {},
  apiData?: SeoApiData | null,
): MetaDescriptor[] {
  const staticDef = pages[pageKey] ?? pages['home'];

  const def: SeoDefinition = apiData
    ? {
        path: apiData.path,
        title: apiData.title,
        description: apiData.description,
        ogImage: apiData.og_image ?? undefined,
        schemaType: apiData.schema_type ?? 'organization',
        serviceName: apiData.service_name ?? undefined,
        serviceDesc: apiData.service_desc ?? undefined,
      }
    : staticDef;

  const title       = overrides.title       ?? def.title;
  const description = overrides.description ?? def.description;
  const image       = overrides.image       ?? def.ogImage ?? DEFAULT_IMAGE;
  const canonical   = overrides.canonical   ?? `${BASE_URL}${def.path}`;

  const schema =
    def.schemaType === 'service'
      ? buildServiceSchema(def)
      : buildOrganizationSchema();

  return [
    { title },
    { name: 'description',          content: description },
    { tagName: 'link', rel: 'canonical', href: canonical },

    // Open Graph
    { property: 'og:type',          content: 'website' },
    { property: 'og:url',           content: canonical },
    { property: 'og:title',         content: title },
    { property: 'og:description',   content: description },
    { property: 'og:image',         content: image },
    { property: 'og:image:width',   content: '1200' },
    { property: 'og:image:height',  content: '630' },
    { property: 'og:site_name',     content: 'Nomadic Studios' },

    // Twitter Card
    { name: 'twitter:card',         content: 'summary_large_image' },
    { name: 'twitter:title',        content: title },
    { name: 'twitter:description',  content: description },
    { name: 'twitter:image',        content: image },

    // Schema.org JSON-LD
    { 'script:ld+json': schema },
  ];
}

// ─────────────────────────────────────────────────────────────────────────────
// Convenience: dynamic event schema (use on /events for individual events)
// ─────────────────────────────────────────────────────────────────────────────

export function getEventSchema(event: {
  name: string;
  description: string;
  startDate: string;
  endDate: string;
  locationName: string;
  city: string;
  country: string;
  imageUrl?: string;
}): MetaDescriptor {
  return {
    'script:ld+json': {
      '@context': 'https://schema.org',
      '@type': 'Event',
      name: event.name,
      description: event.description,
      startDate: event.startDate,
      endDate: event.endDate,
      eventStatus: 'https://schema.org/EventScheduled',
      eventAttendanceMode: 'https://schema.org/OfflineEventAttendanceMode',
      location: {
        '@type': 'Place',
        name: event.locationName,
        address: {
          '@type': 'PostalAddress',
          addressLocality: event.city,
          addressCountry: event.country,
        },
      },
      organizer: { '@id': `${BASE_URL}/#organization` },
      image: event.imageUrl ?? DEFAULT_IMAGE,
    },
  };
}
