/* AMARINE — Portfolio detail template
   Reusable detail page driven by portfolio data and router slug. */

function isVideoValue(value) {
  if (!value) return false;
  const source = typeof value === 'string' ? value : value.src || value.url || value.href || '';
  // Cloudinary resource type is authoritative (handles extensionless URLs).
  if (/\/video\/upload\//i.test(source)) return true;
  if (/\/image\/upload\//i.test(source)) return false;
  return /\.(mp4|webm|mov|avi)$/i.test(source);
}

function buildPlaceholderMedia(label = 'Portfolio') {
  const safeLabel = String(label || 'Portfolio').replace(/&/g, 'and');
  const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1500" viewBox="0 0 1200 1500"><rect width="1200" height="1500" fill="#f3efe5"/><rect x="80" y="80" width="1040" height="1340" rx="24" fill="#fffdf8" stroke="#d8c6a0" stroke-width="2"/><rect x="150" y="220" width="900" height="220" rx="12" fill="#e6dcc8"/><rect x="150" y="500" width="680" height="24" rx="12" fill="#caa86d"/><rect x="150" y="548" width="760" height="24" rx="12" fill="#d8c6a0"/><rect x="150" y="596" width="620" height="24" rx="12" fill="#d8c6a0"/><text x="600" y="1080" text-anchor="middle" font-family="Georgia, serif" font-size="56" fill="#374151">${safeLabel}</text></svg>`;
  return { type: 'image', src: `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(svg)}`, poster: '' };
}

function normalizeMedia(value, fallbackLabel = 'Portfolio') {
  if (!value || (typeof value === 'string' && !value.trim())) {
    return buildPlaceholderMedia(fallbackLabel);
  }

  if (typeof value === 'string') {
    return {
      type: isVideoValue(value) ? 'video' : 'image',
      src: value,
      poster: '',
    };
  }

  if (typeof value === 'object') {
    const src = value.src || value.url || value.href || '';
    const poster = value.poster || value.thumbnail || value.image || '';
    return {
      type: value.type === 'video' || isVideoValue(src) ? 'video' : 'image',
      src: src || poster || '',
      poster: poster || '',
    };
  }

  return buildPlaceholderMedia(fallbackLabel);
}

function getMediaBackground(value) {
  const media = normalizeMedia(value);
  return media.poster || media.src || '';
}

function toCamelCaseDisplay(value) {
  if (!value) return 'Project';
  return String(value)
    .trim()
    .replace(/&/g, ' ')
    .replace(/[^a-zA-Z0-9]+/g, ' ')
    .split(/\s+/)
    .filter(Boolean)
    .map((part, idx) => {
      const normalized = part.replace(/[^a-zA-Z0-9]/g, '');
      if (!normalized) return '';
      const lower = normalized.toLowerCase();
      return idx === 0 ? lower.charAt(0).toUpperCase() + lower.slice(1) : lower.charAt(0).toUpperCase() + lower.slice(1);
    })
    .join('');
}

function resolveLocalizedText(localized, fallback, lang) {
  if (localized && typeof localized === 'object') {
    if (localized[lang]) return localized[lang];
    if (localized.es) return localized.es;
    if (localized.en) return localized.en;
  }
  return fallback || '';
}

function isSafariBrowser() {
  if (typeof navigator === 'undefined') return false;
  const ua = navigator.userAgent || '';
  return /Safari/i.test(ua) && !/Chrome|CriOS|Edg|OPR|Opera/i.test(ua);
}

function shouldReduceVideoLoading() {
  if (typeof window === 'undefined') return true;
  const isSmallDevice = window.matchMedia && window.matchMedia('(max-width: 768px)').matches;
  const reducedMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  return isSmallDevice || reducedMotion || isSafariBrowser();
}

function resolveLocalizedList(localized, fallback, lang) {
  if (localized && typeof localized === 'object') {
    const byLang = localized[lang];
    if (Array.isArray(byLang)) return byLang;
    if (Array.isArray(localized.es)) return localized.es;
    if (Array.isArray(localized.en)) return localized.en;
  }
  return Array.isArray(fallback) ? fallback : [];
}

function PortfolioDetailPage({ slug }) {
  const t = useT();
  const lang = useLang();
  const lp = useLocalizedPath();
  const data = window.AMARINE_PORTFOLIO_DATA;
  const project = data ? data.getBySlug(slug) : null;

  if (!project) {
    return (
      <>
        <Header active="portfolio" onDark={true} />
        <main>
          <section className="port-detail-not-found gut">
            <Reveal as="h1">{t('port.detail.notFound')}</Reveal>
            <Reveal delay={120}>
              <a className="link-arrow" href={lp('/portfolio')}>
                {t('port.detail.back')} <span>→</span>
              </a>
            </Reveal>
          </section>
        </main>
        <Footer />
      </>
    );
  }

  const localizedTitle = React.useMemo(() => resolveLocalizedText(project.titleI18n, project.title, lang), [project.titleI18n, project.title, lang]);
  const gallery = React.useMemo(() => (project.galleryImages || []).filter(Boolean), [project.galleryImages]);
  const related = React.useMemo(() => data.getRelated(project.slug, project.line, 3), [data, project.slug, project.line]);
  const heroMedia = React.useMemo(() => normalizeMedia(project.heroImage, localizedTitle || project.slug || 'Portfolio'), [project.heroImage, localizedTitle, project.slug]);
  const [shouldLoadHeroVideo, setShouldLoadHeroVideo] = React.useState(false);
  const [shouldLoadGalleryVideo, setShouldLoadGalleryVideo] = React.useState(false);
  const heroVideoRef = React.useRef(null);
  const galleryVideoRef = React.useRef(null);
  const galleryMedia = React.useMemo(
    () => gallery.map((item) => normalizeMedia(item, localizedTitle || project.slug || 'Portfolio')).filter((item) => item.src || item.poster),
    [gallery, localizedTitle, project.slug]
  );
  const displayTitle = React.useMemo(() => toCamelCaseDisplay(localizedTitle || project.slug), [localizedTitle, project.slug]);

  React.useEffect(() => {
    if (!heroVideoRef.current || heroMedia.type !== 'video') {
      setShouldLoadHeroVideo(false);
      return undefined;
    }

    if (!shouldReduceVideoLoading()) {
      setShouldLoadHeroVideo(true);
      return undefined;
    }

    const observer = new IntersectionObserver(
      ([entry]) => setShouldLoadHeroVideo(entry.isIntersecting),
      { rootMargin: '220px 0px' },
    );
    observer.observe(heroVideoRef.current);
    return () => observer.disconnect();
  }, [heroMedia.type, heroMedia.src]);

  React.useEffect(() => {
    if (!galleryVideoRef.current || !galleryMedia[0] || galleryMedia[0].type !== 'video') {
      setShouldLoadGalleryVideo(false);
      return undefined;
    }

    if (!shouldReduceVideoLoading()) {
      setShouldLoadGalleryVideo(true);
      return undefined;
    }

    const observer = new IntersectionObserver(
      ([entry]) => setShouldLoadGalleryVideo(entry.isIntersecting),
      { rootMargin: '220px 0px' },
    );
    observer.observe(galleryVideoRef.current);
    return () => observer.disconnect();
  }, [galleryMedia[0] && galleryMedia[0].src, galleryMedia[0] && galleryMedia[0].type]);
  const relatedCardMeta = React.useMemo(
    () => related.map((item) => ({
      href: lp(data.getProjectRoutePath(item.slug)),
      style: { backgroundImage: `url(${getMediaBackground(item.heroImage)})` },
    })),
    [related, data, lp]
  );
  const categoryLabel = React.useMemo(() => {
    const key = project.categoryI18nKey;
    if (key) {
      const translated = t(key);
      if (translated && translated !== key) return translated;
    }
    return project.category;
  }, [project.categoryI18nKey, project.category, t]);
  const subtitleLabel = React.useMemo(
    () => resolveLocalizedText(project.subtitleI18n, project.subtitle, lang),
    [project.subtitleI18n, project.subtitle, lang]
  );
  const overviewLabel = React.useMemo(
    () => resolveLocalizedText(project.overviewI18n, project.overview, lang),
    [project.overviewI18n, project.overview, lang]
  );
  const challengeLabel = React.useMemo(
    () => resolveLocalizedText(project.challengeI18n, project.challenge, lang),
    [project.challengeI18n, project.challenge, lang]
  );
  const solutionLabel = React.useMemo(
    () => resolveLocalizedText(project.solutionI18n, project.solution, lang),
    [project.solutionI18n, project.solution, lang]
  );
  const resultsLabel = React.useMemo(
    () => resolveLocalizedList(project.resultsI18n, project.results, lang),
    [project.resultsI18n, project.results, lang]
  );
  const ctaLabel = React.useMemo(
    () => resolveLocalizedText(project.ctaLabelI18n, project.cta && project.cta.label, lang),
    [project.ctaLabelI18n, project.cta, lang]
  );

  return (
    <>
      <Header active="portfolio" onDark={true} />
      <main className="portfolio-detail-page">
        <section className="port-detail-hero">
          <div className="media-frame">
            {heroMedia.type === 'video' ? (
              <video
                ref={heroVideoRef}
                className="media-video"
                src={shouldLoadHeroVideo ? heroMedia.src : undefined}
                poster={heroMedia.poster || undefined}
                autoPlay={shouldLoadHeroVideo}
                muted
                loop
                playsInline
                preload={shouldReduceVideoLoading() ? 'metadata' : 'auto'}
              />
            ) : (
              <div className="ph" style={{ backgroundImage: `url(${heroMedia.poster || heroMedia.src})` }} role="img" aria-label={`${localizedTitle} hero image`} />
            )}
          </div>
          <div className="overlay" />
          <div className="gut inner">
            <Reveal>
              <span className="eyebrow on-dark">{t('port.eyebrow')}</span>
            </Reveal>
            <Reveal as="h1" delay={120}>
              {displayTitle}
            </Reveal>
            <Reveal as="p" className="subtitle" delay={180}>
              {subtitleLabel}
            </Reveal>
            <Reveal className="facts" delay={220}>
              <div>
                <span>{t('port.detail.category')}</span>
                <strong>{categoryLabel}</strong>
              </div>
              <div>
                <span>{t('port.detail.location')}</span>
                <strong>{project.location}</strong>
              </div>
              <div>
                <span>{t('port.detail.year')}</span>
                <strong>{project.year}</strong>
              </div>
            </Reveal>
          </div>
        </section>

        <section className="port-detail-body gut">
          <Reveal className="detail-block">
            <h2>{t('port.detail.overview')}</h2>
            <p>{overviewLabel}</p>
          </Reveal>

          <Reveal className="detail-block" delay={80}>
            <h2>{t('port.detail.challenge')}</h2>
            <p>{challengeLabel}</p>
          </Reveal>

          <Reveal className="detail-block" delay={140}>
            <h2>{t('port.detail.solution')}</h2>
            <p>{solutionLabel}</p>
          </Reveal>

          <Reveal className="detail-block" delay={200}>
            <h2>{t('port.detail.results')}</h2>
            <ul>
              {resultsLabel.map((item, idx) => (
                <li key={idx}>{item}</li>
              ))}
            </ul>
          </Reveal>
        </section>

        <section className="port-detail-gallery gut">
          <Reveal>
            <h2>{t('port.detail.gallery')}</h2>
          </Reveal>
          <div className="gallery-carousel" role="list" aria-label={`${localizedTitle} gallery`}>
            <Reveal className="gallery-stage" delay={80} role="listitem">
              {galleryMedia[0] && galleryMedia[0].type === 'video' ? (
                <video
                  ref={galleryVideoRef}
                  className="media-video"
                  src={shouldLoadGalleryVideo ? galleryMedia[0].src : undefined}
                  poster={galleryMedia[0].poster || undefined}
                  autoPlay={shouldLoadGalleryVideo}
                  muted
                  playsInline
                  preload={shouldReduceVideoLoading() ? 'metadata' : 'auto'}
                />
              ) : (
                <div
                  className="ph"
                  style={{ backgroundImage: `url(${(galleryMedia[0] || {}).poster || (galleryMedia[0] || {}).src})` }}
                  role="img"
                  aria-label={`${localizedTitle} gallery image 1`}
                />
              )}
            </Reveal>
          </div>
        </section>

        <section className="port-related surface-ivory-warm">
          <div className="s-head">
            <div className="label">
              <span className="numeral">— V</span>
              <span className="eyebrow">{t('port.detail.related')}</span>
            </div>
            <div>
              <h2>{localizedTitle} <span className="it">/</span> {t('port.detail.related')}</h2>
            </div>
          </div>
          <div className="gut">
            <div className="port-grid port-grid-related">
              {related.map((item, idx) => {
                const relatedTitle = resolveLocalizedText(item.titleI18n, item.title, lang);
                return (
                <Reveal
                  key={item.slug}
                  as="a"
                  href={relatedCardMeta[idx].href}
                  className="port-card"
                  delay={(idx % 3) * 100}
                  aria-label={`${t('port.brand.open')} ${relatedTitle}`}
                >
                  <div className="ph" data-label={item.label} style={relatedCardMeta[idx].style} aria-hidden="true" />
                  <div className="meta">
                    <span>{item.line === 'events' ? t('port.line.events') : t('port.filter.line.hospitality')} · {item.city}</span>
                    <span className="yr">{item.year}</span>
                  </div>
                  <h3>{relatedTitle}</h3>
                  <span className="industry">{resolveLocalizedText(item.subtitleI18n, item.subtitle, lang)}</span>
                </Reveal>
                );
              })}
            </div>
          </div>
        </section>

        <section className="closing-cta">
          <Reveal>
            <span className="eyebrow on-dark">{t('home.cta.eyebrow')}</span>
            <h2>{localizedTitle} <br /><span className="it">{subtitleLabel}</span></h2>
            <p>{ctaLabel || t('home.cta.desc')}</p>
            <a className="btn btn-secondary" href={lp(project.cta && project.cta.href ? project.cta.href : '/contact')}>
              {t('home.cta.btn')} <span className="arrow">→</span>
            </a>
          </Reveal>
        </section>
      </main>
      <Footer />
    </>
  );
}

window.AMARINE_PORTFOLIO_PAGES = window.AMARINE_PORTFOLIO_PAGES || {};
window.AMARINE_PORTFOLIO_PAGES.Detail = PortfolioDetailPage;
