// Shared UI primitives - language toggle, marquee, nav, etc.

const { useState, useEffect, useRef } = React;

// ─── i18n dictionary ────────────────────────────────────────────────────────
const I18N = {
  ja: {
    nav: ['サービス', 'ミッション', '会社案内', '採用', 'お知らせ', 'お問い合わせ'],
    brand: '株式会社MARIP',
    tagline: 'Make Ripples — System Engineering, Web & Software',
    heroEyebrow: '— Make Ripples —',
    heroLine1: '一滴から、',
    heroLine2: '未来へ波紋が',
    heroLine3: '広がっていく。',
    heroSub: '株式会社MARIPは、ひとつのプロジェクトから社会・人々・未来へと広がる影響を生み出します。',
    ctaPrimary: 'プロジェクトの相談をする',
    ctaSecondary: 'サービスを見る',
    scrollHint: 'Scroll to explore',
    challengeEyebrow: '01 — Challenges',
    challengeTitle: 'こんな課題を、私たちが解決します。',
    challenges: [
      { n: '01', t: 'IT人材の不足', d: 'プロジェクトを進めたいのに技術者が確保できず、開発スケジュールやリリースが遅れてしまっている。社内だけでは必要なスキルセットが揃わず、進行が滞っているとお困りの方へ。' },
      { n: '02', t: 'スポットでの即戦力', d: '繁忙期や急なアサイン変更で、１ヶ月単位ですぐに動ける技術者が必要。短期間でも、現場に入ってすぐに力を発揮できる即戦力人材をお探しの方へ。' },
      { n: '03', t: '待機中の技術者', d: '次の稼働先がまだ決まっていない自社技術者を、早めに新しいプロジェクトへつなげたい。スキルや希望に合う案件を、スピーディーにマッチングしたい方へ。' },
    ],
    challengeCta: 'MARIPにおまかせください',
    serviceEyebrow: '02 — Services',
    serviceTitle: '4つのサービスで、事業を前に進める。',
    services: [
      { n: 'S.01', t: 'System Engineering\nService', jp: 'システムエンジニアリングサービス', d: 'クライアント様と共にプロジェクトを成功に導く、技術者派遣・常駐支援サービス。', href: 'services/ses/' },
      { n: 'S.02', t: 'Contract\nDevelopment', jp: '受託開発', d: '要件定義から設計・開発・運用まで、ワンストップでお任せいただけます。Webシステム・業務システムから、AI/LLM活用開発まで対応。', href: 'services/development/' },
      { n: 'S.03', t: 'Web Development', jp: 'ホームページ制作', d: 'ブランドを正しく伝え、事業の成長に直結するWebサイトを設計・構築します。', href: 'services/web/' },
      { n: 'S.04', t: 'Ensuma', jp: 'フリーランスエンジニアエージェント', d: '「エンジニアとのご縁をスマートに繋ぐ」フリーランスエンジニア向けエージェントサービス。専任アドバイザーがスキルとご希望に合わせた高単価案件をスピーディーにご紹介します。', href: 'https://ensuma.jp/', external: true },
    ],
    whyEyebrow: '03 — Why MARIP',
    whyTitle: '打ち合わせから、納品まで、一貫して。',
    whys: [
      { t: '納得いくまで\n提案します', d: '打ち合わせの段階から細かいニーズや背景まで丁寧にヒアリングし、ご納得いただけるまで妥協のない提案を行います。' },
      { t: '丁寧に、\nそして早く', d: '急を要する案件や営業中の技術者様にも、状況を素早く把握し、丁寧さを保ったままスピーディーにご提案します。' },
      { t: '地域に根ざして、\n顔の見える関係を', d: 'オンラインだけでなく、直接お会いしての打ち合わせにも柔軟にお応えし、長くお付き合いできる関係を築きます。' },
    ],
    mvvEyebrow: '04 — Mission / Vision / Value',
    mission: { label: 'Mission', t: '未来に広がる影響を\nあたえ続ける。', d: '一滴の水滴でも水面に落ちれば波紋が生まれ、広がっていき、他に影響をあたえていきます。MARIPはさまざまな波紋を生み出し、さまざまな形で社会、人々の生活、人生に影響を与えていきます。' },
    vision: { label: 'Vision', t: '誰もが挑戦し、\n影響をあたえ続ける\n企業となる。', d: '' },
    valuesLabel: 'Value',
    values: [
      { n: '01', en: 'Accurately and politely', jp: '正確に丁寧に', d: '仕事や生活、小さな事でも正確に丁寧に行い、お客様やメンバーとの信頼関係を築き、満足度向上に繋げる。' },
      { n: '02', en: 'Intellectual failure', jp: '知的な失敗', d: '失敗によって人は大きく成長するが、単なる失敗は何も意味がない。考え抜いた上で挑戦した時の失敗、知的な失敗をし成長に繋げる。' },
      { n: '03', en: 'Effort, effort. Play, effort', jp: '努力、努力、違び、努力', d: '常に人一倍努力することは大切なこと、ただたまには違びも。' },
      { n: '04', en: 'Cherish your friends', jp: '仲間を大切に', d: '自分が何かをできるのは、仲間の力があるからということを忘れず、常に仲間は大切に。' },
    ],
    newsEyebrow: '05 — Information',
    newsTitle: 'お知らせ',
    news: [
      { d: '2026.03.30', c: 'Company', t: 'コーポレートサイトをリニューアルしました。', href: 'news/20260330-website-renewal.html' },
      { d: '2025.03.18', c: 'Service', t: 'フリーランスエンジニアエージェント「エンスマ」をリリースしました。', href: 'news/20250318-ensuma-launch.html' },
    ],
    newsMore: 'すべてのお知らせを見る',
    ctaEyebrow: '— Let\'s make ripples —',
    ctaTitle: '最初の一滴を、一緒に落としませんか。',
    ctaSub: 'プロジェクトのご相談、採用に関するお問い合わせ、お気軽にご連絡ください。',
    ctaButton: 'お問い合わせ',
    footerLinks: ['サービス', '会社案内', '採用情報', 'お知らせ', 'お問い合わせ', 'プライバシーポリシー'],
    footerLinkHrefs: ['services/', 'company/', 'careers/', 'news/', 'contact/', 'privacy/'],
    addrLines: ['〒150-0002', '東京都渋谷区渋谷2-19-15', '宮益坂ビルディング609'],
    companyInfoLabel: 'Company Information',
    companyInfoMore: '会社概要を見る',
    companyInfo: [
      { k: '会社名', v: '株式会社MARIP' },
      { k: '代表者', v: '代表取締役 松瀬 仁志' },
      { k: '設立', v: '2023年9月12日' },
      { k: '資本金', v: '100万円' },
      { k: '事業内容', v: 'SES / 受託開発 / Web制作 / エージェント事業' },
      { k: '所在地', v: '東京都渋谷区渋谷2-19-15 宮益坂ビルディング609' },
    ],
  },
  en: {
    nav: ['Services', 'Mission', 'Company', 'Careers', 'News', 'Contact'],
    brand: 'MARIP Inc.',
    tagline: 'Make Ripples — System Engineering, Web & Software',
    heroEyebrow: '— Make Ripples —',
    heroLine1: 'One drop,',
    heroLine2: 'endless ripples',
    heroLine3: 'into the future.',
    heroSub: 'MARIP generates waves that reach across society, people, and lives — one project at a time.',
    ctaPrimary: 'Start a project',
    ctaSecondary: 'Our services',
    scrollHint: 'Scroll to explore',
    challengeEyebrow: '01 — Challenges',
    challengeTitle: 'We solve the problems that stall you.',
    challenges: [
      { n: '01', t: 'Talent shortage', d: 'Your project is short on engineers and losing momentum.' },
      { n: '02', t: 'Spot resourcing', d: 'You need skilled hands, available by the month.' },
      { n: '03', t: 'Bench time', d: 'You have engineers looking for their next assignment.' },
    ],
    challengeCta: 'Leave it to MARIP',
    serviceEyebrow: '02 — Services',
    serviceTitle: 'Four services that move business forward.',
    services: [
      { n: 'S.01', t: 'System Engineering\nService', jp: 'SES', d: 'On-site and embedded engineering support that steers projects to successful delivery.', href: 'services/ses/' },
      { n: 'S.02', t: 'Contract Development', jp: 'Software', d: 'End-to-end delivery from requirements through design, build, and operations — web and business systems plus AI/LLM-powered builds.', href: 'services/development/' },
      { n: 'S.03', t: 'Web Development', jp: 'Web', d: 'Websites designed to communicate your brand and drive measurable business growth.', href: 'services/web/' },
      { n: 'S.04', t: 'Ensuma', jp: 'Freelance Agent', d: 'A freelance engineer agency that connects engineers and projects — smartly. Dedicated advisors match high-rate roles to your skills and goals at speed.', href: 'https://ensuma.jp/', external: true },
    ],
    whyEyebrow: '03 — Why MARIP',
    whyTitle: 'From kickoff to handoff, end-to-end.',
    whys: [
      { t: 'Proposals until\nyou are satisfied', d: 'From the first meeting we listen carefully — to your specific needs and the context behind them — and propose without compromise until you\'re fully satisfied.' },
      { t: 'Thoughtful and\nfast', d: 'For urgent projects or engineers between assignments, we grasp the situation quickly and respond with both speed and care.' },
      { t: 'Local, with\nfaces you know', d: 'Beyond online meetings, we welcome in-person conversations too — and aim to build relationships that last.' },
    ],
    mvvEyebrow: '04 — Mission / Vision / Value',
    mission: { label: 'Mission', t: 'Keep sending ripples\ninto the future.', d: 'A single drop on still water creates ripples that spread and shape what surrounds them. MARIP creates ripples of every kind — reaching society, the way people live, and the lives they lead.' },
    vision: { label: 'Vision', t: 'A company where\neveryone takes on\nchallenges that ripple.', d: '' },
    valuesLabel: 'Value',
    values: [
      { n: '01', en: 'Accurately and politely', jp: 'Be exact, be kind', d: 'In work and in life, treat the small things accurately and politely — trust and satisfaction follow.' },
      { n: '02', en: 'Intellectual failure', jp: 'Fail with intent', d: 'Mindless failure teaches nothing. The kind that comes after deep thought — intellectual failure — is what grows you.' },
      { n: '03', en: 'Effort, effort. Play, effort', jp: 'Work hard, play, work harder', d: 'Outwork everyone else — and now and then, make space to play.' },
      { n: '04', en: 'Cherish your friends', jp: 'Hold your team close', d: 'Whatever you accomplish, you accomplish because of the people around you. Never forget them.' },
    ],
    newsEyebrow: '05 — Information',
    newsTitle: 'News',
    news: [
      { d: '2026.03.30', c: 'Company', t: 'Renewed our corporate website.', href: 'news/20260330-website-renewal.html' },
      { d: '2025.03.18', c: 'Service', t: 'Launched our freelance engineer agency, Ensuma.', href: 'news/20250318-ensuma-launch.html' },
    ],
    newsMore: 'See all news',
    ctaEyebrow: '— Let\'s make ripples —',
    ctaTitle: 'Let\'s drop the first one, together.',
    ctaSub: 'Questions about a project, recruiting, or a partnership — we\'d love to hear from you.',
    ctaButton: 'Get in touch',
    footerLinks: ['Services', 'Company', 'Careers', 'News', 'Contact', 'Privacy'],
    footerLinkHrefs: ['services/', 'company/', 'careers/', 'news/', 'contact/', 'privacy/'],
    addrLines: ['Miyamasuzaka Bldg 609', '2-19-15 Shibuya, Shibuya-ku', 'Tokyo 150-0002, Japan'],
    companyInfoLabel: 'Company Information',
    companyInfoMore: 'View company profile',
    companyInfo: [
      { k: 'Company', v: 'MARIP Inc.' },
      { k: 'Representative', v: 'Hitoshi Matsuse, CEO' },
      { k: 'Founded', v: 'September 12, 2023' },
      { k: 'Capital', v: 'JPY 1,000,000' },
      { k: 'Business', v: 'SES / Contract Dev / Web / Engineer Agency' },
      { k: 'Address', v: 'Miyamasuzaka Bldg 609, 2-19-15 Shibuya, Shibuya-ku, Tokyo 150-0002, Japan' },
    ],
  },
};

// ─── Magnetic button ────────────────────────────────────────────────────────
const MagneticButton = ({ children, variant = 'primary', onClick, accent, href, target, rel }) => {
  const ref = useRef(null);
  const [offset, setOffset] = useState({ x: 0, y: 0 });

  const onMove = (e) => {
    const r = ref.current.getBoundingClientRect();
    const x = (e.clientX - r.left - r.width / 2) * 0.25;
    const y = (e.clientY - r.top - r.height / 2) * 0.25;
    setOffset({ x, y });
  };
  const onLeave = () => setOffset({ x: 0, y: 0 });

  const styles = {
    primary: {
      background: accent,
      color: '#0C1814',
      border: `1px solid ${accent}`,
    },
    ghost: {
      background: 'transparent',
      color: '#fff',
      border: '1px solid rgba(255,255,255,0.25)',
    },
  };

  const Tag = href ? 'a' : 'button';
  const linkProps = href ? { href, target, rel } : {};

  return (
    <Tag
      ref={ref}
      onMouseMove={onMove}
      onMouseLeave={onLeave}
      onClick={onClick}
      {...linkProps}
      className="mag-btn"
      style={{
        ...styles[variant],
        transform: `translate(${offset.x}px, ${offset.y}px)`,
      }}
    >
      <span style={{ transform: `translate(${offset.x * 0.5}px, ${offset.y * 0.5}px)`, display: 'inline-flex', alignItems: 'center', gap: 10 }}>
        {children}
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
          <path d="M2 7h10M8 3l4 4-4 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </span>
    </Tag>
  );
};

// ─── Marquee (horizontal scrolling text) ────────────────────────────────────
const Marquee = ({ items, speed = 40, accent }) => {
  return (
    <div className="marquee">
      <div className="marquee-track" style={{ animationDuration: `${speed}s` }}>
        {[...items, ...items, ...items].map((item, i) => (
          <span key={i} className="marquee-item">
            <span>{item}</span>
            <svg width="18" height="18" viewBox="0 0 18 18" style={{ margin: '0 32px', opacity: 0.4 }}>
              <circle cx="9" cy="9" r="2" fill={accent} />
              <circle cx="9" cy="9" r="5" fill="none" stroke={accent} strokeWidth="0.5" opacity="0.6" />
              <circle cx="9" cy="9" r="8" fill="none" stroke={accent} strokeWidth="0.5" opacity="0.3" />
            </svg>
          </span>
        ))}
      </div>
    </div>
  );
};

// イントロオーバーレイ（marip-intro--lock）が外れるまで実行を待つヘルパ。
// オーバーレイ表示中に IntersectionObserver が幾何的に「見えている」と判定し、
// アニメがオーバーレイの裏で消化されてしまうのを防ぐ。
const _afterIntro = (fn) => {
  if (!document.documentElement.classList.contains('marip-intro--lock')) {
    fn();
    return () => {};
  }
  const mo = new MutationObserver(() => {
    if (!document.documentElement.classList.contains('marip-intro--lock')) {
      mo.disconnect();
      fn();
    }
  });
  mo.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
  return () => mo.disconnect();
};

// ─── Reveal-on-scroll wrapper ───────────────────────────────────────────────
const Reveal = ({ children, delay = 0, y = 40, className = '' }) => {
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let obs;
    const stopWait = _afterIntro(() => {
      obs = new IntersectionObserver(
        ([e]) => { if (e.isIntersecting) { setVisible(true); obs.disconnect(); } },
        { threshold: 0.15 }
      );
      obs.observe(el);
    });
    return () => { stopWait(); if (obs) obs.disconnect(); };
  }, []);
  return (
    <div
      ref={ref}
      className={className}
      style={{
        transform: visible ? 'translateY(0)' : `translateY(${y}px)`,
        opacity: visible ? 1 : 0,
        transition: `transform 1.1s cubic-bezier(.22,1,.36,1) ${delay}s, opacity 1.1s ease ${delay}s`,
      }}
    >
      {children}
    </div>
  );
};

// ─── Split text that reveals per-character/word on scroll ──────────────────
const SplitReveal = ({ text, className = '', delay = 0, stagger = 0.025, by = 'char' }) => {
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let obs;
    const stopWait = _afterIntro(() => {
      obs = new IntersectionObserver(
        ([e]) => { if (e.isIntersecting) { setVisible(true); obs.disconnect(); } },
        { threshold: 0.2 }
      );
      obs.observe(el);
    });
    return () => { stopWait(); if (obs) obs.disconnect(); };
  }, []);

  const units = by === 'word' ? text.split(' ') : [...text];
  return (
    <span ref={ref} className={className} style={{ display: 'inline-block' }}>
      {units.map((u, i) => (
        <span key={i} style={{ display: 'inline-block', overflow: 'hidden', verticalAlign: 'bottom' }}>
          <span
            style={{
              display: 'inline-block',
              transform: visible ? 'translateY(0)' : 'translateY(110%)',
              transition: `transform 1s cubic-bezier(.22,1,.36,1) ${delay + i * stagger}s`,
              whiteSpace: 'pre',
            }}
          >
            {u === ' ' ? '\u00A0' : u}{by === 'word' ? '\u00A0' : ''}
          </span>
        </span>
      ))}
    </span>
  );
};

Object.assign(window, { I18N, MagneticButton, Marquee, Reveal, SplitReveal });
