/* =====================================================================
   VARA5 Careers — Single Department page
   ---------------------------------------------------------------------
   One template, three entry points:
       department.html?dept=operations
       department.html?dept=tech
       department.html?dept=founders

   Top of page  : a split hero — a looping GIF avatar on the LEFT, the
                  department title + blurb on the RIGHT.
                  Per-department GIFs live in DEPARTMENTS[].gif (see ASSETS).
   Below banner : the open jobs for THIS department, sourced live from the
                  Keka embed, each with an Apply button that opens the Keka
                  application form for that specific role.

   Notes
   • Every location is forced to "Delhi" for now (see FORCE_LOCATION).
   • Until the Keka embed loads, the seed list keeps the page populated.
   • Job parsing is anchor-based (no Keka class names). If a job ever fails to
     appear, open the page with ?debug=1 and read the console.
   ===================================================================== */

const KEKA = {
  identifier: '1060cc43-53d5-48b5-b68d-00a6425a619f',
  base: 'https://vara5journeyspvtltd.keka.com/careers/',
  staging: '#khembedjobs',
  enabled: true,
};

/* Every job shows this location for now. Set to null to use the real value. */
const FORCE_LOCATION = 'Delhi';

/* Folder (relative to this page) that holds the department hero GIFs.
   Put TWO files per department in project/assets/ :
     wide (laptop+):   operations.gif          tech.gif          founders.gif
     tall (mobile):    operations-portrait.gif tech-portrait.gif founders-portrait.gif
   The tall ones are used below 860px so the avatar isn't cropped on phones.
   GIFs loop on their own — no extra code needed. */
const ASSETS = 'assets/';

const DEPARTMENTS = {
  operations: {
    id: 'operations',
    label: 'Travel Operations',
    eyebrow: '§ Operations',
    blurb: 'The people who make every journey run - flawlessly, invisibly, on time. Travel design, member care and partnerships.',
    gif: ASSETS + 'operations.gif',
    gifPortrait: ASSETS + 'operations-portrait.gif',
  },
  tech: {
    id: 'tech',
    label: 'Technology',
    eyebrow: '§ Technology',
    blurb: 'Engineers, designers and product minds building the platform behind every VARA5 journey.',
    gif: ASSETS + 'tech.gif',
    gifPortrait: ASSETS + 'tech-portrait.gif',
  },
  founders: {
    id: 'founders',
    label: "Founder's Office",
    eyebrow: "§ Founder's Office",
    blurb: 'High-leverage generalists working directly with the founders on the highest-impact problems.',
    gif: ASSETS + 'founders.gif',
    gifPortrait: ASSETS + 'founders-portrait.gif',
  },
};

/* Map a Keka department/team name -> one of our 3 buckets (case-insensitive,
   substring). Extend as you add Keka departments. */
const DEPT_MAP = {
  'operations': 'operations', 'ops': 'operations', 'travel': 'operations',
  'travel design': 'operations', 'member care': 'operations', 'concierge': 'operations',
  'partnerships': 'operations', 'in-market': 'operations', 'curation': 'operations',
  'tech': 'tech', 'technology': 'tech', 'engineering': 'tech', 'software': 'tech',
  'product': 'tech', 'design': 'tech', 'data': 'tech',
  'i.t.': 'tech', 'i.t': 'tech', 'information technology': 'tech', 'it support': 'tech',
  "founder": 'founders', "founders": 'founders', "founder's office": 'founders',
  'leadership': 'founders', 'strategy': 'founders', 'chief of staff': 'founders',
};
const UNMAPPED_BUCKET = 'operations';

/* Force specific job titles into a chosen team, no matter what Keka filed
   them under or what the auto-mapper guesses.
   Keys = job title in lowercase; values = 'operations' | 'tech' | 'founders'. */
const TITLE_OVERRIDES = {
  'summer intern': 'founders',
};

/* Seed roles — replaced by live Keka jobs once they load. */
const SEED_JOBS = [
  { id: 'seed-travel-designer', title: 'Travel Designer', dept: 'operations',
    loc: 'Delhi', type: 'Full-time', applyUrl: KEKA.base, seed: true },
];

/* Map a Keka department/category label to one of our 3 buckets. */
function mapDept(raw) {
  const s = (raw || '').toLowerCase();
  // Keka files the Technology roles under an "I.T." category (dotted form):
  if (/\bi\.t\.?\b/.test(s) || s.includes('information technology')) return 'tech';
  for (const key of Object.keys(DEPT_MAP)) if (s.includes(key)) return DEPT_MAP[key];
  return null;
}

/* Is this <a> a real job link (not the Keka logo / social / footer / bare base)? */
function isJobLink(a) {
  const href = (a.getAttribute('href') || '').toLowerCase();
  const label = (a.textContent || '').trim().toLowerCase();
  if (!href || href.startsWith('#') || href.startsWith('mailto:')) return false;
  if (href.includes('keka.com') && !href.includes('/careers/')) return false;   // marketing/logo
  if (/facebook|twitter|linkedin|instagram|youtube|powered/.test(href + ' ' + label)) return false;
  return href.includes('/careers/') && !/\/careers\/?(\?|#|$)/.test(href);       // points to a specific job
}

/* Read whatever Keka rendered into the hidden staging node and normalise it.
   This is ANCHOR-driven (every job card links to its job page), so it does NOT
   depend on Keka's CSS class names — which is what kept breaking before. */
function harvestKekaJobs() {
  const root = document.querySelector(KEKA.staging);
  if (!root) return [];

  const anchors = Array.from(root.querySelectorAll('a[href]')).filter(isJobLink);
  const seen = new Set();
  const jobs = [];
  const unmapped = new Set();

  anchors.forEach((a, i) => {
    let applyUrl = a.getAttribute('href');
    try { applyUrl = new URL(applyUrl, KEKA.base).href; } catch (e) {}
    if (seen.has(applyUrl)) return;
    seen.add(applyUrl);

    // ---- TITLE: read it from INSIDE the job link only. ----
    // (Climbing to an ancestor was grabbing Keka's group header — that's why
    //  every row read "Operations2 jobs" instead of the real job name.)
    const titleEl =
      a.querySelector('[class*="title"],[class*="position"],[class*="designation"],[class*="job-name"],[class*="jobname"],[class*="role"],[class*="name"],h1,h2,h3,h4,h5,h6')
      || a.firstElementChild;
    let title = ((titleEl && titleEl.textContent) || a.textContent || '').replace(/\s+/g, ' ').trim();
    // If that still carried the location/type tail, trim it off.
    title = title
      .replace(/\b(full[\s-]?time|part[\s-]?time|internship|contract|temporary|permanent)\b.*$/i, '')
      .replace(/\b(new delhi|delhi|mumbai|bengaluru|bangalore|gurgaon|gurugram|noida|remote|hybrid|on[\s-]?site|london|paris)\b/ig, '')
      .replace(/[•·|,]+/g, ' ')
      .replace(/\bjobs?\b\s*$/i, '')
      .replace(/\s+/g, ' ')
      .trim();
    if (!title || title.length < 2 ||
        /^(apply|apply now|view|view job|view role|read more|learn more|details)$/i.test(title)) {
      title = (a.textContent || '').replace(/\s+/g, ' ').trim();
    }
    if (!title) return;

    // ---- DEPARTMENT: detect from THIS job's own card only. ----
    // Climb up, but STOP before reaching any container that also holds another
    // job — otherwise a neighbouring "I.T." role makes this one look like I.T.
    // too (which is exactly why Travel Designer showed up under Technology).
    let card = a;
    while (card.parentElement && card.parentElement !== root) {
      const parent = card.parentElement;
      const siblingJobs = Array.from(parent.querySelectorAll('a[href]')).filter(isJobLink).length;
      if (siblingJobs > 1) break;   // parent holds other jobs → don't merge their text
      card = parent;
    }
    let bucket = mapDept(card.textContent) || mapDept(title);
    if (!bucket) { unmapped.add(title); bucket = UNMAPPED_BUCKET; }

    // Manual overrides win over everything above
    const ov = TITLE_OVERRIDES[title.trim().toLowerCase()];
    if (ov) bucket = ov;

    jobs.push({ id: 'keka-' + i, title, dept: bucket, loc: 'Delhi', type: 'Full-time', applyUrl });
  });

  if (unmapped.size) {
    console.warn('[VARA5] Jobs with an unrecognised department (sent to "' + UNMAPPED_BUCKET +
      '"). Add their Keka category to DEPT_MAP:', Array.from(unmapped));
  }
  return jobs;
}

/* Add ?debug=1 to the URL to print what Keka actually rendered + what we parsed.
   Use this to diagnose if jobs ever fail to appear. */
function kekaDebug() {
  const root = document.querySelector(KEKA.staging);
  console.log('%c[VARA5 Keka debug]', 'color:#B07C54;font-weight:bold');
  console.log('staging node found:', !!root);
  console.log('raw anchors in staging:', root ? root.querySelectorAll('a[href]').length : 0);
  console.log('parsed jobs:', harvestKekaJobs());
  if (root) console.log('staging innerHTML (first 4000 chars):\n', root.innerHTML.slice(0, 4000));
}

/* ---------------- UI ---------------- */

function DeptHero({ dept }) {
  // GIFs loop natively. The GIF fills the whole hero; the copy overlaps the
  // (intentionally empty) area of each GIF. Below 860px the browser swaps to
  // the tall/portrait GIF so the avatar isn't cropped on phones.
  return (
    <header className="dept-hero">
      <picture className="dept-hero-media">
        <source media="(max-width: 860px)" srcSet={dept.gifPortrait} />
        <img className="dept-hero-gif" src={dept.gif} alt={dept.label + ' team'} />
      </picture>
      <div className="dept-hero-overlay">
        <div className="dept-hero-copy">
          <a href="index.html#openroles" className="dept-back">&larr; All teams</a>
          {/* <div className="eyebrow">{dept.eyebrow}</div> */}
          <h1>{dept.label}</h1>
          <p className="dept-hero-blurb">{dept.blurb}</p>
        </div>
      </div>
    </header>
  );
}

function JobRow({ job }) {
  const loc = FORCE_LOCATION || job.loc;
  return (
    <div className="job-row">
      <div className="job-main">
        <div className="job-title">{job.title}</div>
        <div className="job-meta">
          <span>{loc}</span><span className="dot"></span><span>{job.type}</span>
        </div>
      </div>
      <a className="job-apply btn btn-primary" href={job.applyUrl}
         target="_blank" rel="noopener noreferrer">
        <span>Apply</span><span className="arrow"></span>
      </a>
    </div>
  );
}

function App() {
  const params = new URLSearchParams(location.search);
  const key = params.get('dept');
  const dept = DEPARTMENTS[key] || DEPARTMENTS.operations;

  const [jobs, setJobs] = React.useState(SEED_JOBS);
  const [live, setLive] = React.useState(false);

  React.useEffect(() => { document.title = `${dept.label} — VARA5 Careers`; }, [dept.label]);

  React.useEffect(() => {
    if (!KEKA.enabled) return;
    const root = document.querySelector(KEKA.staging);
    if (!root) return;
    const debug = new URLSearchParams(location.search).get('debug') === '1';

    const pull = () => {
      const found = harvestKekaJobs();
      if (found.length) { setJobs(found); setLive(true); }
      return found.length;
    };

    pull();
    // Observe DOM changes…
    const obs = new MutationObserver(pull);
    obs.observe(root, { childList: true, subtree: true });
    // …and also poll, since some embeds swap content without a mutation we catch.
    const iv = setInterval(pull, 1000);
    const stop = setTimeout(() => {
      obs.disconnect(); clearInterval(iv);
      if (debug) kekaDebug();
    }, 12000);

    return () => { obs.disconnect(); clearInterval(iv); clearTimeout(stop); };
  }, []);

  const deptJobs = jobs.filter(j => j.dept === dept.id);
  const n = deptJobs.length;

  return (
    <React.Fragment>
      <DeptHero dept={dept} />

      <section className="dept-listing">
        <div className="container">
          <div className="listing-meta">
            <div className="count">
              {n === 0 ? 'No open roles' : <React.Fragment><em>{n}</em> Open {n === 1 ? 'Role' : 'Roles'}</React.Fragment>}
              {' '}in {dept.label}
            </div>
            
          </div>

          {n === 0 ? (
            <div className="listing-empty">
              <p>No open positions in {dept.label} right now.</p>
              <a href="mailto:careers@vara5.com" className="link-cta accent">
                Tell us what you'd build <span className="arrow"></span>
              </a>
            </div>
          ) : (
            <div className="job-list">
              {deptJobs.map(j => <JobRow key={j.id} job={j} />)}
            </div>
          )}
        </div>
      </section>

      <section className="other-depts">
        <div className="container">
          <div className="eyebrow" style={{ marginBottom: '24px' }}>Other teams</div>
          <div className="other-grid">
            {Object.values(DEPARTMENTS).filter(d => d.id !== dept.id).map(d => (
              <a key={d.id} className="other-card" href={`department.html?dept=${d.id}`}>
                <div className="t">{d.label}</div>
                <div className="arr">→</div>
              </a>
            ))}
          </div>
        </div>
      </section>
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById('app-mount')).render(<App />);
