// Main app — composes routing, pages, and the Tweaks panel.

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#2452ff",
  "accentInk": "#ffffff",
  "dark": false
}/*EDITMODE-END*/;

// ── UI string translations ──────────────────────────────────
const UI = {
  en: {
    nav: { projects: "Projects", about: "About", process: "Process", cv: "CV & Feedback", contacts: "Contacts" },
    heroLede: "focused on digital campaigns and product launches at the intersection of creative and technology.",
    nowLabel: "Now",
    awardsLabel: "Awards & mentions",
    selectedProjects: "Index — Selected projects",
    viewAll: (n) => `View all ${n} projects`,
    backHome: "Back home",
    allProjects: "All projects",
    archive: "Archive",
    updatedDate: "Updated May 2026",
    aboutLabel: (name) => `About — ${name}`,
    toolkitLabel: "Toolkit — what I work with daily",
    generalLabel: "General",
    experienceLabel: "Experience",
    moreLabel: "More",
    downloadPDF: "Download PDF",
    cvPdfUrl: "/assets/resume-en.pdf",
    cvFeedback: "CV & Feedback",
    careerLabel: "Career",
    feedbackLabel: "Feedback",
    feedbackDesc: (n) => `What colleagues and clients say — ${n}+ people I've shipped projects with.`,
    contactsLabel: "Contacts",
    getInTouch: "Get in touch",
    contactsBody1: "Open to <b>Lead / Senior Project Manager</b>, production director, and head of delivery roles. Hybrid or fully remote — no restrictions, relocation considered.",
    contactsBody2: "Fastest way to reach me: email or Telegram. I aim to reply within the business day.",
    locationLabel: "Location",
    locationBody: "<b>Tbilisi, Georgia</b> · GMT+4. Worked simultaneously with teams in Moscow, London, and Tbilisi — time zones aren't a problem.",
    languages: "Languages: Russian (native), English (B2).",
    processLabel: "Process — how I run projects",
    processTitle1: "How I run",
    processTitle2: "projects & teams",
    principlesLabel: "Principles",
    principlesDesc: "Rules I use when priorities, deadlines, or stakeholders collide.",
    dailyToolkit: "Daily toolkit",
    dailyToolkitDesc: "Full stack on the About page.",
    allProjectsLink: "All projects",
    caseStudy: "Case study",
    yearLabel: "Year",
    roleLabel: "Role",
    clientLabel: "Client",
    agencyLabel: "Agency",
    countryLabel: "Country",
    durationLabel: "Duration",
    videoLabel: "Video",
    clickToPlay: "Click to play inline",
    watchLabel: "Watch",
    peopleLabel: "People",
    fromThisTeam: "from this team",
    whatTheySaid: "What they said",
    seeAllFeedback: "See all feedback →",
    prevCase: "← Prev case",
    nextCase: "Next case →",
    notFoundTitle: "Case not found",
    notFoundBody: (id) => `Case ${id} not found in the archive. The link may be outdated or contain a typo. Here's what you can do:`,
    notFoundViewAll: (n) => `View all ${n} projects`,
    notFoundTell: "Tell me about this",
    notFoundBack: "Back home",
    openToRoles: "Open to senior roles",
    fullCareerHistory: "Full career history →",
    cvLink: "open CV & Feedback",
  },
  ru: {
    nav: { projects: "Проекты", about: "Обо мне", process: "Процесс", cv: "CV и отзывы", contacts: "Контакты" },
    heroLede: ", специализируюсь на цифровых кампаниях и запусках продуктов на стыке креатива и технологий.",
    nowLabel: "Сейчас",
    awardsLabel: "Награды и упоминания",
    selectedProjects: "Избранные проекты",
    viewAll: (n) => `Все ${n} проектов`,
    backHome: "На главную",
    allProjects: "Все проекты",
    archive: "Архив",
    updatedDate: "Обновлено май 2026",
    aboutLabel: (name) => `О себе — ${name}`,
    toolkitLabel: "Инструменты — с чем работаю каждый день",
    generalLabel: "Общее",
    experienceLabel: "Опыт",
    moreLabel: "Ещё",
    downloadPDF: "Скачать PDF",
    cvPdfUrl: "/assets/resume-ru.pdf",
    cvFeedback: "CV и отзывы",
    careerLabel: "Карьера",
    feedbackLabel: "Отзывы",
    feedbackDesc: (n) => `Что говорят коллеги и клиенты — ${n}+ человек, с которыми я запускал проекты.`,
    contactsLabel: "Контакты",
    getInTouch: "Связаться",
    contactsBody1: "Открыт к позициям <b>Старший проджект-менеджер</b>, продюсер, руководитель направления. Гибрид или удалёнка — без ограничений, готов к релокации.",
    contactsBody2: "Быстрее всего через email или Telegram. Стараюсь отвечать в течение рабочего дня.",
    locationLabel: "Местоположение",
    locationBody: "<b>Тбилиси, Грузия</b> · GMT+4. Работал одновременно с командами в Москве, Лондоне и Тбилиси — часовые пояса не проблема.",
    languages: "Языки: русский (родной), английский (B2).",
    processLabel: "Процесс — как я веду проекты",
    processTitle1: "Как я лидирую",
    processTitle2: "проекты и команды",
    principlesLabel: "Принципы",
    principlesDesc: "Правила, которые я использую когда сталкиваются приоритеты, дедлайны и интересы стейкхолдеров.",
    dailyToolkit: "Ежедневный инструментарий",
    dailyToolkitDesc: "Полный список на странице Обо мне.",
    allProjectsLink: "Все проекты",
    caseStudy: "Кейс",
    yearLabel: "Год",
    roleLabel: "Роль",
    clientLabel: "Клиент",
    agencyLabel: "Агентство",
    countryLabel: "Страна",
    durationLabel: "Длительность",
    videoLabel: "Видео",
    clickToPlay: "Нажмите для просмотра",
    watchLabel: "Смотреть",
    peopleLabel: "Люди",
    fromThisTeam: "из этой команды",
    whatTheySaid: "Что говорят",
    seeAllFeedback: "Все отзывы →",
    prevCase: "← Предыдущий",
    nextCase: "Следующий →",
    notFoundTitle: "Кейс не найден",
    notFoundBody: (id) => `Кейс ${id} не найден в архиве. Ссылка могла устареть или содержать опечатку. Вот что можно сделать:`,
    notFoundViewAll: (n) => `Все ${n} проектов`,
    notFoundTell: "Сообщить об ошибке",
    notFoundBack: "На главную",
    openToRoles: "Открыт к новым позициям",
    fullCareerHistory: "Полная история карьеры →",
    cvLink: "открыть CV и отзывы",
  },
};

function App() {
  const route = useRoute();
  const [lang, setLang] = React.useState(() => localStorage.getItem("lang") || "en");
  const data = window.PORTFOLIO_DATA[lang];
  const ui = UI[lang];
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  const switchLang = React.useCallback((l) => {
    localStorage.setItem("lang", l);
    setLang(l);
  }, []);

  // Scroll to top on every route change
  useEffect(() => {
    window.scrollTo({ top: 0, behavior: "instant" });
  }, [route.name, route.id]);

  // Reveal animations — observe all .reveal elements after route renders
  useEffect(() => {
    const timer = setTimeout(() => {
      const els = document.querySelectorAll(".reveal:not(.is-visible)");
      const obs = new IntersectionObserver(
        (entries) => {
          entries.forEach((e) => {
            if (e.isIntersecting) {
              e.target.classList.add("is-visible");
              obs.unobserve(e.target);
            }
          });
        },
        { threshold: 0.08 }
      );
      els.forEach((el) => obs.observe(el));
      return () => obs.disconnect();
    }, 50);
    return () => clearTimeout(timer);
  }, [route.name, route.id, lang]);

  // Apply accent to CSS vars whenever it changes
  useEffect(() => {
    const root = document.documentElement;
    root.style.setProperty("--accent", t.accent);
    root.style.setProperty("--accent-ink", t.accentInk);
    if (t.dark) root.setAttribute("data-theme", "dark");
    else root.removeAttribute("data-theme");
  }, [t.accent, t.accentInk, t.dark]);

  // ⌘K cycles sections
  useEffect(() => {
    const tabs = ["projects", "about", "process", "cv", "contacts"];
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        const cur = route.name === "case" ? "projects" : route.name;
        const idx = tabs.indexOf(cur);
        const next = tabs[(idx + 1) % tabs.length];
        navigate(`#/${next}`);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [route.name]);

  const pageProps = { data, ui, lang };

  let page;
  switch (route.name) {
    case "about":   page = <PageAbout {...pageProps} />; break;
    case "cv":      page = <PageCV {...pageProps} />; break;
    case "contacts":page = <PageContacts {...pageProps} />; break;
    case "all":     page = <PageAllProjects {...pageProps} />; break;
    case "process": page = <PageProcess {...pageProps} />; break;
    case "case":    page = <PageCase {...pageProps} caseId={route.id} />; break;
    case "projects":
    default:        page = <PageProjects {...pageProps} />;
  }

  return (
    <div className="shell">
      <Topbar route={route} person={data.person} lang={lang} switchLang={switchLang} ui={ui} />
      <main className="frame">
        {page}
      </main>
      <Footer />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Accent" />
        <TweakColor
          label="Accent color"
          value={t.accent}
          options={["#2452ff", "#111111", "#d97757", "#1f8a5b", "#7a5ae0"]}
          onChange={(v) => setTweak("accent", v)}
        />
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
