const EXPERT_PAGE_SIZE = 24;

const normalizeExpertText = (value = "") => String(value)
  .replace(/[يى]/g, "ی")
  .replace(/ك/g, "ک")
  .replace(/\s+/g, " ")
  .trim()
  .toLocaleLowerCase("fa");

const uniqueExpertValues = (values) => [...new Set(values.filter(Boolean))]
  .sort((a, b) => a.localeCompare(b, "fa"));

const expertSourceLabel = (source, lang) => source === "23055"
  ? (lang === "fa" ? "مرکز کارشناسان رسمی قوه قضاییه" : "Judiciary Expert Center")
  : (lang === "fa" ? "کانون‌های کارشناسان رسمی دادگستری" : "Official Expert Associations");

const expertInitials = (name = "") => name.split(/\s+/).filter(Boolean).slice(0, 2).map((part) => part[0]).join("") || "ک";

const RealExpertAvatar = ({ person, large = false, lang }) => {
  const [failed, setFailed] = React.useState(false);
  React.useEffect(() => setFailed(false), [person.ph]);
  if (!person.ph || failed) {
    return <div className={`lv-avatar ${large ? "is-large" : ""}`} role="img" aria-label={lang === "fa" ? `تصویر برای ${person.n} منتشر نشده` : `No published portrait for ${person.n}`}><span>{expertInitials(person.n)}</span><Ic.microscope size={large ? 32 : 24}/></div>;
  }
  return <img src={person.ph} alt={lang === "fa" ? `تصویر ${person.n}` : `${person.n} portrait`} width={large ? 102 : 78} height={large ? 118 : 94} loading="lazy" onError={() => setFailed(true)}/>;
};

const RealExpertView = ({ lang }) => {
  const L = (fa, en, ar = fa) => lang === "fa" ? fa : lang === "ar" ? ar : en;
  const [directoryIndex, setDirectoryIndex] = React.useState(null);
  const [experts, setExperts] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [loadError, setLoadError] = React.useState(false);
  const [loadVersion, setLoadVersion] = React.useState(0);
  const [query, setQuery] = React.useState("");
  const [source, setSource] = React.useState("all");
  const [province, setProvince] = React.useState("all");
  const [city, setCity] = React.useState("all");
  const [field, setField] = React.useState("all");
  const [page, setPage] = React.useState(1);
  const [selectedId, setSelectedId] = React.useState("");
  const deferredQuery = React.useDeferredValue(normalizeExpertText(query));

  React.useEffect(() => {
    const controller = new AbortController();
    const load = async () => {
      setLoading(true);
      setLoadError(false);
      try {
        const indexResponse = await fetch("/expert-data/index.json?v=31.47", { signal: controller.signal });
        if (!indexResponse.ok) throw new Error(`index ${indexResponse.status}`);
        const nextIndex = await indexResponse.json();
        const responses = await Promise.all(nextIndex.sources.map((item) => fetch(item.file, { signal: controller.signal })));
        if (responses.some((response) => !response.ok)) throw new Error("expert dataset response failed");
        const datasets = await Promise.all(responses.map((response) => response.json()));
        const rows = datasets.flat();
        setDirectoryIndex(nextIndex);
        setExperts(rows);
        setSelectedId(rows[0]?.id || "");
      } catch (reason) {
        if (reason?.name !== "AbortError") setLoadError(true);
      } finally {
        if (!controller.signal.aborted) setLoading(false);
      }
    };
    load();
    return () => controller.abort();
  }, [loadVersion]);

  const searchIndex = React.useMemo(() => new Map(experts.map((person) => [person.id, normalizeExpertText([
    person.n, person.l, person.f, person.p, ...(person.c || []), ...(person.k || [])
  ].join(" "))])), [experts]);
  const sourceRows = React.useMemo(() => source === "all" ? experts : experts.filter((person) => person.src === source), [experts, source]);
  const provinces = React.useMemo(() => uniqueExpertValues(sourceRows.map((person) => person.p)), [sourceRows]);
  const provinceRows = React.useMemo(() => province === "all" ? sourceRows : sourceRows.filter((person) => person.p === province), [province, sourceRows]);
  const cities = React.useMemo(() => uniqueExpertValues(provinceRows.flatMap((person) => person.c || [])), [provinceRows]);
  const fields = React.useMemo(() => uniqueExpertValues(sourceRows.map((person) => person.f)), [sourceRows]);

  React.useEffect(() => { if (province !== "all" && !provinces.includes(province)) setProvince("all"); }, [province, provinces]);
  React.useEffect(() => { if (city !== "all" && !cities.includes(city)) setCity("all"); }, [city, cities]);
  React.useEffect(() => { if (field !== "all" && !fields.includes(field)) setField("all"); }, [field, fields]);

  const filtered = React.useMemo(() => experts.filter((person) => {
    if (source !== "all" && person.src !== source) return false;
    if (province !== "all" && person.p !== province) return false;
    if (city !== "all" && !(person.c || []).includes(city)) return false;
    if (field !== "all" && person.f !== field) return false;
    return !deferredQuery || searchIndex.get(person.id)?.includes(deferredQuery);
  }), [city, deferredQuery, experts, field, province, searchIndex, source]);

  const pageCount = Math.max(1, Math.ceil(filtered.length / EXPERT_PAGE_SIZE));
  const visible = React.useMemo(() => filtered.slice((page - 1) * EXPERT_PAGE_SIZE, page * EXPERT_PAGE_SIZE), [filtered, page]);
  React.useEffect(() => setPage(1), [city, deferredQuery, field, province, source]);
  React.useEffect(() => { if (page > pageCount) setPage(pageCount); }, [page, pageCount]);
  React.useEffect(() => { if (visible.length && !visible.some((person) => person.id === selectedId)) setSelectedId(visible[0].id); }, [selectedId, visible]);
  const selected = experts.find((person) => person.id === selectedId) || visible[0];

  if (loading) return <div className="lv-loading" role="status" aria-live="polite"><span/><h3>{L("در حال آماده‌سازی بانک واقعی کارشناسان", "Loading the verified expert directory")}</h3><p>{L("رشته‌ها، شهرها و پروفایل‌های رسمی در حال بارگذاری هستند…", "Loading official specialties, cities and profiles…")}</p></div>;
  if (loadError) return <div className="lv-empty" role="alert"><Ic.shieldAlert size={28}/><h3>{L("دریافت بانک کارشناسان انجام نشد.", "The expert directory could not be loaded.")}</h3><button className="btn ghost" onClick={() => setLoadVersion((value) => value + 1)}>{L("تلاش دوباره", "Retry")}</button></div>;

  return <section className="lv-directory expert-directory real-expert-directory" aria-label={L("بانک کارشناسان رسمی سراسر ایران", "Iran official expert directory")}>
    <div className="lv-intro"><div><span><Ic.shieldCheck size={15}/>{L("داده رسمی و تفکیک‌شده سراسر ایران", "Verified nationwide public data")}</span><h2>{L("انتخاب کارشناس بر پایه رشته، استان و شهر", "Choose an expert by specialty, province and city")}</h2><p>{L("اطلاعات واقعی استخراج‌شده از مرکز کارشناسان قوه قضاییه و کانون‌های کارشناسان رسمی؛ بدون پروفایل و امتیاز فرضی", "Real records from both official expert directories, without fictional profiles or ratings")}</p></div><div className="lv-count"><strong>{fmt(directoryIndex?.total || experts.length, lang)}</strong><span>{L("کارشناس واقعی", "real experts")}</span></div></div>
    <div className="lv-filter-card"><div className="lv-filter-grid real-expert-filters">
      <label className="lv-search"><span>{L("جست‌وجوی کارشناس", "Search experts")}</span><div><Ic.search size={17}/><input value={query} onChange={(event) => setQuery(event.target.value)} placeholder={L("نام، شماره پروانه، رشته یا صلاحیت…", "Name, license, specialty or competency…")}/></div></label>
      <label><span>{L("مرجع", "Source")}</span><select value={source} onChange={(event) => setSource(event.target.value)}><option value="all">{L("هر دو مرجع", "Both sources")}</option><option value="23055">{expertSourceLabel("23055", lang)}</option><option value="kanoon">{expertSourceLabel("kanoon", lang)}</option></select></label>
      <label><span>{L("استان", "Province")}</span><select value={province} onChange={(event) => setProvince(event.target.value)}><option value="all">{L(`همه استان‌ها (${fmt(provinces.length, lang)})`, `All provinces (${provinces.length})`)}</option>{provinces.map((item) => <option key={item} value={item}>{item}</option>)}</select></label>
      <label><span>{L("شهر", "City")}</span><select value={city} onChange={(event) => setCity(event.target.value)}><option value="all">{L(`همه شهرها (${fmt(cities.length, lang)})`, `All cities (${cities.length})`)}</option>{cities.map((item) => <option key={item} value={item}>{item}</option>)}</select></label>
      <label><span>{L("رشته کارشناسی", "Specialty")}</span><select value={field} onChange={(event) => setField(event.target.value)}><option value="all">{L(`همه رشته‌ها (${fmt(fields.length, lang)})`, `All specialties (${fields.length})`)}</option>{fields.map((item) => <option key={item} value={item}>{item}</option>)}</select></label>
    </div></div>
    <div className="lv-meta" aria-live="polite"><span>{L(`${fmt(filtered.length, lang)} کارشناس مطابق فیلترها`, `${filtered.length.toLocaleString()} matching experts`)}</span><small><Ic.shieldCheck size={13}/>{L(`${fmt(directoryIndex?.field_count || fields.length, lang)} رشته · ${fmt(directoryIndex?.city_count || cities.length, lang)} شهر · ${fmt(directoryIndex?.with_photo || 0, lang)} تصویر رسمی`, `${directoryIndex?.field_count || fields.length} specialties · ${directoryIndex?.city_count || cities.length} cities`)}</small></div>
    {visible.length ? <div className="lv-layout"><div><div className="lv-list" role="list">{visible.map((person) => { const active = selected?.id === person.id; return <button key={person.id} role="listitem" className={`lv-card ${active ? "active" : ""}`} aria-pressed={active} onClick={() => setSelectedId(person.id)}><RealExpertAvatar person={person} lang={lang}/><div className="lv-card-body"><div className="lv-card-title"><div><h3>{person.n}<Ic.shieldCheck size={14}/></h3><p>{L("پروانه", "License")} <b>{person.l || "—"}</b> · {expertSourceLabel(person.src, lang)}</p></div></div><div className="lv-card-facts"><span><Ic.building size={14}/>{[person.p, (person.c || [])[0]].filter(Boolean).join("، ") || "—"}</span>{person.s && <span><Ic.shieldCheck size={13}/>{person.s}</span>}</div><div className="lv-card-bottom"><div className="lv-tags"><span>{person.f || L("رشته منتشر نشده", "Specialty not published")}</span></div></div></div></button>})}</div><nav className="lv-pagination" aria-label={L("صفحه‌بندی کارشناسان", "Expert pagination")}><button onClick={() => setPage((value) => Math.max(1, value - 1))} disabled={page === 1}>{L("صفحه قبل", "Previous")}</button><span>{L(`صفحه ${fmt(page, lang)} از ${fmt(pageCount, lang)}`, `Page ${page} of ${pageCount}`)}</span><button onClick={() => setPage((value) => Math.min(pageCount, value + 1))} disabled={page === pageCount}>{L("صفحه بعد", "Next")}</button></nav></div>
      {selected && <aside className="lv-profile"><div className="lv-profile-head"><RealExpertAvatar person={selected} large lang={lang}/><div><div className="lv-verified"><Ic.shieldCheck size={14}/>{L("رکورد عمومی مرجع رسمی", "Official public record")}</div><h3>{selected.n}</h3><p>{selected.t || L("کارشناس رسمی دادگستری", "Official expert")} · {L("پروانه", "License")} <b>{selected.l || "—"}</b></p></div></div><div className="lv-profile-content"><div className="lv-info-grid"><div><span><Ic.microscope size={15}/>{L("رشته کارشناسی", "Specialty")}</span><b>{selected.f || "—"}</b></div><div><span><Ic.shieldCheck size={15}/>{L("وضعیت پروانه", "License status")}</span><b>{selected.s || "—"}{selected.v ? ` · ${L("تا", "until")} ${selected.v}` : ""}</b></div><div><span><Ic.building size={15}/>{L("استان و شهرها", "Province and cities")}</span><b>{[selected.p, ...(selected.c || [])].filter(Boolean).join("، ") || "—"}</b></div><div><span><Ic.shield size={15}/>{L("مرجع وابسته", "Affiliation")}</span><b>{selected.a || expertSourceLabel(selected.src, lang)}</b></div>{selected.g && <div className="is-wide"><span><Ic.building size={15}/>{L("حوزه جغرافیایی", "Geographic scope")}</span><b>{selected.g}</b></div>}</div><div className="lv-specialties"><h4><Ic.microscope size={16}/>{L(`صلاحیت‌های منتشرشده (${fmt((selected.k || []).length, lang)})`, `Published competencies (${(selected.k || []).length})`)}</h4>{(selected.k || []).length ? <div className="lv-tags">{selected.k.map((item) => <span key={item}>{item}</span>)}</div> : <p>{L("صلاحیتی در پروفایل عمومی منتشر نشده است.", "No competency was published in the public profile.")}</p>}</div></div></aside>}
    </div> : <div className="lv-empty"><Ic.search size={28}/><h3>{L("کارشناسی با این مشخصات پیدا نشد", "No matching expert found")}</h3><button className="btn ghost" onClick={() => { setQuery(""); setSource("all"); setProvince("all"); setCity("all"); setField("all"); }}>{L("پاک کردن فیلترها", "Clear filters")}</button></div>}
  </section>;
};
