// ============================================================
// Workflow.jsx — vista live workflow_instance (FASE 8.UI / P3 sessione 34)
// ============================================================
//
// Sostituisce la vecchia pagina marketing-statica con:
//  - GET /api/workflow-instances (globale, filter status/entityType)
//  - Lista istanze per stato (in_progress / completed / rejected / cancelled)
//  - Detail panel con timeline step + transition (POST /api/workflow-instances/[id]/transition)
//
// L'utente vede chi sta approvando cosa, in che step, da quanto tempo.
function Workflow() {
  const { user, pushToast, navigate, seed, seedCustom } = useStore();
  const [instances, setInstances] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState(null);
  // FASE 19 — scope tabs: "tutti" (admin), "mie" (filtra by createdBy=user), "da approvare" (step.approver.roleId in user.roleIds)
  const [scope, setScope] = React.useState('todo'); // 'todo' | 'mine' | 'all'
  const [filterStatus, setFilterStatus] = React.useState('in_progress');
  const [filterEntity, setFilterEntity] = React.useState('*');
  const [sel, setSel] = React.useState(null);

  const reload = React.useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const params = new URLSearchParams();
      if (filterStatus !== '*') params.set('status', filterStatus);
      if (filterEntity !== '*') params.set('entityType', filterEntity);
      params.set('limit', '500');
      const r = await fetch('/api/workflow-instances?' + params, { credentials: 'same-origin', cache: 'no-store' });
      if (!r.ok) throw new Error('HTTP ' + r.status);
      const j = await r.json();
      setInstances(j.data || []);
    } catch (e) {
      setError(String(e?.message || e));
    } finally {
      setLoading(false);
    }
  }, [filterStatus, filterEntity]);

  React.useEffect(() => { reload(); }, [reload]);

  // FASE 19 — Filtra by scope:
  //  - 'todo'   : istanze in_progress dove lo step ATTIVO chiede un role del user
  //  - 'mine'   : istanze dove createdBy === user.id (inoltrate da me)
  //  - 'all'    : tutte (admin view, no filter)
  // FASE 16 (sessione 94) — ruoli effettivi = propri ∪ ereditati per delega attiva.
  const userRoleIds = React.useMemo(
    () => (typeof effectiveRoleIdsForUser === 'function'
      ? effectiveRoleIdsForUser(user, seedCustom?.DELEGATIONS, seed?.PERSONAS)
      : (user?.roleIds || [])),
    [user, seedCustom?.DELEGATIONS, seed?.PERSONAS],
  );
  const scopedInstances = React.useMemo(() => {
    const all = instances || [];
    if (scope === 'all') return all;
    if (scope === 'mine') {
      return all.filter((it) => it.createdBy === user?.id);
    }
    // scope === 'todo'
    return all.filter((it) => {
      if (it.status !== 'in_progress') return false;
      const current = (it.steps || []).find((s) => s.status === 'active');
      if (!current) return false;
      const approver = current.stepSnapshot?.approver;
      return approver?.kind === 'role' && userRoleIds.includes(approver.roleId);
    });
  }, [instances, scope, user?.id, userRoleIds]);

  // Counts per scope (shown in tab labels)
  const scopeCounts = React.useMemo(() => {
    const all = instances || [];
    let todo = 0, mine = 0;
    for (const it of all) {
      if (it.createdBy === user?.id) mine += 1;
      if (it.status === 'in_progress') {
        const current = (it.steps || []).find((s) => s.status === 'active');
        const approver = current?.stepSnapshot?.approver;
        if (approver?.kind === 'role' && userRoleIds.includes(approver.roleId)) todo += 1;
      }
    }
    return { todo, mine, all: all.length };
  }, [instances, user?.id, userRoleIds]);

  const stats = React.useMemo(() => {
    const all = scopedInstances;
    const byStatus = {};
    const byEntity = {};
    for (const it of all) {
      byStatus[it.status] = (byStatus[it.status] || 0) + 1;
      byEntity[it.entityType] = (byEntity[it.entityType] || 0) + 1;
    }
    return { total: all.length, byStatus, byEntity };
  }, [scopedInstances]);

  return (
    <div className="page fade-in">
      <div className="page-header">
        <div>
          <div className="eyebrow">Operations</div>
          <h1 className="page-title">Workflow CAPEX</h1>
          <div className="page-sub">Stato live di tutte le istanze di approvazione: chi sta approvando cosa, in che step, da quando. La pagina si aggiorna ad ogni navigazione.</div>
        </div>
        <div className="actions">
          <Btn variant="ghost" size="sm" onClick={reload}><Icon name="refresh" size={11}/> Aggiorna</Btn>
        </div>
      </div>

      {/* FASE 19 — Scope tabs */}
      <div style={{ display: 'flex', gap: 4, borderBottom: '1px solid var(--line)', marginBottom: 12 }}>
        {[
          { id: 'todo', label: 'Da approvare', count: scopeCounts.todo, hint: 'Step attivi che chiedono un mio ruolo' },
          { id: 'mine', label: 'Inoltrate da me', count: scopeCounts.mine, hint: 'Istanze che ho avviato' },
          { id: 'all', label: 'Tutte (admin)', count: scopeCounts.all, hint: 'Vista cross-tenant amministratore' },
        ].map((t) => (
          <button
            key={t.id}
            data-scope={t.id}
            onClick={() => setScope(t.id)}
            title={t.hint}
            style={{
              padding: '8px 14px', fontSize: 12, fontWeight: 500,
              color: scope === t.id ? 'var(--text-0)' : 'var(--text-2)',
              borderBottom: '2px solid ' + (scope === t.id ? 'var(--accent)' : 'transparent'),
              marginBottom: -1, background: 'transparent', cursor: 'pointer',
            }}
          >
            {t.label} <span className="mono" style={{ color: 'var(--text-3)', marginLeft: 4 }}>({t.count})</span>
          </button>
        ))}
      </div>

      {/* Filtri */}
      <div className="row" style={{ gap: 8, marginBottom: 12, alignItems: 'center', flexWrap: 'wrap' }}>
        <div className="row" style={{ gap: 2, background: 'var(--bg-2)', padding: 2, borderRadius: 6 }}>
          {['*', 'in_progress', 'completed', 'rejected', 'cancelled'].map((s) => (
            <button key={s} className={`btn sm ${filterStatus === s ? 'primary' : 'ghost'}`} onClick={() => setFilterStatus(s)}>
              {s === '*' ? `Tutti (${stats.total})` : `${s} ${stats.byStatus[s] ? `(${stats.byStatus[s]})` : ''}`}
            </button>
          ))}
        </div>
        <span className="spacer" />
        <div className="row" style={{ gap: 6, fontSize: 11, color: 'var(--text-2)' }}>
          <span>Entità:</span>
          <select value={filterEntity} onChange={(e) => setFilterEntity(e.target.value)} style={{ fontSize: 11.5 }}>
            <option value="*">tutte</option>
            <option value="rda">rda</option>
            <option value="vendor">vendor</option>
            <option value="project">project</option>
            <option value="progetto">progetto</option>
          </select>
        </div>
      </div>

      {loading && <div className="card"><div className="card-body">Caricamento istanze workflow…</div></div>}
      {error && <div className="card" style={{ borderColor: 'var(--err)' }}><div className="card-body" style={{ color: 'var(--err)' }}>Errore: {error}</div></div>}

      {!loading && !error && (
        <div>
          <div className="card">
            <div className="card-header">
              <div className="title">Istanze ({scopedInstances.length})</div>
              <div className="desc">Click su una riga per aprire timeline e azioni nel drawer laterale</div>
            </div>
            {scopedInstances.length === 0 ? (
              <div className="card-body" style={{ color: 'var(--text-3)', fontSize: 12.5 }}>
                Nessuna istanza per i filtri selezionati. Le istanze si creano automaticamente all'avanzamento di un'RdA o di un progetto verso uno step di approvazione.
              </div>
            ) : (
              <table className="tbl dense">
                <thead><tr>
                  <th>Entità</th>
                  <th>Workflow</th>
                  <th>Step corrente</th>
                  <th style={{ width: 110 }}>Avanzamento</th>
                  <th style={{ width: 110 }}>Avviato</th>
                  <th style={{ width: 100 }}>Stato</th>
                </tr></thead>
                <tbody>
                  {scopedInstances.map((it) => {
                    const stepsArr = it.steps || [];
                    const total = stepsArr.length;
                    const done = stepsArr.filter((s) => s.status === 'completed' || s.status === 'rejected').length;
                    const current = stepsArr.find((s) => s.status === 'active');
                    const pct = total > 0 ? Math.round((done / total) * 100) : 0;
                    const startedAt = it.startedAt ? new Date(it.startedAt).toLocaleDateString('it-IT', { day: '2-digit', month: 'short' }) : '—';
                    const isSelected = sel?.id === it.id;
                    return (
                      <tr key={it.id} className="clickable" onClick={() => setSel(it)} style={isSelected ? { background: 'color-mix(in oklch, var(--accent) 8%, var(--bg-1))' } : undefined}>
                        <td>
                          <div style={{ fontWeight: 500, fontSize: 12 }}>{it.entityId}</div>
                          <div style={{ fontSize: 10.5, color: 'var(--text-3)' }}>{it.entityType}</div>
                        </td>
                        <td style={{ fontSize: 11.5 }}>{it.workflowSnapshot?.name || it.workflowId}</td>
                        <td style={{ fontSize: 11.5 }}>
                          {current ? (
                            <>
                              <div style={{ fontWeight: 500 }}>{current.stepName}</div>
                              <div style={{ fontSize: 10.5, color: 'var(--text-3)' }}>
                                {current.stepSnapshot?.approver?.kind === 'role' ? `→ ${current.stepSnapshot.approver.roleId}` : current.stepSnapshot?.approver?.kind}
                              </div>
                            </>
                          ) : it.status === 'completed' ? <span style={{ color: 'var(--ok)' }}>tutti completati</span> : <span style={{ color: 'var(--text-3)' }}>—</span>}
                        </td>
                        <td>
                          <div className="row" style={{ gap: 6, fontSize: 11 }}>
                            <Meter value={pct} tone={it.status === 'rejected' ? 'err' : (it.status === 'completed' ? 'ok' : 'info')} />
                            <span className="num mono" style={{ fontSize: 10.5 }}>{done}/{total}</span>
                          </div>
                        </td>
                        <td className="mono" style={{ fontSize: 10.5, color: 'var(--text-3)' }}>{startedAt}</td>
                        <td>
                          <Chip kind={statusKind(it.status)} dot>{statusLabel(it.status)}</Chip>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            )}
          </div>

          {sel && (
            <WorkflowDrawer
              instance={sel}
              onClose={() => setSel(null)}
              onTransitionDone={() => { reload(); setSel(null); }}
            />
          )}
        </div>
      )}
    </div>
  );
}

function statusKind(s) {
  return s === 'completed' ? 'ok' : s === 'rejected' ? 'err' : s === 'cancelled' ? '' : 'info';
}
function statusLabel(s) {
  return ({ in_progress: 'in corso', completed: 'completato', rejected: 'rigettato', cancelled: 'annullato' }[s]) || s;
}

function WorkflowDetailPanel({ instance, onClose, onTransitionDone }) {
  const { user, pushToast, seed, seedCustom } = useStore();
  const [comment, setComment] = React.useState('');
  const [submitting, setSubmitting] = React.useState(false);
  React.useEffect(() => { setComment(''); }, [instance?.id]);

  const steps = instance.steps || [];
  const current = steps.find((s) => s.status === 'active');
  // FASE 16 (sessione 94) — ruoli effettivi = propri ∪ ereditati per delega attiva.
  const myRoleIds = typeof effectiveRoleIdsForUser === 'function'
    ? effectiveRoleIdsForUser(user, seedCustom?.DELEGATIONS, seed?.PERSONAS)
    : (user?.roleIds || []);
  const isMyTurn = current && current.stepSnapshot?.approver?.kind === 'role'
    && myRoleIds.includes(current.stepSnapshot.approver.roleId);

  async function transition(decision) {
    if (submitting || !current || instance.status !== 'in_progress') return;
    setSubmitting(true);
    try {
      const r = await fetch(`/api/workflow-instances/${encodeURIComponent(instance.id)}/transition`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-Actor-Persona-Id': user?.id || '' },
        credentials: 'same-origin',
        body: JSON.stringify({
          stepId: current.stepId,
          decision,
          comment: comment.trim() || null,
        }),
      });
      const j = await r.json().catch(() => ({}));
      if (!r.ok) throw new Error(j.error || 'HTTP ' + r.status);
      pushToast({ title: decision === 'approve' ? 'Step approvato' : 'Step rigettato', tone: 'ok' });
      onTransitionDone();
    } catch (e) {
      pushToast({ title: 'Errore transizione', desc: String(e?.message || e), tone: 'err' });
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <div className="card">
      <div className="card-header">
        <div className="title">{instance.entityId} · {instance.workflowSnapshot?.name || instance.workflowId}</div>
        <div className="actions">
          <Btn variant="ghost" size="sm" onClick={onClose}><Icon name="x" size={11}/></Btn>
        </div>
      </div>
      <div className="card-body" style={{ paddingTop: 6 }}>
        <div className="row" style={{ gap: 8, marginBottom: 10, fontSize: 11.5 }}>
          <Chip kind={statusKind(instance.status)} dot>{statusLabel(instance.status)}</Chip>
          <span style={{ color: 'var(--text-3)' }}>·</span>
          <span style={{ color: 'var(--text-2)' }}>config v <code>{instance.configVersionId || '—'}</code></span>
          <span className="spacer"/>
          <span style={{ color: 'var(--text-3)', fontFamily: 'var(--font-mono)', fontSize: 10.5 }}>{instance.id}</span>
        </div>

        {/* Timeline */}
        <div style={{ display: 'grid', gap: 8, marginBottom: 12 }}>
          {steps.map((s, idx) => {
            const tone = s.status === 'completed'
              ? (s.decision === 'reject' ? 'var(--err)' : 'var(--ok)')
              : s.status === 'active' ? 'var(--accent)'
              : s.status === 'rejected' ? 'var(--err)'
              : 'var(--line)';
            return (
              <div key={s.id} style={{ display: 'grid', gridTemplateColumns: '24px 1fr', gap: 10, alignItems: 'flex-start' }}>
                <div style={{ width: 24, height: 24, borderRadius: 12, border: `2px solid ${tone}`, display: 'grid', placeItems: 'center', fontSize: 10, fontWeight: 600, background: 'var(--bg-1)' }}>
                  {idx + 1}
                </div>
                <div style={{ flex: 1, padding: '6px 10px', border: '1px solid var(--line)', borderRadius: 6, background: s.status === 'active' ? 'color-mix(in oklch, var(--accent) 6%, var(--bg-1))' : 'var(--bg-1)' }}>
                  <div className="row" style={{ gap: 8 }}>
                    <div style={{ fontWeight: 500, fontSize: 12 }}>{s.stepName}</div>
                    <Chip kind={s.status === 'completed' ? (s.decision === 'reject' ? 'err' : 'ok') : s.status === 'active' ? 'info' : ''} dot>{s.status}</Chip>
                    {s.stepSnapshot?.slaDays && <span style={{ fontSize: 10.5, color: 'var(--text-3)' }}>SLA {s.stepSnapshot.slaDays}gg</span>}
                  </div>
                  <div style={{ fontSize: 10.5, color: 'var(--text-3)', marginTop: 2 }}>
                    Approver:{' '}
                    {s.stepSnapshot?.approver?.kind === 'role'
                      ? <code>{s.stepSnapshot.approver.roleId}</code>
                      : s.stepSnapshot?.approver?.kind}
                    {s.startedAt && <> · Avviato {new Date(s.startedAt).toLocaleString('it-IT', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' })}</>}
                    {s.completedAt && <> · Chiuso {new Date(s.completedAt).toLocaleString('it-IT', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' })}</>}
                  </div>
                  {s.decisionBy && (
                    <div style={{ fontSize: 10.5, color: s.decision === 'reject' ? 'var(--err)' : 'var(--ok)', marginTop: 2 }}>
                      <Icon name={s.decision === 'approve' ? 'check' : 'x'} size={10}/> {s.decision} da {s.decisionBy}
                      {s.decisionComment && <> — <em>"{s.decisionComment}"</em></>}
                    </div>
                  )}
                </div>
              </div>
            );
          })}
        </div>

        {/* Transition action */}
        {instance.status === 'in_progress' && current ? (
          <div style={{ padding: 10, background: 'var(--bg-2)', borderRadius: 8 }}>
            <div className="eyebrow" style={{ marginBottom: 6 }}>Decisione su step "{current.stepName}"</div>
            <div className="field" style={{ marginBottom: 8 }}>
              <textarea rows={2} placeholder="Commento (opzionale)" value={comment} onChange={(e) => setComment(e.target.value)} style={{ fontSize: 12 }}/>
            </div>
            {!isMyTurn && current.stepSnapshot?.approver?.kind === 'role' && (
              <div style={{ fontSize: 10.5, color: 'var(--warn)', marginBottom: 8 }}>
                <Icon name="info" size={10}/> Lo step richiede ruolo <code>{current.stepSnapshot.approver.roleId}</code>. Il tuo profilo ({myRoleIds.join(', ') || '—'}) potrebbe non essere abilitato.
              </div>
            )}
            <div className="row" style={{ gap: 6 }}>
              <Btn variant="primary" size="sm" disabled={submitting} onClick={() => transition('approve')}>
                <Icon name="check" size={11}/> Approva
              </Btn>
              <Btn variant="ghost" size="sm" disabled={submitting} onClick={() => transition('reject')}>
                <Icon name="x" size={11}/> Rigetta
              </Btn>
              {submitting && <span style={{ fontSize: 11, color: 'var(--text-3)' }}>Invio…</span>}
            </div>
          </div>
        ) : (
          <div style={{ fontSize: 11.5, color: 'var(--text-3)', padding: 8, background: 'var(--bg-2)', borderRadius: 6 }}>
            <Icon name="info" size={11}/> Workflow {statusLabel(instance.status)}. Nessuna azione disponibile.
          </div>
        )}
      </div>
    </div>
  );
}

// ===========================================================================
// Sessione 74 (FASE 19 residuo) — WorkflowDrawer sliding lateral.
//
// Promotion da inline-panel a drawer:
//  - Backdrop semi-trasparente (click to close)
//  - Slide-in da destra (transform animato)
//  - ESC key to close
//  - Larghezza 640px (più leggibile del 1fr/1fr precedente)
//  - Riusa WorkflowDetailPanel internamente per la timeline grafica + transition action
// ===========================================================================
function WorkflowDrawer({ instance, onClose, onTransitionDone }) {
  React.useEffect(() => {
    function onKeyDown(e) {
      if (e.key === 'Escape') onClose();
    }
    document.addEventListener('keydown', onKeyDown);
    return () => document.removeEventListener('keydown', onKeyDown);
  }, [onClose]);

  return (
    <div
      data-testid="workflow-drawer"
      style={{
        position: 'fixed',
        inset: 0,
        zIndex: 60,
        display: 'flex',
        justifyContent: 'flex-end',
      }}
    >
      {/* Backdrop click-to-close */}
      <div
        data-testid="workflow-drawer-backdrop"
        onClick={onClose}
        style={{
          position: 'absolute',
          inset: 0,
          background: 'rgba(0,0,0,0.45)',
          backdropFilter: 'blur(2px)',
        }}
      />
      {/* Panel sliding */}
      <div
        role="dialog"
        aria-label="Dettaglio istanza workflow"
        style={{
          position: 'relative',
          width: 640,
          maxWidth: '95vw',
          height: '100vh',
          background: 'var(--bg-1)',
          borderLeft: '1px solid var(--line)',
          boxShadow: '-8px 0 32px rgba(0,0,0,0.35)',
          overflowY: 'auto',
          animation: 'wfDrawerSlide 180ms ease-out',
        }}
      >
        <style>{`@keyframes wfDrawerSlide { from { transform: translateX(16px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }`}</style>
        <WorkflowDetailPanel
          instance={instance}
          onClose={onClose}
          onTransitionDone={onTransitionDone}
        />
      </div>
    </div>
  );
}

Object.assign(window, { Workflow, WorkflowDetailPanel, WorkflowDrawer });
