/* ClientBase, page Annuaire des pros (pages-annuaire.jsx)
   --------------------------------------------------------------------------
   Annuaire public côté vitrine CLIENT. Liste les pros « actifs » qui ont
   une page de réservation publique exploitable. Permet :
   - de filtrer par activité (coiffure, esthétique, etc.) et par ville
   - de voir une fiche pro résumée + un badge « Actif »
   - de cliquer pour ouvrir directement la page publique de RDV du pro

   IMPORTANT : PAS de démo / seed local. On affiche UNIQUEMENT des pros
   réels qui répondent au critère d'activité (au moins 3 services + un
   slug public). Si la RPC n'est pas câblée OU si aucun pro n'est encore
   actif, on rend un empty state propre invitant les pros à s'inscrire.

   Source des données : window.cbSupabase.rpc("get_active_directory") (à
   câbler côté backend — voir supabase/migrations/018-active-directory.sql
   pour la définition attendue). */

// Fallback : pros RÉELS déjà inscrits qu'on liste à la main tant que
// la RPC get_active_directory n'est pas câblée. À mettre à jour quand
// les vraies infos arrivent. Vide pour l'instant — on n'ajoute un pro
// QUE quand son compte est vraiment actif (config services + connexion
// récente, voir critères ACTIVE_CRITERIA + ACTIVITY_RULE plus bas).
const REAL_PROS_FALLBACK = [];

// Règle d'activité : un compte est considéré ACTIF s'il s'est connecté
// au moins une fois dans les 14 derniers jours. INACTIF au-delà.
// Documenté ici (et plus tard via le backend) pour cohérence partout.
const ACTIVITY_RULE = {
  activeDaysMax: 14,           // ≤ 14j depuis dernière connexion = actif
  minServices:    3,           // ≥ 3 prestations configurées
  requiresVerifiedEmail: true, // email confirmé obligatoire
  requiresPublicSlug:    true, // page de RDV publique active
};

// Critères d'activité pour qu'un pro apparaisse dans l'annuaire.
// Documenté visiblement dans la section « Comment apparaître ici ? »
// en bas de page pour que les pros sachent ce qu'il faut.
const ACTIVE_CRITERIA = [
  { icon: "users",   label: "Compte vérifié",                hint: "Email confirmé" },
  { icon: "box",     label: "Au moins 3 services configurés", hint: "Vos prestations + leurs prix" },
  { icon: "link",    label: "Page de RDV publique active",    hint: "Lien clientbase.fr/?book=…" },
];

const ACTIVITY_OPTIONS = [
  { key: "all",        label: "Toutes activités" },
  { key: "coiffure",   label: "Coiffure" },
  { key: "esthetique", label: "Esthétique" },
  { key: "ongles",     label: "Beauté des ongles" },
  { key: "tatouage",   label: "Tatouage" },
  { key: "massage",    label: "Massage / bien-être" },
  { key: "sante",      label: "Santé" },
  { key: "sport",      label: "Coach sportif" },
  { key: "autre",      label: "Autre indépendant" },
];
const CITY_OPTIONS = [
  { key: "all",       label: "Toute la France" },
  { key: "paris",     label: "Paris" },
  { key: "lyon",      label: "Lyon" },
  { key: "marseille", label: "Marseille" },
  { key: "bordeaux",  label: "Bordeaux" },
  { key: "toulouse",  label: "Toulouse" },
  { key: "nantes",    label: "Nantes" },
  { key: "lille",     label: "Lille" },
  { key: "strasbourg","label": "Strasbourg" },
];

const AnnuairePage = ({ go }) => {
  const isMobile = useIsMobile(720);
  const [pros, setPros] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [activity, setActivity] = React.useState("all");
  const [city, setCity] = React.useState("all");
  const [search, setSearch] = React.useState("");

  // Fetch via Supabase RPC. Si la RPC n'existe pas / base vide / RPC
  // renvoie un tableau plus court que la liste fallback, on COMPLÈTE
  // avec REAL_PROS_FALLBACK (Julie Tugar etc.) en évitant les doublons
  // par slug. Au fil des inscriptions, les vrais pros prendront la
  // place de la liste codée en dur.
  React.useEffect(() => {
    let alive = true;
    (async () => {
      let serverPros = [];
      try {
        if (window.cbSupabase) {
          const { data, error } = await window.cbSupabase.rpc("get_active_directory");
          if (!error && Array.isArray(data)) {
            serverPros = data.map((row, i) => ({
              id: row.id || `pro-${i}`,
              name: row.name || row.business_name || "Pro",
              owner: row.owner || row.owner_name || "",
              activity: row.activity || row.activity_label || "Indépendant",
              activityKey: (row.activity_key || "").toLowerCase() || "autre",
              city: row.city || "",
              cityKey: (row.city_key || (row.city || "").toLowerCase()).replace(/\s/g, "") || "all",
              hue: row.hue ?? 280,
              slug: row.slug || row.booking_slug || "",
              bio: row.bio || "",
              photo: row.avatar || row.photo || null,
              serviceCount: row.service_count ?? null,
              joinedAt: row.created_at || null,
            }));
          }
        }
      } catch {}
      if (!alive) return;
      // Merge serverPros + fallback. Si la RPC a déjà retourné un slug
      // qu'on a en fallback, le serveur gagne (données plus fraîches).
      const serverSlugs = new Set(serverPros.map(p => p.slug));
      const merged = [
        ...serverPros,
        ...REAL_PROS_FALLBACK.filter(p => !serverSlugs.has(p.slug)),
      ];
      setPros(merged);
      setLoading(false);
    })();
    return () => { alive = false; };
  }, []);

  const filtered = React.useMemo(() => {
    const q = search.trim().toLowerCase();
    return pros.filter(p => {
      if (activity !== "all" && p.activityKey !== activity) return false;
      if (city !== "all" && p.cityKey !== city) return false;
      if (!q) return true;
      return (
        p.name.toLowerCase().includes(q)
        || (p.owner || "").toLowerCase().includes(q)
        || (p.activity || "").toLowerCase().includes(q)
        || (p.city || "").toLowerCase().includes(q)
      );
    });
  }, [pros, activity, city, search]);

  return (
    <>
      <PageHeader
        eyebrow="Annuaire"
        title="Trouvez un pro indépendant près de chez vous."
        subtitle="Tous les pros listés ici ont un compte actif, des prestations configurées et une page de RDV publique. Vous réservez en direct, sans commission."
      />

      <section style={{ padding: "8px 0 32px" }}>
        <div className="container">
          {/* Compteur + total filtré, en haut */}
          <div style={{
            display: "flex", flexWrap: "wrap", alignItems: "center",
            gap: 12, marginBottom: 20,
          }}>
            <AnnuaireProsBadge total={pros.length}/>
            <div style={{ flex: 1, minWidth: 200 }}/>
            {!loading && pros.length > 0 && (
              <div style={{ fontSize: 13, color: "var(--ink-3)" }}>
                {filtered.length} pro{filtered.length > 1 ? "s" : ""} affiché{filtered.length > 1 ? "s" : ""}
                {filtered.length !== pros.length && ` (sur ${pros.length})`}
              </div>
            )}
          </div>

          {/* Filtres — toujours visibles, même si liste vide, pour rappel
              du système. Activité + ville + search libre. */}
          <div style={{
            display: "grid", gap: 10, marginBottom: 22,
            gridTemplateColumns: isMobile ? "1fr" : "minmax(180px, 1fr) minmax(180px, 1fr) minmax(220px, 2fr)",
            padding: 14,
            background: "var(--surface)", border: "1px solid var(--line)",
            borderRadius: 12,
          }}>
            <select value={activity} onChange={e => setActivity(e.target.value)}
              style={annInputStyle}
              aria-label="Filtrer par activité">
              {ACTIVITY_OPTIONS.map(o => <option key={o.key} value={o.key}>{o.label}</option>)}
            </select>
            <select value={city} onChange={e => setCity(e.target.value)}
              style={annInputStyle}
              aria-label="Filtrer par ville">
              {CITY_OPTIONS.map(o => <option key={o.key} value={o.key}>{o.label}</option>)}
            </select>
            <input type="search" value={search}
              onChange={e => setSearch(e.target.value)}
              placeholder="Rechercher par nom, activité, ville…"
              style={annInputStyle}/>
          </div>

          {/* Grille / loader / empty state */}
          {loading ? (
            <div style={{
              display: "grid",
              gridTemplateColumns: isMobile ? "1fr" : "repeat(auto-fill, minmax(280px, 1fr))",
              gap: 14,
            }}>
              {[0, 1, 2, 3].map(i => (
                <div key={i} style={{
                  height: 220, borderRadius: 14,
                  background: "var(--bg-alt)", border: "1px solid var(--line)",
                  animation: `cbAnnSkeleton 1.4s ease-in-out ${i * 0.1}s infinite`,
                }}/>
              ))}
            </div>
          ) : pros.length === 0 ? (
            <AnnuaireEmptyState go={go}/>
          ) : filtered.length === 0 ? (
            <div style={{
              padding: 40, textAlign: "center",
              background: "var(--bg-alt)", border: "1px dashed var(--line-strong)",
              borderRadius: 14,
            }}>
              <div style={{ fontSize: 40, marginBottom: 8 }}>🔍</div>
              <div style={{ fontSize: 15, color: "var(--ink-2)", fontWeight: 540, marginBottom: 4 }}>
                Aucun pro pour ces filtres.
              </div>
              <div style={{ fontSize: 13, color: "var(--ink-4)" }}>
                Élargissez les critères ou changez de ville.
              </div>
            </div>
          ) : (
            <div style={{
              display: "grid",
              gridTemplateColumns: isMobile ? "1fr" : "repeat(auto-fill, minmax(280px, 1fr))",
              gap: 14,
            }}>
              {filtered.map(p => <AnnuaireCard key={p.id} pro={p}/>)}
            </div>
          )}

          {/* Section « Comment apparaître ici ? » : explique aux pros
              les 3 critères d'activité pour entrer dans l'annuaire.
              Toujours visible, indépendamment du nombre de pros listés. */}
          <div style={{
            marginTop: 56, padding: "28px 26px",
            background: "linear-gradient(135deg, var(--cli-soft) 0%, var(--surface) 70%)",
            border: "1px solid var(--cli-soft-2)",
            borderRadius: 18,
          }}>
            <div style={{
              display: "flex", alignItems: "center", gap: 10, marginBottom: 6,
            }}>
              <span aria-hidden style={{
                width: 32, height: 32, borderRadius: 9,
                background: "var(--cli-accent)", color: "white",
                display: "inline-flex", alignItems: "center", justifyContent: "center",
                fontSize: 16, fontWeight: 700,
              }}>?</span>
              <h3 style={{
                margin: 0, fontFamily: "var(--ff-display)", fontSize: 20, fontWeight: 600,
                letterSpacing: "-0.022em",
              }}>
                Comment apparaître dans l'annuaire ?
              </h3>
            </div>
            <p style={{
              margin: "6px 0 18px", fontSize: 14, color: "var(--ink-3)",
              lineHeight: 1.55, maxWidth: 600,
            }}>
              On préfère lister moins de pros, mais que des vrais. Pour entrer dans l'annuaire, votre compte doit cocher ces 3 cases :
            </p>
            <div style={{
              display: "grid",
              gridTemplateColumns: isMobile ? "1fr" : "repeat(3, 1fr)",
              gap: 12,
            }}>
              {ACTIVE_CRITERIA.map((c, i) => (
                <div key={c.label} style={{
                  display: "flex", alignItems: "flex-start", gap: 10,
                  padding: "12px 14px",
                  background: "var(--surface)", border: "1px solid var(--line)",
                  borderRadius: 12,
                }}>
                  <span aria-hidden style={{
                    width: 28, height: 28, borderRadius: 8, flexShrink: 0,
                    background: "var(--cli-soft)", color: "var(--cli-ink)",
                    display: "inline-flex", alignItems: "center", justifyContent: "center",
                  }}>
                    <Icon name={c.icon} size={14}/>
                  </span>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 540, color: "var(--ink)" }}>{c.label}</div>
                    <div style={{ fontSize: 11.5, color: "var(--ink-4)", marginTop: 2, lineHeight: 1.4 }}>{c.hint}</div>
                  </div>
                </div>
              ))}
            </div>
            <button onClick={() => go("signup")}
              className="btn btn-accent"
              style={{ marginTop: 18 }}>
              Créer mon compte pro
            </button>
          </div>
        </div>

        <style>{`
          @keyframes cbAnnSkeleton {
            0%, 100% { opacity: 0.5; }
            50%      { opacity: 0.8; }
          }
        `}</style>
      </section>
    </>
  );
};

// Badge compteur live « X pros actifs sur ClientBase ». Comme on n'a pas
// encore de RPC qui retourne le compte des pros ACTIFS (vs tous les pros),
// on utilise le total fourni par la page (length du fetch). Si ça vaut 0,
// on cache le badge — pas d'embarras.
const AnnuaireProsBadge = ({ total }) => {
  if (!total || total <= 0) return null;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 7,
      padding: "5px 12px 5px 10px",
      background: "var(--surface)",
      border: "1px solid color-mix(in oklab, var(--cli-accent) 32%, var(--line))",
      borderRadius: 999,
      fontSize: 12.5, fontWeight: 540,
      color: "var(--cli-accent)",
      fontVariantNumeric: "tabular-nums",
    }}>
      <span aria-hidden style={{
        width: 7, height: 7, borderRadius: 50, background: "var(--cli-accent)",
        animation: "cbPulse 1.8s ease-in-out infinite",
      }}/>
      <strong style={{ fontWeight: 700, color: "var(--cli-accent)" }}>{total}</strong>
      pro{total > 1 ? "s" : ""} actif{total > 1 ? "s" : ""}
    </span>
  );
};

// Empty state affiché quand AUCUN pro n'est encore actif. Pas une erreur,
// juste un message qui invite les pros à s'inscrire en premier.
const AnnuaireEmptyState = ({ go }) => (
  <div style={{
    padding: "48px 28px", textAlign: "center",
    background: "linear-gradient(135deg, var(--cli-soft) 0%, var(--surface) 60%)",
    border: "1px dashed var(--cli-soft-2)",
    borderRadius: 18,
  }}>
    <div style={{ fontSize: 56, marginBottom: 12 }}>🌱</div>
    <h3 style={{
      margin: 0, fontFamily: "var(--ff-display)", fontSize: 22, fontWeight: 600,
      letterSpacing: "-0.022em", color: "var(--ink)",
    }}>
      Bientôt nos premiers pros actifs.
    </h3>
    <p style={{
      margin: "10px auto 18px", maxWidth: 480,
      fontSize: 14, color: "var(--ink-3)", lineHeight: 1.55,
    }}>
      ClientBase est en bêta. Pour ne lister que des comptes qui marchent vraiment, on attend que les premiers pros aient configuré leurs services et leur page de RDV publique. Ça arrivera très vite.
    </p>
    <button onClick={() => go("signup")}
      className="btn btn-lg"
      style={{
        background: "var(--cli-accent)", color: "#fff", border: "none",
        boxShadow: "0 8px 22px -10px var(--cli-accent)",
      }}>
      Je suis pro · m'inscrire
    </button>
  </div>
);

const annInputStyle = {
  width: "100%", padding: "10px 14px",
  background: "var(--bg)", border: "1px solid var(--line)",
  borderRadius: 9, fontSize: 14, fontFamily: "inherit", color: "var(--ink)",
  outline: "none",
};

const AnnuaireCard = ({ pro }) => {
  const [hover, setHover] = React.useState(false);
  const initials = (pro.owner || pro.name).split(/\s+/).map(s => s[0]).slice(0, 2).join("").toUpperCase();
  const openBooking = () => {
    if (!pro.slug) return;
    try { window.location.href = `/?book=${encodeURIComponent(pro.slug)}`; } catch {}
  };
  return (
    <div
      onClick={openBooking}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        padding: 18,
        background: "var(--surface)", border: "1px solid var(--line)",
        borderRadius: 14,
        cursor: pro.slug ? "pointer" : "default",
        transform: hover ? "translateY(-3px)" : "translateY(0)",
        boxShadow: hover
          ? "0 18px 36px -20px color-mix(in oklab, var(--cli-accent) 50%, transparent), var(--sh-2)"
          : "var(--sh-1)",
        transition: "transform .22s cubic-bezier(.22,1,.36,1), box-shadow .22s ease, border-color .22s ease",
        display: "flex", flexDirection: "column", gap: 12,
        position: "relative",
      }}>
      {/* Badge « Actif » discret en haut à droite — preuve que le pro
          coche les critères d'activité (3+ services, slug public). */}
      <span style={{
        position: "absolute", top: 12, right: 12,
        display: "inline-flex", alignItems: "center", gap: 4,
        padding: "2px 8px 2px 6px",
        background: "var(--sage-soft)", color: "var(--sage-ink, oklch(38% 0.10 160))",
        border: "1px solid color-mix(in oklab, var(--sage) 30%, transparent)",
        borderRadius: 999, fontSize: 10.5, fontWeight: 600,
        letterSpacing: "0.04em", textTransform: "uppercase",
      }}>
        <span aria-hidden style={{ width: 5, height: 5, borderRadius: 50, background: "var(--sage)" }}/>
        Actif
      </span>

      {/* Header : avatar coloré + nom + ville */}
      <div style={{ display: "flex", alignItems: "center", gap: 12, paddingRight: 60 }}>
        <div style={{
          width: 48, height: 48, borderRadius: 12, flexShrink: 0,
          background: pro.photo
            ? `url(${pro.photo}) center/cover`
            : `linear-gradient(135deg, oklch(78% 0.14 ${pro.hue}), oklch(60% 0.20 ${(pro.hue + 30) % 360}))`,
          color: "#fff",
          display: "flex", alignItems: "center", justifyContent: "center",
          fontFamily: "var(--ff-display)", fontWeight: 600, fontSize: 18,
        }}>
          {!pro.photo && initials}
        </div>
        <div style={{ minWidth: 0, flex: 1 }}>
          <div style={{
            fontFamily: "var(--ff-display)", fontWeight: 600, fontSize: 16,
            color: "var(--ink)", letterSpacing: "-0.015em",
            whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
          }}>{pro.name}</div>
          <div style={{
            fontSize: 12, color: "var(--ink-4)", marginTop: 2,
            display: "flex", alignItems: "center", gap: 6,
          }}>
            {pro.activity} {pro.city ? `· ${pro.city}` : ""}
          </div>
        </div>
      </div>

      {/* Bio */}
      {pro.bio && (
        <div style={{
          fontSize: 13, color: "var(--ink-3)", lineHeight: 1.5,
          display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical",
          overflow: "hidden",
        }}>
          {pro.bio}
        </div>
      )}

      {/* Footer : nombre de services (si dispo) + CTA Réserver */}
      <div style={{
        display: "flex", alignItems: "center", justifyContent: "space-between",
        gap: 10, marginTop: 4,
      }}>
        {pro.serviceCount != null ? (
          <div style={{
            display: "inline-flex", alignItems: "center", gap: 5,
            fontSize: 11.5, color: "var(--ink-4)",
          }}>
            <Icon name="box" size={11}/>
            {pro.serviceCount} prestation{pro.serviceCount > 1 ? "s" : ""}
          </div>
        ) : (
          <div/>
        )}
        <span style={{
          display: "inline-flex", alignItems: "center", gap: 5,
          fontSize: 12.5, color: "var(--cli-ink)", fontWeight: 540,
          transform: hover ? "translateX(3px)" : "translateX(0)",
          transition: "transform .2s ease",
        }}>
          Réserver <Icon name="arrow" size={11}/>
        </span>
      </div>
    </div>
  );
};

if (typeof window !== "undefined") {
  window.AnnuairePage = AnnuairePage;
}
