/* =============================================================
   CreateChartPage.jsx — "إنشاء خريطتي" / Create my chart
   -----
   The entry point to the REAL chart engine. Collects birth data,
   calls HDEngine (via ChartStore.createChart), then routes to the
   computed result (overview). Mirrors reference page-21-create-chart.
   Browser build: classic <script type="text/babel">; window.CreateChartPage
   ============================================================= */
(function () {
  const { useState, useMemo } = React;

  // Detect whether a string is primarily Arabic script.
  function isArabicStr(s) { return /[\u0600-\u06FF]/.test(s || ""); }

  // ── Curated birth-place presets (lat, lng, standard GMT offset min) ──
  // Offsets are standard time; users can adjust the timezone for DST-era births.
  const CITIES = [
    { k: "riyadh",    ar: "الرياض، السعودية",   en: "Riyadh, Saudi Arabia",     lat: 24.7136,  lng: 46.6753,  tz: 180 },
    { k: "jeddah",    ar: "جدة، السعودية",       en: "Jeddah, Saudi Arabia",     lat: 21.4858,  lng: 39.1925,  tz: 180 },
    { k: "mecca",     ar: "مكة، السعودية",       en: "Mecca, Saudi Arabia",      lat: 21.3891,  lng: 39.8579,  tz: 180 },
    { k: "cairo",     ar: "القاهرة، مصر",          en: "Cairo, Egypt",             lat: 30.0444,  lng: 31.2357,  tz: 120 },
    { k: "alex",      ar: "الإسكندرية، مصر",      en: "Alexandria, Egypt",        lat: 31.2001,  lng: 29.9187,  tz: 120 },
    { k: "giza",      ar: "الجيزة، مصر",          en: "Giza, Egypt",              lat: 30.0131,  lng: 31.2089,  tz: 120 },
    { k: "suez",      ar: "السويس، مصر",           en: "Suez, Egypt",              lat: 29.9737,  lng: 32.5311,  tz: 120 },
    { k: "portsaid",  ar: "بورسعيد، مصر",         en: "Port Said, Egypt",         lat: 31.2653,  lng: 32.3019,  tz: 120 },
    { k: "ismailia",  ar: "الإسماعيلية، مصر",     en: "Ismailia, Egypt",          lat: 30.5965,  lng: 32.2715,  tz: 120 },
    { k: "mansura",   ar: "المنصورة، مصر",        en: "Mansoura, Egypt",          lat: 31.0364,  lng: 31.3807,  tz: 120 },
    { k: "tanta",     ar: "طنطا، مصر",            en: "Tanta, Egypt",             lat: 30.7865,  lng: 30.9996,  tz: 120 },
    { k: "zagazig",   ar: "الزقازيق، مصر",        en: "Zagazig, Egypt",           lat: 30.5833,  lng: 31.5000,  tz: 120 },
    { k: "damietta",  ar: "دمياط، مصر",           en: "Damietta, Egypt",          lat: 31.4165,  lng: 31.8133,  tz: 120 },
    { k: "faiyum",    ar: "الفيوم، مصر",          en: "Faiyum, Egypt",            lat: 29.3084,  lng: 30.8428,  tz: 120 },
    { k: "benisuef",  ar: "بني سويف، مصر",        en: "Beni Suef, Egypt",         lat: 29.0661,  lng: 31.0994,  tz: 120 },
    { k: "minya",     ar: "المنيا، مصر",          en: "Minya, Egypt",             lat: 28.1099,  lng: 30.7503,  tz: 120 },
    { k: "asyut",     ar: "أسيوط، مصر",           en: "Asyut, Egypt",             lat: 27.1809,  lng: 31.1837,  tz: 120 },
    { k: "sohag",     ar: "سوهاج، مصر",           en: "Sohag, Egypt",             lat: 26.5591,  lng: 31.6956,  tz: 120 },
    { k: "qena",      ar: "قنا، مصر",             en: "Qena, Egypt",              lat: 26.1551,  lng: 32.7160,  tz: 120 },
    { k: "luxor",     ar: "الأقصر، مصر",          en: "Luxor, Egypt",             lat: 25.6872,  lng: 32.6396,  tz: 120 },
    { k: "aswan",     ar: "أسوان، مصر",           en: "Aswan, Egypt",             lat: 24.0889,  lng: 32.8998,  tz: 120 },
    { k: "hurghada",  ar: "الغردقة، مصر",         en: "Hurghada, Egypt",          lat: 27.2579,  lng: 33.8116,  tz: 120 },
    { k: "sharm",     ar: "شرم الشيخ، مصر",       en: "Sharm El-Sheikh, Egypt",   lat: 27.9158,  lng: 34.3300,  tz: 120 },
    { k: "matrouh",   ar: "مرسى مطروح، مصر",      en: "Mersa Matruh, Egypt",      lat: 31.3543,  lng: 27.2373,  tz: 120 },
    { k: "dubai",     ar: "دبي، الإمارات",       en: "Dubai, UAE",               lat: 25.2048,  lng: 55.2708,  tz: 240 },
    { k: "abudhabi",  ar: "أبوظبي، الإمارات",    en: "Abu Dhabi, UAE",           lat: 24.4539,  lng: 54.3773,  tz: 240 },
    { k: "doha",      ar: "الدوحة، قطر",         en: "Doha, Qatar",              lat: 25.2854,  lng: 51.5310,  tz: 180 },
    { k: "kuwait",    ar: "الكويت",              en: "Kuwait City, Kuwait",      lat: 29.3759,  lng: 47.9774,  tz: 180 },
    { k: "manama",    ar: "المنامة، البحرين",    en: "Manama, Bahrain",          lat: 26.2285,  lng: 50.5860,  tz: 180 },
    { k: "muscat",    ar: "مسقط، عُمان",         en: "Muscat, Oman",             lat: 23.5880,  lng: 58.3829,  tz: 240 },
    { k: "sanaa",     ar: "صنعاء، اليمن",        en: "Sanaa, Yemen",             lat: 15.3694,  lng: 44.1910,  tz: 180 },
    { k: "amman",     ar: "عمّان، الأردن",       en: "Amman, Jordan",            lat: 31.9454,  lng: 35.9284,  tz: 180 },
    { k: "beirut",    ar: "بيروت، لبنان",        en: "Beirut, Lebanon",          lat: 33.8938,  lng: 35.5018,  tz: 120 },
    { k: "damascus",  ar: "دمشق، سوريا",         en: "Damascus, Syria",          lat: 33.5138,  lng: 36.2765,  tz: 120 },
    { k: "baghdad",   ar: "بغداد، العراق",       en: "Baghdad, Iraq",            lat: 33.3152,  lng: 44.3661,  tz: 180 },
    { k: "khartoum",  ar: "الخرطوم، السودان",    en: "Khartoum, Sudan",          lat: 15.5007,  lng: 32.5599,  tz: 120 },
    { k: "tripoli",   ar: "طرابلس، ليبيا",       en: "Tripoli, Libya",           lat: 32.8872,  lng: 13.1913,  tz: 120 },
    { k: "tunis",     ar: "تونس",                en: "Tunis, Tunisia",           lat: 36.8065,  lng: 10.1815,  tz: 60 },
    { k: "algiers",   ar: "الجزائر",             en: "Algiers, Algeria",         lat: 36.7538,  lng: 3.0588,   tz: 60 },
    { k: "casa",      ar: "الدار البيضاء، المغرب",en: "Casablanca, Morocco",      lat: 33.5731,  lng: -7.5898,  tz: 60 },
    { k: "istanbul",  ar: "إسطنبول، تركيا",      en: "Istanbul, Türkiye",        lat: 41.0082,  lng: 28.9784,  tz: 180 },
    { k: "london",    ar: "لندن، بريطانيا",      en: "London, UK",               lat: 51.5074,  lng: -0.1278,  tz: 0 },
    { k: "paris",     ar: "باريس، فرنسا",        en: "Paris, France",            lat: 48.8566,  lng: 2.3522,   tz: 60 },
    { k: "newyork",   ar: "نيويورك، أمريكا",     en: "New York, USA",            lat: 40.7128,  lng: -74.0060, tz: -300 },
    { k: "la",        ar: "لوس أنجلوس، أمريكا",  en: "Los Angeles, USA",         lat: 34.0522,  lng: -118.2437,tz: -480 },
    { k: "mumbai",    ar: "مومباي، الهند",       en: "Mumbai, India",            lat: 19.0760,  lng: 72.8777,  tz: 330 },
    { k: "jakarta",   ar: "جاكرتا، إندونيسيا",   en: "Jakarta, Indonesia",       lat: -6.2088,  lng: 106.8456, tz: 420 },
  ];

  // GMT offset options (minutes) with sample-city labels (reference style)
  const TZ_OPTS = [
    { v: 0,    ar: "(GMT+00:00) لندن، الدار البيضاء",   en: "(GMT+00:00) London, Casablanca" },
    { v: 60,   ar: "(GMT+01:00) باريس، تونس، الجزائر",  en: "(GMT+01:00) Paris, Tunis, Algiers" },
    { v: 120,  ar: "(GMT+02:00) القاهرة، بيروت، دمشق",  en: "(GMT+02:00) Cairo, Beirut, Damascus" },
    { v: 180,  ar: "(GMT+03:00) الرياض، الكويت، إسطنبول",en: "(GMT+03:00) Riyadh, Kuwait, Istanbul" },
    { v: 210,  ar: "(GMT+03:30) طهران",                 en: "(GMT+03:30) Tehran" },
    { v: 240,  ar: "(GMT+04:00) دبي، مسقط",             en: "(GMT+04:00) Dubai, Muscat" },
    { v: 300,  ar: "(GMT+05:00) كراتشي",                en: "(GMT+05:00) Karachi" },
    { v: 330,  ar: "(GMT+05:30) مومباي، نيودلهي",       en: "(GMT+05:30) Mumbai, New Delhi" },
    { v: 420,  ar: "(GMT+07:00) جاكرتا، بانكوك",        en: "(GMT+07:00) Jakarta, Bangkok" },
    { v: 480,  ar: "(GMT+08:00) سنغافورة، بكين",        en: "(GMT+08:00) Singapore, Beijing" },
    { v: 540,  ar: "(GMT+09:00) طوكيو، سيول",           en: "(GMT+09:00) Tokyo, Seoul" },
    { v: -60,  ar: "(GMT−01:00) الأزور",                en: "(GMT−01:00) Azores" },
    { v: -180, ar: "(GMT−03:00) بوينس آيرس",            en: "(GMT−03:00) Buenos Aires" },
    { v: -300, ar: "(GMT−05:00) نيويورك، تورنتو",       en: "(GMT−05:00) New York, Toronto" },
    { v: -360, ar: "(GMT−06:00) مكسيكو سيتي، شيكاغو",   en: "(GMT−06:00) Mexico City, Chicago" },
    { v: -480, ar: "(GMT−08:00) لوس أنجلوس",            en: "(GMT−08:00) Los Angeles" },
  ];

  const MONTHS_AR = ["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"];
  // Best-effort IANA timezone → standard GMT-offset minutes (user can
  // still adjust via the TZ dropdown for DST-era births).
  const TZ_FROM_NAME = {
    "Africa/Cairo": 120, "Africa/Casablanca": 60, "Africa/Tunis": 60, "Africa/Algiers": 60,
    "Africa/Khartoum": 120, "Africa/Tripoli": 120,
    "Asia/Riyadh": 180, "Asia/Kuwait": 180, "Asia/Qatar": 180, "Asia/Bahrain": 180,
    "Asia/Dubai": 240, "Asia/Muscat": 240, "Asia/Baghdad": 180, "Asia/Amman": 120,
    "Asia/Beirut": 120, "Asia/Damascus": 120, "Asia/Jerusalem": 120, "Asia/Tehran": 210,
    "Asia/Karachi": 300, "Asia/Kolkata": 330, "Asia/Dhaka": 360, "Asia/Jakarta": 420,
    "Asia/Bangkok": 420, "Asia/Singapore": 480, "Asia/Shanghai": 480, "Asia/Tokyo": 540,
    "Asia/Seoul": 540, "Europe/Istanbul": 180, "Europe/London": 0, "Europe/Paris": 60,
    "Europe/Berlin": 60, "Europe/Madrid": 60, "Europe/Rome": 60, "Europe/Moscow": 180,
    "America/New_York": -300, "America/Toronto": -300, "America/Chicago": -360,
    "America/Denver": -420, "America/Los_Angeles": -480, "America/Mexico_City": -360,
    "America/Sao_Paulo": -180, "America/Argentina/Buenos_Aires": -180, "Australia/Sydney": 600,
  };

  const MONTHS_EN = ["January","February","March","April","May","June","July","August","September","October","November","December"];

  // decorative empty bodygraph for the hero
  function HeroChart() {
    return (
      <svg className="cc-hero-bg" viewBox={window.BG_VIEWBOX || "0 0 360 530"} aria-hidden="true">
        <path d={window.BG_SILHOUETTE_PATH} fill="rgba(124,91,227,0.05)" stroke="rgba(150,130,255,0.22)" strokeWidth="1" />
        {(window.BG_CENTERS || []).map((c) => {
          // poly centers (Ego) carry pts instead of x/y/w/h
          let cx, cy, r;
          if (c.pts) {
            cx = c.pts.reduce((s, p) => s + p[0], 0) / c.pts.length;
            cy = c.pts.reduce((s, p) => s + p[1], 0) / c.pts.length;
            r = 28;
          } else {
            cx = c.x + c.w / 2; cy = c.y + c.h / 2;
            r = Math.min(c.w, c.h) / 2.6;
          }
          return <g key={c.id}>
            <circle cx={cx} cy={cy} r={r} fill="none" stroke="rgba(170,150,255,0.28)" strokeWidth="1.1" />
          </g>;
        })}
        {(window.BG_CHANNELS || []).map((ch, i) => (
          <path key={i} d={ch[2]} fill="none" stroke="rgba(120,100,200,0.13)" strokeWidth="1" />
        ))}
      </svg>
    );
  }

  window.CreateChartPage = function CreateChartPage({ lang, onRoute, param, initialInput, onSaveInput, intake = false, confirmBirth = false }) {
    const ar = lang === "ar";
    const t = I18N[lang].create_chart;
    const now = new Date();

    // Edit mode: #/create/<id> prefills from an existing saved chart and
    // updates it in place (same id) instead of creating a new one.
    const editId = param || null;
    const editRec = editId && window.ChartStore ? ChartStore.getChart(editId) : null;
    const ein = initialInput || editRec?.input || null;
    const e_local = ein && ein.year ? null : null;

    const [nameAr, setNameAr] = useState(ein ? (ein.nameAr || (isArabicStr(ein.name) ? ein.name : "") || "") : "");
    const [nameEn, setNameEn] = useState(ein ? (ein.nameEn || (!isArabicStr(ein.name) ? ein.name : "") || "") : "");
    const [year, setYear] = useState(ein ? String(ein.year || "") : "");
    const [month, setMonth] = useState(ein ? String(ein.month || "") : "");
    const [day, setDay] = useState(ein ? String(ein.day || "") : "");
    const [unknownTime, setUnknownTime] = useState(ein ? !!ein.unknownTime : false);
    const [hour, setHour] = useState(ein && !ein.unknownTime ? String(((ein.hour % 12) || 12)) : "");
    const [minute, setMinute] = useState(ein && !ein.unknownTime ? String(ein.minute || 0) : "");
    const [ampm, setAmpm] = useState(ein && ein.hour >= 12 ? "pm" : "am");
    const [tz, setTz] = useState(ein ? (ein.tzOffsetMinutes != null ? ein.tzOffsetMinutes : 180) : 180);
    const [err, setErr] = useState("");
    const [busy, setBusy] = useState(false);
    const [confirmed, setConfirmed] = useState(false);

    // ── Place: live geocoding search (Open-Meteo, no key, worldwide) ──
    const [place, setPlace] = useState(ein ? { lat: ein.lat, lng: ein.lng, ar: ein.placeAr, en: ein.placeEn, tzName: ein.tzName } : null);
    const [manualOffset, setManualOffset] = useState(ein?.manualOffset ?? Boolean(ein && !ein.tzName));
    const [query, setQuery] = useState(ein ? (ar ? (ein.placeAr || ein.placeEn || "") : (ein.placeEn || ein.placeAr || "")) : "");
    const [results, setResults] = useState([]);
    const [searching, setSearching] = useState(false);
    const [openList, setOpenList] = useState(false);
    const cityCache = React.useRef(new Map());

    const months = ar ? MONTHS_AR : MONTHS_EN;
    const years = useMemo(() => { const a = []; for (let y = now.getFullYear(); y >= 1920; y--) a.push(y); return a; }, []);
    const days = useMemo(() => { const a = []; for (let d = 1; d <= 31; d++) a.push(d); return a; }, []);

    // Debounced worldwide city search via Open-Meteo geocoding API.
    React.useEffect(() => {
      const q = query.trim();
      if (q.length < 2 || (place && q === (ar ? (place.ar || place.en) : (place.en || place.ar)))) {
        setResults([]);
        setSearching(false);
        return;
      }
      const lng = ar ? "ar" : "en";
      const key = lng + ":" + q.toLowerCase();
      const cache = cityCache.current;
      if (cache.has(key)) {
        setResults(cache.get(key));
        setOpenList(true);
        setSearching(false);
        return;
      }
      const controller = new AbortController();
      setResults([]);
      setSearching(true);
      const tmr = setTimeout(() => {
        fetch(`https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(q)}&count=8&language=${lng}&format=json`, { signal: controller.signal })
          .then((r) => { if (!r.ok) throw new Error("City search failed"); return r.json(); })
          .then((d) => {
            if (controller.signal.aborted) return;
            const matches = d?.results || [];
            if (cache.size >= 24) cache.delete(cache.keys().next().value);
            cache.set(key, matches);
            setResults(matches);
            setSearching(false); setOpenList(true);
          })
          .catch(() => { if (!controller.signal.aborted) { setResults([]); setSearching(false); } });
      }, 320);
      return () => { clearTimeout(tmr); controller.abort(); };
    }, [query, place, ar]);

    function offsetForTz(tzName, y, mo, d, h, mi) {
      try {
        const date = new Date(Date.UTC(y || 2000, (mo || 1) - 1, d || 1, h == null ? 12 : h, mi || 0));
        const dtf = new Intl.DateTimeFormat("en-US", { timeZone: tzName, hourCycle: "h23", year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit" });
        const m = {}; dtf.formatToParts(date).forEach((p) => { m[p.type] = p.value; });
        const asUTC = Date.UTC(+m.year, +m.month - 1, +m.day, +m.hour, +m.minute, +m.second);
        return Math.round((asUTC - date.getTime()) / 60000);
      } catch (e) { return null; }
    }

    function offsetsForBirthTime(tzName, y, mo, d, h, mi) {
      const local = Date.UTC(y, mo - 1, d, h, mi);
      const minuteMs = 60000;
      const offsetAt = (instant) => {
        const date = new Date(instant);
        return offsetForTz(tzName, date.getUTCFullYear(), date.getUTCMonth() + 1,
          date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes());
      };
      // Sample on both sides of an offset change, then keep only offsets
      // that round-trip to the requested local wall time.
      const dayMs = 24 * 60 * minuteMs;
      const candidates = new Set([offsetAt(local - dayMs), offsetAt(local), offsetAt(local + dayMs)]);
      return [...candidates].filter((offset) => offset !== null && offsetAt(local - offset * minuteMs) === offset);
    }

    function pickPlace(r) {
      const country = ar ? (r.country || "") : (r.country || "");
      const label = `${r.name}${country ? "، " + country : ""}`;
      const labelEn = `${r.name}${r.country ? ", " + r.country : ""}`;
      setPlace({ lat: r.latitude, lng: r.longitude, ar: label, en: labelEn, tzName: r.timezone || null });
      setManualOffset(false);
      setQuery(ar ? label : labelEn);
      setOpenList(false); setResults([]);
      // Auto-detect the timezone for this city, DST-aware for the birth
      // date when known. Works for EVERY city worldwide via the IANA name.
      let off = null;
      if (typeof r.timezone === "string") off = offsetForTz(r.timezone, +year, +month, +day, 12, 0);
      if (off == null && typeof r.utc_offset_seconds === "number") off = Math.round(r.utc_offset_seconds / 60);
      if (off == null && typeof r.timezone === "string" && TZ_FROM_NAME[r.timezone] != null) off = TZ_FROM_NAME[r.timezone];
      if (off != null) setTz(off);
    }

    function submit(e) {
      e.preventDefault();
      setErr("");
      const y = Number(year), mo = Number(month), d = Number(day);
      const birthDay = new Date(Date.UTC(y, mo - 1, d));
      if (!year || !month || !day || birthDay.getUTCMonth() !== mo - 1 ||
          birthDay.getUTCDate() !== d || birthDay.getTime() > Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())) {
        setErr(t.err_date); return;
      }
      if (!place || place.lat == null) { setErr(t.err_city); return; }
      if (!window.HDEngine || !HDEngine.ready()) { setErr(t.err_engine); return; }

      let h24 = 12, mn = 0;
      if (!unknownTime) {
        if (!hour || !minute) {
          setErr(ar ? "اختار الساعة والدقيقة، أو حدّد إن وقت الميلاد غير معروف." : "Select the hour and minute, or mark the birth time as unknown.");
          return;
        }
        let h = Number(hour) % 12;
        if (ampm === "pm") h += 12;
        h24 = h; mn = Number(minute);
      }
      let tzMin = tz;
      if (place.tzName) {
        const offsets = offsetsForBirthTime(place.tzName, y, mo, d, h24, mn);
        if (offsets.length === 1) {
          tzMin = offsets[0];
        } else if (offsets.length === 0) {
          setErr(ar ? "الوقت ده مش موجود بالتوقيت المحلي للمدينة. راجع وقت الميلاد." : "That local time does not exist for this city. Check the birth time.");
          return;
        } else if (!manualOffset || !offsets.includes(tz)) {
          setErr(ar ? "الساعة دي اتكررت بسبب تغيير التوقيت. اختار فرق GMT الصحيح من القائمة." : "This local time occurred twice. Select the correct GMT offset.");
          return;
        }
      } else if (!manualOffset) {
        setErr(ar ? "اختار فرق GMT لمدينة الميلاد." : "Select the GMT offset for the birth city.");
        return;
      }
      const input = {
        name: (ar ? (nameAr.trim() || nameEn.trim()) : (nameEn.trim() || nameAr.trim())),
        nameAr: nameAr.trim(), nameEn: nameEn.trim(),
        year: y, month: mo, day: d,
        hour: h24, minute: mn, unknownTime,
        tzOffsetMinutes: tzMin,
        manualOffset,
        lat: place.lat, lng: place.lng,
        placeAr: place.ar, placeEn: place.en, tzName: place.tzName || null,
      };
      setBusy(true);
      setTimeout(async () => {
        try {
          if (onSaveInput) {
            await onSaveInput(input);
            setBusy(false);
            return;
          }
          const record = editId
            ? await window.ChartStore.updateChart(editId, input)
            : await window.ChartStore.createChart(input);
          if (!record) throw new Error("Chart unavailable");
          if (editId) window.ChartStore.setActiveChart(editId);
          onRoute("overview");
        } catch (err) {
          setErr(onSaveInput ? (ar ? "تعذّر حفظ بيانات الميلاد. جرّب تاني." : "Could not save birth details. Try again.") : t.err_engine);
          setBusy(false);
        }
      }, 30);
    }

    if (busy && !intake) return <CosmicLoading lang={lang} chart />;

    return (
      <>
        {!intake && <PageHeader title={confirmBirth ? (ar ? "راجع بيانات ميلادك" : "Confirm your birth details") : editId ? t.edit_title : t.title}
          sub={confirmBirth ? (ar ? "بعد التأكيد، أي تصحيح هيحتاج الأدمن." : "After confirmation, an administrator can correct your birth details.") : t.sub} lang={lang} />}
        <div className="cc-wrap">
          <div className="cc-grid">
            {/* ── hero / explainer ── */}
            {!intake && <aside className="cc-hero card-glass">
              <div className="cc-hero-art"><HeroChart /></div>
              <div className="cc-how">
                <div className="cc-how-head"><span className="cc-how-i"><Icon.help size={13} /></span><strong>{t.how_t}</strong></div>
                <p>{t.how_b}</p>
                <div className="cc-feats">
                  <div className="cc-feat"><span><Icon.planets size={20} /></span><em>{t.f1}</em></div>
                  <div className="cc-feat"><span><Icon.lock size={20} /></span><em>{t.f2}</em></div>
                  <div className="cc-feat"><span><Icon.compass size={20} /></span><em>{t.f3}</em></div>
                </div>
              </div>
            </aside>}

            {/* ── form ── */}
            <form className="cc-form card-glass" onSubmit={submit}>
              <div className="cc-form-head"><Icon.calendar size={18} /><h2>{t.data}</h2></div>

              {!intake && !confirmBirth && <><label className="cc-field">
                <span className="cc-label">{ar ? t.name : t.name_en_l}</span>
                <span className="cc-input-wrap"><span className="cc-ic"><Icon.profile size={15} /></span>
                  <input type="text" dir="rtl" value={nameAr} onChange={(e) => setNameAr(e.target.value)} placeholder={ar ? t.name_ph : t.name_en_ph} /></span>
              </label>
              <label className="cc-field">
                <span className="cc-label">{ar ? t.name_en_l : t.name}</span>
                <span className="cc-input-wrap"><span className="cc-ic"><Icon.profile size={15} /></span>
                  <input type="text" dir="ltr" value={nameEn} onChange={(e) => setNameEn(e.target.value)} placeholder={ar ? t.name_en_ph : t.name_ph} /></span>
              </label>
              <p className="cc-hint cc-name-hint">{t.name_hint}</p></>}

              <div className="cc-field">
                <span className="cc-label">{t.dob}</span>
                <div className="cc-row3">
                  <select value={day} onChange={(e) => setDay(e.target.value)} className={day ? "" : "ph"}><option value="">{t.day}</option>{days.map((d) => <option key={d} value={d}>{d}</option>)}</select>
                  <select value={month} onChange={(e) => setMonth(e.target.value)} className={month ? "" : "ph"}><option value="">{t.month}</option>{months.map((m, i) => <option key={i} value={i + 1}>{m}</option>)}</select>
                  <select value={year} onChange={(e) => setYear(e.target.value)} className={year ? "" : "ph"}><option value="">{t.year}</option>{years.map((y) => <option key={y} value={y}>{y}</option>)}</select>
                </div>
              </div>

              <div className="cc-field">
                <div className="cc-tob-head">
                  <span className="cc-label">{t.tob}</span>
                  <button type="button" className={`cc-toggle ${unknownTime ? "on" : ""}`} onClick={() => setUnknownTime(!unknownTime)} aria-pressed={unknownTime}>
                    <span className="cc-toggle-knob" /><em>{t.unknown}</em>
                  </button>
                </div>
                <div className={`cc-row3 ${unknownTime ? "disabled" : ""}`}>
                  <select value={ampm} onChange={(e) => setAmpm(e.target.value)} disabled={unknownTime}><option value="am">{t.am}</option><option value="pm">{t.pm}</option></select>
                  <select value={minute} onChange={(e) => setMinute(e.target.value)} disabled={unknownTime} className={minute ? "" : "ph"}><option value="">{t.minute}</option>{Array.from({ length: 60 }, (_, i) => <option key={i} value={i}>{String(i).padStart(2, "0")}</option>)}</select>
                  <select value={hour} onChange={(e) => setHour(e.target.value)} disabled={unknownTime} className={hour ? "" : "ph"}><option value="">{t.hour}</option>{Array.from({ length: 12 }, (_, i) => <option key={i} value={i + 1}>{i + 1}</option>)}</select>
                </div>
                <p className="cc-hint">{unknownTime
                  ? (ar ? "الشارت هيكون تقديري على أساس الساعة 12 ظهرًا بالتوقيت المحلي." : "The chart is an estimate based on 12:00 noon local time.")
                  : t.tob_hint}</p>
              </div>

              <div className="cc-field cc-place-field">
                <span className="cc-label">{t.city}</span>
                <span className="cc-input-wrap"><span className="cc-ic"><Icon.globe size={15} /></span>
                  <input type="text" value={query} placeholder={t.city_ph} autoComplete="off"
                    onChange={(e) => { setQuery(e.target.value); setPlace(null); }}
                    onFocus={() => results.length && setOpenList(true)} />
                  {searching && <span className="cc-place-spin" />}
                </span>
                {openList && results.length > 0 && (
                  <div className="cc-place-list">
                    {results.map((r, i) => (
                      <button type="button" key={i} className="cc-place-opt" onClick={() => pickPlace(r)}>
                        <Icon.pin size={13} />
                        <span><strong>{r.name}</strong>{r.admin1 ? `، ${r.admin1}` : ""}{r.country ? ` · ${r.country}` : ""}</span>
                      </button>
                    ))}
                  </div>
                )}
              </div>

              <label className="cc-field">
                <span className="cc-label">{t.tz}</span>
                <span className="cc-input-wrap"><span className="cc-ic"><Icon.clock size={15} /></span>
                  <select value={manualOffset ? tz : ""} onChange={(e) => {
                    setManualOffset(e.target.value !== "");
                    if (e.target.value !== "") setTz(Number(e.target.value));
                  }} className="cc-sel">
                    <option value="">{ar ? "تلقائي حسب المدينة ووقت الميلاد" : "Automatic from city and birth time"}</option>
                    {!TZ_OPTS.some((o) => o.v === tz) && (
                      <option value={tz}>{`(GMT${tz >= 0 ? "+" : "−"}${String(Math.floor(Math.abs(tz) / 60)).padStart(2, "0")}:${String(Math.abs(tz) % 60).padStart(2, "0")}) ${t.tz_auto}`}</option>
                    )}
                    {TZ_OPTS.map((o) => <option key={o.v} value={o.v}>{ar ? o.ar : o.en}</option>)}
                  </select></span>
              </label>

              {err && <div className="cc-err">{err}</div>}

              <div className="cc-actions">
                {!window.ChartStore?.remote && <button type="button" className="btn-outline cc-import" onClick={() => onRoute("charts")}><Icon.download size={15} /> {t.import}</button>}
                {confirmBirth && <label className="cc-hint"><input type="checkbox" checked={confirmed} onChange={(event) => setConfirmed(event.target.checked)} /> {ar ? "راجعت تاريخ ووقت ومكان الميلاد" : "I reviewed my birth date, time and place"}</label>}
                <button type="submit" className="btn-primary cc-submit" disabled={busy || (confirmBirth && !confirmed)}>
                  {busy ? t.computing : intake ? (ar ? "كمّل للحساب" : "Continue to account")
                    : confirmBirth ? (ar ? "أكّد وافتح شارتك" : "Confirm and open my chart") : <><Icon.sparkle size={16} /> {t.submit}</>}
                </button>
              </div>
            </form>
          </div>

          <div className="cc-privacy card-glass">
            <span className="cc-privacy-i"><Icon.lock size={18} /></span>
            <div><strong>{t.privacy_t}</strong><p>{ChartStore.remote
              ? (ar ? "بنحفظ بيانات الميلاد في حسابك عشان نعرض شارتك. الأدمن يقدر يراجعها ويصحّحها عند الحاجة." : "Birth details are saved to your account for your chart. An administrator can review and correct them when needed.")
              : t.privacy_b}</p></div>
          </div>
        </div>
      </>
    );
  };
})();
