// Talentir data layer — fetches from the backend API and exposes the same
// `window.TalentirData` shape the prototype views expect. Replaces the original
// mock-data module. Static enums + the WA demo conversation stay client-side;
// JOBS / CANDIDATES / HR_USERS / WA_NUMBERS / INTERVIEWS come from the API.

const API = window.TALENTIR_API || "http://localhost:3006";

const initials = (n) =>
  (n || "")
    .split(" ")
    .map((w) => w[0])
    .slice(0, 2)
    .join("")
    .toUpperCase();

// Fallback enums (used until /api/meta resolves; identical to the backend's).
const STATUSES = [
  { id: "baru", name: "Baru Masuk", color: "oklch(0.55 0.01 260)" },
  { id: "ai", name: "Disaring AI", color: "oklch(0.52 0.16 256)" },
  { id: "wawancara-hr", name: "Wawancara HR", color: "oklch(0.72 0.14 75)" },
  { id: "wawancara-user", name: "Wawancara User", color: "oklch(0.65 0.16 45)" },
  { id: "diterima", name: "Diterima", color: "oklch(0.58 0.13 155)" },
  { id: "ditolak", name: "Ditolak", color: "oklch(0.60 0.16 25)" },
];

const SOURCES = {
  whatsapp: { label: "WhatsApp", code: "WA", cls: "wa" },
  form: { label: "Form Mandiri", code: "FM", cls: "fm" },
  jobportal: { label: "Job Portal", code: "JP", cls: "jp" },
  glints: { label: "Glints", code: "GL", cls: "jp" },
  manual: { label: "Input Manual", code: "ML", cls: "ml" },
};

const INTERVIEW_MODES = {
  zoom: { label: "Zoom", color: "oklch(0.55 0.14 250)", icon: "🎥" },
  onsite: { label: "On-site", color: "oklch(0.58 0.13 30)", icon: "🏢" },
  "wa-call": { label: "WhatsApp Call", color: "oklch(0.55 0.14 152)", icon: "📞" },
  phone: { label: "Telepon", color: "oklch(0.55 0.05 260)", icon: "☎" },
};

// (Removed the WA_DEMO mock conversation: the drawer's Chat tab now renders
// real wa_logs from the API, and the WhatsApp view has its own thread loader.
// Nothing read this constant anymore.)

// --- field mappers: API row -> shape the prototype views read ---
const mapJob = (j) => ({
  id: j.id,
  title: j.title,
  dept: j.dept,
  loc: j.loc,
  type: j.type,
  status: j.status,
  wa: !!j.waBotEnabled,
  published: j.published,
  salary: j.salary,
  applicants: j.applicants,
  description: j.description,
  requirements: j.requirements || [],
  workSystem: j.workSystem ?? null,
  country: j.country ?? null,
  officeAddress: j.officeAddress ?? null,
  benefits: j.benefits || [],
});

const mapCandidate = (c) => ({
  id: c.id,
  jobId: c.jobId,
  name: c.name,
  email: c.email,
  phone: c.phone,
  location: c.location,
  age: c.age,
  experience: c.experience,
  status: c.status,
  score: c.score,
  source: c.source,
  appliedAt: c.appliedAt,
  tags: c.tags || [],
  hasWA: !!c.hasWa,
  hasCV: !!c.hasCv,
  assignedTo: c.assignedTo ?? null,
  aiSummary: c.aiSummary ?? null,
  cvUrl: c.cvUrl ?? null,
  notes: c.notes ?? null,
  // Rich profile fields (e.g. ingested from Glints) — null when not provided.
  gender: c.gender ?? null,
  distanceFromOfficeKm: c.distanceFromOfficeKm ?? null,
  willingToRelocate: c.willingToRelocate ?? null,
  educationLevel: c.educationLevel ?? null,
  educationMajor: c.educationMajor ?? null,
  educationInstitution: c.educationInstitution ?? null,
  currentPosition: c.currentPosition ?? null,
  currentCompany: c.currentCompany ?? null,
  previousPositions: c.previousPositions ?? null,
  skills: c.skills ?? null,
  expectedSalary: c.expectedSalary ?? null,
  lastActive: c.lastActive ?? null,
  sourceStatus: c.sourceStatus ?? null,
});

const mapWaNumber = (n) => ({
  id: n.id,
  label: n.label,
  phone: n.phone,
  branch: n.branch,
  assignedHR: n.assignedHr,
  status: n.status,
  connectedSince: n.connectedSince,
  msgToday: n.msgToday,
  msgWeek: n.msgWeek,
  queueDepth: n.queueDepth,
  rateLimit: { used: n.rateUsed, limit: n.rateLimit },
  assignedJobs: n.assignedJobs || [],
  isDefault: !!n.isDefault,
});

const get = (path) =>
  fetch(API + path, { credentials: "include" }).then((r) => {
    if (r.status === 401) {
      const e = new Error("unauthorized");
      e.code = 401;
      throw e;
    }
    if (!r.ok) throw new Error(`${path} → ${r.status}`);
    return r.json();
  });

// Seed window.TalentirData with statics + empty collections so any early
// render doesn't crash; loadTalentirData() fills the rest.
window.TalentirData = {
  JOBS: [],
  CANDIDATES: [],
  STATUSES,
  SOURCES,
  HR_USERS: [],
  WA_NUMBERS: [],
  INTERVIEWS: [],
  INTERVIEW_MODES,
  initials,
};

// Fetch everything the app needs, in parallel. Throws {code:401} when the
// recruiter isn't signed in so the bootstrapper can redirect to login.
window.loadTalentirData = async function loadTalentirData() {
  const [meta, jobs, candidates, hr, waNumbers, interviews, settings, orgs] =
    await Promise.all([
      get("/api/meta").catch(() => null),
      get("/api/jobs"),
      get("/api/candidates"),
      get("/api/hr"),
      get("/api/wa-numbers"),
      get("/api/interviews"),
      get("/api/settings").catch(() => null),
      get("/api/orgs").catch(() => null),
    ]);
  const activeOrg = orgs?.organizations?.find((o) => o.id === orgs.activeOrgId);

  window.TalentirData = {
    JOBS: jobs.map(mapJob),
    CANDIDATES: candidates.map(mapCandidate),
    STATUSES: meta?.statuses ?? STATUSES,
    SOURCES: meta?.sources ?? SOURCES,
    HR_USERS: hr, // /api/hr returns id/name/role/branch/avatar/color/...
    WA_NUMBERS: waNumbers.map(mapWaNumber),
    INTERVIEWS: interviews, // field names already match
    INTERVIEW_MODES: meta?.interviewModes ?? INTERVIEW_MODES,
    USER: settings?.profile ?? null,
    ORG_NAME: activeOrg?.name ?? settings?.organization?.name ?? null,
    ORGS: orgs?.organizations ?? [],
    ACTIVE_ORG_ID: orgs?.activeOrgId ?? null,
    DEFAULT_ORG_ID: orgs?.defaultOrgId ?? null,
    initials,
  };
  return window.TalentirData;
};

const write = (method) => (path, body) =>
  fetch(API + path, {
    method,
    credentials: "include",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body ?? {}),
  }).then((r) => {
    if (!r.ok) throw new Error(`${method} ${path} → ${r.status}`);
    return r.json();
  });

// Shared validators — keep validation logic in one place so every form
// (Tambah Kandidat, public assessment, Team invite, …) behaves the same.
window.TalentirValidate = {
  email: (s) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(s || '').trim()),
  // Accept Indonesian phones in any common shape: +62…, 62…, 08… — digits only.
  phone: (s) => {
    const d = String(s || '').replace(/\D/g, '');
    return d.length >= 9 && d.length <= 15;
  },
};

// Expose the API base + helpers (used by boot.jsx, app.jsx and login.html).
window.TalentirAPI = {
  base: API,
  get,
  post: write("POST"),
  patch: write("PATCH"),
  put: write("PUT"),
  mapCandidate, // so callers can normalize API rows to the UI shape
  async logout() {
    await fetch(API + "/api/auth/sign-out", {
      method: "POST",
      credentials: "include",
    }).catch(() => {});
  },
};
