// app.jsx — main application shell + flow state machine
const { useState: useS, useEffect: useE, useMemo } = React;

// Konfigurasi brand (tetap, tidak bisa diubah runtime)
const CONFIG = {
  brand:       "#e81090",
  accent:      "#a855f7",
  font:        "'Plus Jakarta Sans'",
  radius:      18,
  authLayout:  "split",
  testLayout:  "card",
  brandSuffix: "Karier",
};

const STATE_KEY = "rabbani_karier_state_v1";

function mapApplicationToProfile(a) {
  return {
    fullName:    a.full_name    || "",
    aboutMe:     a.about_me    || "",
    birthPlace:  a.birth_place || "",
    birthDate:   a.birth_date  ? a.birth_date.slice(0, 10) : "",
    address:     a.address     || "",
    edu:         a.edu_level   != null ? a.edu_level : "",
    major:       a.major       || "",
    instagram:   a.instagram   || "",
    tiktok:      a.tiktok      || "",
    linkedin:    a.linkedin    || "",
    facebook:    a.facebook    || "",
    famName:     a.fam_name    || "",
    famRelation: a.fam_relation || "",
    famPhone:    a.fam_phone   || "",
    positions:   Array.isArray(a.positions_json)  ? a.positions_json  : [],
    locations:   Array.isArray(a.locations_json)  ? a.locations_json  : [],
    salary:      a.salary      || "",
    workHistory: Array.isArray(a.work_history)    ? a.work_history    : [],
    otherPhones: Array.isArray(a.other_phones)    ? a.other_phones    : [],
    skills:      Array.isArray(a.skills)          ? a.skills          : [],
    references:  Array.isArray(a.references_data) ? a.references_data : [],
  };
}

// URL ↔ step mapping
const STEP_TO_PATH = {
  register: "/lamaran",
  otp:      "/lamaran/otp",
  login:    "/lamaran/login",
  forgot:   "/lamaran/forgot",
  method:   "/lamaran/metode",
  cv:       "/lamaran/cv",
  profile:  "/lamaran/profil",
  disc:     "/lamaran/test-1",
  iq:       "/lamaran/test-2",
  aptitude: "/lamaran/test-3",
  member:   "/lamaran/status",
};
const PATH_TO_STEP = Object.fromEntries(Object.entries(STEP_TO_PATH).map(([s,p])=>[p,s]));

function loadState() {
  try { return JSON.parse(localStorage.getItem(STATE_KEY)) || {}; } catch { return {}; }
}

function App() {
  const saved = useMemo(loadState, []);

  // Baca ?pos=N dari URL landing page untuk pre-select posisi
  const urlPos = useMemo(() => {
    const p = new URLSearchParams(location.search).get("pos");
    return p !== null ? Number(p) : null;
  }, []);

  // Tentukan step awal dari URL path
  // Step yang butuh session — jika tidak ada token, reset ke register
  const PROTECTED_STEPS = new Set(["method","cv","profile","disc","iq","aptitude","member"]);
  const initialStep = useMemo(() => {
    const urlPath = location.pathname.replace(/\/$/, "") || "/lamaran";
    const stepFromUrl = PATH_TO_STEP[urlPath];
    const hasToken = !!window.API.getToken();
    if (stepFromUrl && PROTECTED_STEPS.has(stepFromUrl) && !hasToken) {
      // Clear localStorage dan kembalikan ke register
      localStorage.removeItem(STATE_KEY);
      history.replaceState({ step: "register" }, "", "/lamaran");
      return "register";
    }
    return stepFromUrl || saved.step || "register";
  }, []);

  const [lang,  setLang]  = useS(saved.lang  || "id");
  const [step,  setStep]  = useS(initialStep);
  const [masterPositions, setMasterPositions] = useS([]);
  const [masterLocations, setMasterLocations] = useS([]);

  useE(() => {
    window.API.getPositions().then(d => { if (Array.isArray(d)) setMasterPositions(d); }).catch(()=>{});
    window.API.getLocations().then(d => { if (Array.isArray(d)) setMasterLocations(d); }).catch(()=>{});
  }, []);
  const [state, setState] = useS(() => {
    // profile tidak boleh diambil dari cache lokal — DB adalah satu-satunya source of truth,
    // cache lama bisa berisi posisi/lokasi basi dan memicu auto-save menimpa data DB yang benar
    const { profile, ...s } = saved.state || {};
    if (urlPos !== null) {
      return { ...s, profile: { positions: [urlPos] } };
    }
    return s;
  });

  const tr = window.I18N[lang];

  // Terapkan CSS vars dari CONFIG saat mount
  useE(() => {
    const r = document.documentElement.style;
    r.setProperty("--brand",      CONFIG.brand);
    r.setProperty("--accent",     CONFIG.accent);
    r.setProperty("--font-sans",  `${CONFIG.font}, system-ui, sans-serif`);
    r.setProperty("--radius",     CONFIG.radius + "px");
    r.setProperty("--radius-sm",  (CONFIG.radius * 0.66) + "px");
    r.setProperty("--radius-lg",  (CONFIG.radius * 1.44) + "px");
  }, []);

  // Simpan progres ke localStorage — profile & cvFilled dikecualikan (DB sebagai source of truth)
  useE(() => {
    const { profile, cvFilled, ...rest } = state;
    localStorage.setItem(STATE_KEY, JSON.stringify({ lang, step, state: rest }));
  }, [lang, step, state]);

  const [profileReady, setProfileReady] = useS(!window.API.getToken());

  // Load profil dari DB saat app init (jika sudah login)
  useE(() => {
    if (!window.API.getToken()) return;
    window.API.getMyApplication().then(res => {
      const a = res?.application;
      if (a) {
        setState(s => ({
          ...s,
          cvFilled:   !!a.full_name,
          discResult: a.disc_result  ?? s.discResult,
          iqResult:   a.iq_result    ?? s.iqResult,
          aptResult:  a.apt_result   ?? s.aptResult,
          appId:      a.app_id       || s.appId,
          profile:    mapApplicationToProfile(a),
          reg:        { ...(s.reg || {}), email: a.email || s.reg?.email || "", wa: a.wa || s.reg?.wa || "", name: a.name || s.reg?.name || "" },
        }));
      }
      setProfileReady(true);
    }).catch(() => { setProfileReady(true); });
  }, []);

  // Auto-save profile ke DB saat berubah (debounce 1.5 detik)
  // profileReady wajib true dulu — mencegah cache lama/basi menimpa data DB yang sudah benar
  useE(() => {
    if (!window.API.getToken() || !state.profile || !profileReady) return;
    const hasData = state.profile.fullName || state.profile.birthPlace || state.profile.positions?.length;
    if (!hasData) return;
    const timer = setTimeout(() => {
      window.API.saveStep('profile', { profile: state.profile }).catch(() => {});
    }, 1500);
    return () => clearTimeout(timer);
  }, [state.profile]);

  const needsApt = (state.profile?.positions || []).some(posId => {
    const p = masterPositions.find(p => p.id === posId);
    return p ? p.test_apt : window.APPDATA.needsAptitude(posId);
  });

  const phaseOf = { register: 0, otp: 0, login: 0, forgot: 0, method: 1, cv: 1, profile: 1, disc: 2, iq: 3, aptitude: 4, member: needsApt ? 4 : 3 };
  const phase = phaseOf[step] ?? 0;
  const steps = needsApt
    ? [tr.stepRegister, tr.stepProfile, tr.stepDisc, tr.stepIq, tr.stepApt]
    : [tr.stepRegister, tr.stepProfile, tr.stepDisc, tr.stepIq];

  function go(s) {
    const path = STEP_TO_PATH[s] || "/lamaran";
    history.pushState({ step: s }, "", path);
    setStep(s);
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  // Ref untuk akses state terkini di dalam event listener
  const stateRef = React.useRef(state);
  useE(() => { stateRef.current = state; }, [state]);

  // Browser back/forward button
  useE(() => {
    function onPop(e) {
      const s = e.state?.step || PATH_TO_STEP[location.pathname] || "register";
      const cur = stateRef.current;
      // Jika mencoba kembali ke step test yang sudah selesai, arahkan ke step berikutnya
      if (s === "disc" && cur.discResult) {
        const next = cur.iqResult ? "member" : "iq";
        history.replaceState({ step: next }, "", STEP_TO_PATH[next] || "/lamaran");
        setStep(next);
      } else if (s === "iq" && cur.iqResult) {
        history.replaceState({ step: "member" }, "", STEP_TO_PATH["member"] || "/lamaran");
        setStep("member");
      } else if (s === "aptitude" && cur.aptResult != null) {
        history.replaceState({ step: "member" }, "", STEP_TO_PATH["member"] || "/lamaran");
        setStep("member");
      } else {
        setStep(s);
      }
      window.scrollTo({ top: 0 });
    }
    window.addEventListener("popstate", onPop);
    // Set initial history state tanpa push baru
    history.replaceState({ step }, "", STEP_TO_PATH[step] || "/lamaran");
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  // Simpan data step ke API lalu pindah step
  function saveAndGo(apiStep, data, nextStep) {
    go(nextStep);
    if (window.API.getToken()) {
      window.API.saveStep(apiStep, data).then(res => {
        if (res?.error) console.error('[saveAndGo]', apiStep, res.error);
        if (res?.appId) setState(s => ({ ...s, appId: res.appId }));
      }).catch(e => console.error('[saveAndGo] fetch error:', e));
    }
  }

  // Hapus sesi & state lokal (untuk logout dari member area)
  function logout() {
    window.API.clearSession();
    setState({});
    history.pushState({ step: "register" }, "", "/lamaran");
    setStep("register");
    window.scrollTo({ top: 0 });
  }

  const [editMode, setEditMode] = useS(false);
  const autoFilled = !!state.cvFilled;

  function fillFromCv(cv) {
    // Placeholder email dari template CV (abaikan, pakai email registrasi)
    const PLACEHOLDER_EMAILS = /^(name@|nama@|your@|example@|test@|email@|sample@|dummy@)/i;
    const registeredEmail = state.reg?.email || "";
    const registeredWa    = state.reg?.wa    || "";
    const cvEmail = (cv.email && !PLACEHOLDER_EMAILS.test(cv.email)) ? cv.email : registeredEmail;

    // Pisahkan nomor HP dari CV — nomor yang sudah di-OTP terkunci, sisanya jadi "kontak lain"
    const normalize = n => n.replace(/\D/g, "").replace(/^620?/, "0").replace(/^62/, "0");
    const regWaNorm = normalize(registeredWa);
    const cvWaRaw   = cv.wa || "";
    const allNums   = cvWaRaw.split(/[\/,]/).map(s => s.trim()).filter(Boolean);
    const otherPhones = allNums.filter(n => normalize(n) !== regWaNorm && n !== "");

    setState((s) => ({
      ...s,
      cvFilled: true,
      profile: {
        ...(s.profile || {}),
        fullName:    cv.fullName   || s.profile?.fullName   || "",
        otherPhones: otherPhones.length ? otherPhones : (s.profile?.otherPhones || []),
        email:       cvEmail,
        birthPlace:  cv.birthPlace || s.profile?.birthPlace || "",
        birthDate:   cv.birthDate  || s.profile?.birthDate  || "",
        address:     cv.address    || s.profile?.address    || "",
        edu:         cv.edu        ? (() => {
                       const e = cv.edu.toUpperCase();
                       if (e.includes('S2') || e.includes('MAGISTER') || e.includes('MASTER')) return 3;
                       if (e.includes('S1') || e.includes('SARJANA') || e.includes('BACHELOR') || e.includes('D4')) return 2;
                       if (e.includes('D3') || e.includes('D2') || e.includes('D1') || e.includes('DIPLOMA')) return 1;
                       if (e.includes('SMA') || e.includes('SMK') || e.includes('SMP') || e.includes('SD')) return 0;
                       return s.profile?.edu ?? "";
                     })() : (s.profile?.edu ?? ""),
        major:       cv.major      || s.profile?.major      || "",
        aboutMe:     cv.aboutMe    || s.profile?.aboutMe    || "",
        experience:  cv.experience || s.profile?.experience || "",
        positions:   urlPos !== null ? [urlPos] : (s.profile?.positions || []),
        location:    s.profile?.location ?? "",
        salary:      cv.salary     || s.profile?.salary     || "",
        instagram:   cv.instagram  || s.profile?.instagram  || "",
        tiktok:      cv.tiktok     || s.profile?.tiktok     || "",
        workHistory: cv.workHistory?.length
          ? cv.workHistory.map(w => ({ company: w.company, position: w.position, period: w.period, salary: w.salary || "" }))
          : (s.profile?.workHistory || []),
        skills:      cv.skills?.length     ? cv.skills     : (s.profile?.skills     || []),
        references:  cv.references?.length ? cv.references : (s.profile?.references || []),
        facebook:    cv.facebook   || s.profile?.facebook   || "",
        famName:     s.profile?.famName     || "",
        famRelation: s.profile?.famRelation || "",
        famPhone:    s.profile?.famPhone    || "",
      }
    }));
    go("profile");
  }

  function profileNext() {
    const data = { profile: state.profile };
    if (editMode) { setEditMode(false); saveAndGo("profile", data, "member"); return; }
    if (!state.discResult)                             saveAndGo("profile", data, "disc");
    else if (!state.iqResult)                          saveAndGo("profile", data, "iq");
    else if (needsApt && state.aptResult == null)      saveAndGo("profile", data, "aptitude");
    else                                               saveAndGo("profile", data, "member");
  }
  function profileBack() {
    if (editMode) { setEditMode(false); go("member"); }
    else go("method");
  }
  function editProfile() { setEditMode(true); go("profile"); }

  let screen = null;
  if (step === "register")
    screen = <RegisterScreen t={tr} lang={lang} setLang={setLang} state={state} setState={setState}
               onNext={() => go("otp")} onLogin={() => go("login")} layout={CONFIG.authLayout} />;

  else if (step === "login")
    screen = <LoginScreen t={tr} lang={lang} state={state} setState={setState}
               onSuccess={(resumeStep, loginData) => {
                 setState(s => ({
                   ...s,
                   ...(loginData?.discResult != null ? { discResult: loginData.discResult } : {}),
                   ...(loginData?.iqResult   != null ? { iqResult:   loginData.iqResult   } : {}),
                   ...(loginData?.aptResult  != null ? { aptResult:  loginData.aptResult  } : {}),
                   ...(loginData?.appId ? { appId: loginData.appId } : {}),
                 }));
                 go(resumeStep || "member");
                 window.API.getMyApplication().then(res => {
                   const a = res?.application;
                   if (!a) return;
                   setState(s => ({ ...s, cvFilled: !!a.full_name, profile: mapApplicationToProfile(a) }));
                 }).catch(() => {});
               }}
               onBack={() => go("register")} onForgot={() => go("forgot")} />;

  else if (step === "forgot")
    screen = <ForgotPasswordScreen t={tr} lang={lang}
               onBack={() => go("login")} onSuccess={() => go("login")} />;

  else if (step === "otp")
    screen = <OtpScreen t={tr} lang={lang} state={state} setState={setState}
               onNext={() => go("method")} onBack={() => go("register")} />;

  else if (step === "method")
    screen = <MethodScreen t={tr} lang={lang} state={state}
               onChoose={(m) => {
                 if (m === "upload") go("cv");
                 else { setState((s) => ({ ...s, cvFilled: false })); go("profile"); }
               }} />;

  else if (step === "cv")
    screen = <CvUploadScreen t={tr} lang={lang} onParsed={(data) => fillFromCv(data || {})} onBack={() => go("method")} />;

  else if (step === "profile") {
    const testsAllDone = !!(state.discResult && state.iqResult && (!needsApt || state.aptResult != null));
    screen = <ProfileScreen t={tr} lang={lang} state={state} setState={setState}
               autoFilled={autoFilled && !editMode} editMode={editMode}
               profileReady={profileReady} testsAllDone={testsAllDone}
               masterPositions={masterPositions} masterLocations={masterLocations}
               onNext={profileNext} onBack={profileBack} />;
  }

  else if (step === "disc")
    screen = <DiscScreen t={tr} lang={lang} state={state} setState={setState}
               onNext={(data) => saveAndGo("disc", data, "iq")}
               layout={CONFIG.testLayout} />;

  else if (step === "iq")
    screen = <IqScreen t={tr} lang={lang} state={state} setState={setState}
               onNext={(data) => saveAndGo("iq", data, needsApt ? "aptitude" : "member")}
               layout={CONFIG.testLayout} />;

  else if (step === "aptitude")
    screen = <AptitudeScreen t={tr} lang={lang} state={state} setState={setState}
               onNext={(data) => saveAndGo("aptitude", data, "member")}
               layout={CONFIG.testLayout} />;

  else if (step === "member")
    screen = <MemberScreen t={tr} lang={lang} state={state} setState={setState} needsApt={needsApt}
               masterLocations={masterLocations}
               onEditProfile={editProfile} onLogout={logout} />;

  const testsCompleted = !!(state.discResult && state.iqResult);
  const showStepper = !testsCompleted && step !== "member" && step !== "login" && step !== "forgot";
  const showMemberNav = testsCompleted && (step === "profile" || step === "member");

  return (
    <div className="app">
      <header className="topbar">
        <a href="/" style={{ textDecoration: "none", color: "inherit" }}>
          <Logo suffix={CONFIG.brandSuffix} />
        </a>
        <div className="spacer" />
        {showStepper && (
          <div style={{ marginRight: 8 }}>
            <Stepper steps={steps} current={phase} />
          </div>
        )}
        {showMemberNav && (
          <nav style={{ display: "flex", gap: 8, marginRight: 8 }}>
            <a href="/lamaran/status" className="btn btn-ghost" style={{ fontSize: 13, padding: "6px 14px" }}>
              {lang === "id" ? "Beranda" : "Home"}
            </a>
            <button className="btn btn-ghost" style={{ fontSize: 13, padding: "6px 14px" }}
              onClick={() => step === "member" ? editProfile() : go("member")}>
              {step === "member" ? (lang === "id" ? "Ubah Profil" : "Edit Profile") : (lang === "id" ? "← Kembali" : "← Back")}
            </button>
            <button className="btn btn-ghost" style={{ fontSize: 13, padding: "6px 14px" }}
              onClick={logout}>
              {lang === "id" ? "Keluar" : "Sign out"}
            </button>
          </nav>
        )}
        <div className="lang-toggle">
          <button className={lang === "id" ? "on" : ""} onClick={() => setLang("id")}>ID</button>
          <button className={lang === "en" ? "on" : ""} onClick={() => setLang("en")}>EN</button>
        </div>
      </header>

      <main className="content">{screen}</main>

      <footer className="app-footer">
        <div className="af-inner">
          <div className="footer-simple">
            <a className="logo" href="/"><img src="/assets/rabbani-logo.png" alt="Rabbani" /><b>Rabbani<span className="k"> Karier</span></b></a>
            <nav className="footer-nav">
              <a href="/#posisi">Posisi Terbuka</a>
              <a href="/#proses">Proses Seleksi</a>
              <a href="/#budaya">Budaya Kerja</a>
              <a href="/#faq">FAQ</a>
              {!window.API.getToken() && <a href="/lamaran">Lamar Sekarang</a>}
            </nav>
          </div>
          <div className="footer-bottom">
            <span>© 2026 Rabbani. Seluruh hak cipta dilindungi.</span>
            <span><a href="tel:+62227209256">(022) 7209256</a> · Jl. Citarum No.20A, Bandung Wetan 40115</span>
          </div>
        </div>
      </footer>
    </div>
  );
}

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