// ============================================================
// project-team-editor.jsx — Editor del team di un progetto
// FASE 1 Project Cockpit (sessione 104)
// ------------------------------------------------------------
// Componente controllato shared tra NewProjectModal step "Team" e
// ProjectDetail Overview "Sezione Team". Mostra una lista di membri come
// righe (avatar/nome + ruolo nel progetto + remove), un add-row in fondo
// con PersonaAutocomplete + select ruolo. La logica di persistence vive
// nel parent:
//  - NewProjectModal: append/remove in `f.team`, payload submit
//  - ProjectDetail:   POST/DELETE /api/projects/[id]/members live
//
// Props:
//  - members: Array<{
//      id?: string,                // memberId DB (mode 'manage')
//      personaId: string,
//      personaName?: string,       // display, opzionale
//      personaEmail?: string,
//      personaActive?: boolean,
//      roleInProject: string,      // codice (es. 'PM')
//      roleName?: string,          // label readable
//      notes?: string|null,
//      locked?: boolean,           // true → no remove (es. PM in create)
//    }>
//  - roles: Array<{code, name, isDefault?, displayOrder?, suggestedRoleIds?}>
//      suggestedRoleIds (s124) = role.id RBAC per pre-rank della ricerca persona
//  - personasFallback: Array<{id, name, email?, role?}> (riusato in PersonaAutocomplete)
//  - onAdd(member): callback append (riceve {personaId, roleInProject})
//  - onRemove(member): callback (riceve l'oggetto member, identifica via .id o .personaId+.roleInProject)
//  - onRoleChange?(member, newRole): opzionale, attivato dall'editor inline
//  - disabled?: boolean              — read-only mode (no add/remove)
//  - emptyHint?: string              — testo mostrato se la lista è vuota
// ============================================================

function ProjectTeamEditor({
  members = [],
  roles = [],
  personasFallback = [],
  onAdd,
  onRemove,
  onRoleChange,
  disabled = false,
  emptyHint = 'Nessun membro nel team — aggiungi sotto.',
}) {
  const [newPersonaId, setNewPersonaId] = React.useState(null);
  const [newRoleCode, setNewRoleCode] = React.useState('');

  // Default role = isDefault==true se presente, altrimenti PM, altrimenti primo
  React.useEffect(() => {
    if (newRoleCode || roles.length === 0) return;
    const def = roles.find((r) => r.isDefault) || roles.find((r) => r.code === 'PM') || roles[0];
    if (def) setNewRoleCode(def.code);
  }, [roles, newRoleCode]);

  // PersonaAutocomplete exclude: persone già nel team (evita doppi)
  const excludeIds = React.useMemo(
    () => Array.from(new Set(members.map((m) => m.personaId))),
    [members],
  );

  const sortedRoles = React.useMemo(
    () => [...roles].sort((a, b) => (a.displayOrder ?? 0) - (b.displayOrder ?? 0) || a.code.localeCompare(b.code)),
    [roles],
  );

  const roleNameByCode = React.useMemo(() => {
    const m = new Map();
    for (const r of roles) m.set(r.code, r.name);
    return m;
  }, [roles]);

  // s133 — HARD filter per ruolo: i suggestedRoleIds del ruolo di progetto selezionato
  // restringono il pool a SOLO le persone con uno di quei ruoli RBAC. Se il
  // project_role non ha `suggestedRoleIds` configurati (array vuoto), no filter:
  // l'utente può scegliere chiunque (degradazione morbida).
  const filterRoleIds = React.useMemo(() => {
    const r = roles.find((x) => x.code === newRoleCode);
    return Array.isArray(r?.suggestedRoleIds) ? r.suggestedRoleIds : [];
  }, [roles, newRoleCode]);

  // s133 — Quando l'utente cambia ruolo, resetta la persona selezionata: il pool
  // di candidati è cambiato e la persona precedente potrebbe non essere più valida.
  React.useEffect(() => {
    setNewPersonaId(null);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [newRoleCode]);

  const handleAdd = () => {
    if (!newPersonaId || !newRoleCode || disabled) return;
    onAdd?.({ personaId: newPersonaId, roleInProject: newRoleCode });
    setNewPersonaId(null);
  };

  const initials = (name) => {
    if (!name) return '·';
    return name
      .split(/\s+/)
      .map((p) => p[0])
      .slice(0, 2)
      .join('')
      .toUpperCase();
  };

  return (
    <div className="project-team-editor">
      <div style={{ border: '1px solid var(--line)', borderRadius: 8, overflow: 'hidden' }}>
        {members.length === 0 ? (
          <div style={{ padding: 14, fontSize: 12, color: 'var(--text-3)', textAlign: 'center' }}>
            {emptyHint}
          </div>
        ) : (
          <div>
            {members.map((m, idx) => {
              const key = m.id || `${m.personaId}-${m.roleInProject}-${idx}`;
              const name = m.personaName
                || personasFallback.find((p) => p.id === m.personaId)?.name
                || m.personaId;
              const email = m.personaEmail
                || personasFallback.find((p) => p.id === m.personaId)?.email
                || null;
              const roleLabel = m.roleName || roleNameByCode.get(m.roleInProject) || m.roleInProject;
              const isInactive = m.personaActive === false;
              return (
                <div
                  key={key}
                  className="row"
                  style={{
                    gap: 10,
                    padding: '8px 12px',
                    borderBottom: idx === members.length - 1 ? 'none' : '1px solid var(--line)',
                    alignItems: 'center',
                    opacity: isInactive ? 0.55 : 1,
                  }}
                >
                  <div
                    style={{
                      width: 28,
                      height: 28,
                      borderRadius: '50%',
                      background: 'var(--bg-2)',
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      fontSize: 11,
                      fontWeight: 600,
                      color: 'var(--text-1)',
                      flexShrink: 0,
                    }}
                    title={m.personaId}
                  >
                    {initials(name)}
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 12.5, fontWeight: 500 }}>
                      {name}
                      {isInactive && (
                        <span style={{ marginLeft: 6, fontSize: 10, color: 'var(--warn, #c98e36)' }}>
                          🚫 disattivato
                        </span>
                      )}
                    </div>
                    {email && (
                      <div style={{ fontSize: 10.5, color: 'var(--text-3)' }}>{email}</div>
                    )}
                  </div>
                  <div style={{ minWidth: 160 }}>
                    {onRoleChange && !disabled && !m.locked ? (
                      <window.Autocomplete
                        value={m.roleInProject}
                        onChange={(v) => onRoleChange(m, v)}
                        allowClear={false}
                        options={sortedRoles.map((r) => ({ value: r.code, label: r.name, sublabel: r.code }))}
                        placeholder="Cerca ruolo…"
                        testId="team-member-role-ac"
                      />
                    ) : (
                      <Chip kind="info">{roleLabel}</Chip>
                    )}
                  </div>
                  {!disabled && (
                    <button
                      type="button"
                      className="btn ghost icon"
                      onClick={() => onRemove?.(m)}
                      disabled={m.locked}
                      title={m.locked ? 'PM derivato dal campo Project Manager dello step 1' : 'Rimuovi dal team'}
                      style={{ opacity: m.locked ? 0.4 : 1 }}
                    >
                      <Icon name="x" size={11}/>
                    </button>
                  )}
                </div>
              );
            })}
          </div>
        )}
      </div>

      {!disabled && (
        <div
          className="row"
          style={{
            gap: 8,
            marginTop: 10,
            padding: 10,
            background: 'var(--bg-2)',
            borderRadius: 8,
            border: '1px dashed var(--line)',
            alignItems: 'center',
          }}
        >
          {/* s133 — Layout: prima Ruolo (driver del filtro), poi Persona (filtrata),
              infine bottone Aggiungi. */}
          <div style={{ minWidth: 200 }}>
            <window.Autocomplete
              value={newRoleCode}
              onChange={(v) => setNewRoleCode(v)}
              allowClear={false}
              disabled={sortedRoles.length === 0}
              options={sortedRoles.map((r) => ({ value: r.code, label: r.name, sublabel: r.code }))}
              placeholder="Cerca ruolo…"
              testId="team-add-role-ac"
            />
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <PersonaAutocomplete
              value={newPersonaId}
              onChange={setNewPersonaId}
              placeholder={
                filterRoleIds.length > 0
                  ? 'Aggiungi persona al team… (filtrata per ruolo)'
                  : 'Aggiungi persona al team…'
              }
              excludeIds={excludeIds}
              personasFallback={personasFallback}
              filterRoleIds={filterRoleIds}
            />
          </div>
          <Btn
            variant="primary"
            size="sm"
            onClick={handleAdd}
            disabled={!newPersonaId || !newRoleCode}
          >
            <Icon name="plus" size={11}/> Aggiungi
          </Btn>
        </div>
      )}
    </div>
  );
}
