import type { LocalTask } from '../api';

/**
 * スペース詳細「チャット」タブ用のフィルタ。
 * リスト API はスペースで絞り込まないため、全件を取得してクライアント側で
 * `spaceId` 一致だけを残す。新しい更新が上に来るよう updatedAt 降順で並べる。
 *
 * spec §7: `space_id` が null のタスクは個人スペースに属するものとして扱う。
 *
 * 個人スペース (`isPersonalSpace`) の判定は「個人バケツ」= legacy の null タスク、
 * または **case スペースでない `space_id`**（= 誰かの個人スペース）に属するタスク。
 * `caseSpaceIds`（= 閲覧可能な case スペースの id 集合）を渡すと、他ユーザーの
 * 個人スペース（具体 id 持ち）も個人バケツに含められる。これは admin が他ユーザーの
 * 個人ワークスペースを監視するために必要（呼び出し側で owner 絞りを併用する）。
 *
 * `caseSpaceIds` 未指定時は後方互換で「この個人スペース or null」のみを残す。
 * 個人スペースかどうかに関わらず、所有者での絞り込みは行わない（呼び出し側の責務）。
 */
export function filterTasksForSpace(
  tasks: LocalTask[],
  spaceId: string,
  isPersonalSpace = false,
  caseSpaceIds?: ReadonlySet<string>,
): LocalTask[] {
  return tasks
    .filter(t => {
      if (!isPersonalSpace) return t.spaceId === spaceId;
      if (t.spaceId == null) return true;
      if (caseSpaceIds) return !caseSpaceIds.has(t.spaceId);
      return t.spaceId === spaceId;
    })
    .sort((a, b) => (b.updatedAt ?? '').localeCompare(a.updatedAt ?? ''));
}

/**
 * 指定スペースに属し、いま実行中 (latestJob.status === 'running') のタスク件数。
 * リスト API はスペースで絞らないため、クライアント保持の全件から数える。
 *
 * **バッジの母集団は「チャット一覧で見えるタスク」と一致させる**（ずれると実態と合わない）:
 * - 案件スペース: `space_id === space.id` のみ。
 * - 個人スペース: 個人バケツ（`space_id == null` または case でない space_id = 誰かの
 *   個人スペース）を母集団とし、`filterTasksForSpace` の個人スペース判定と揃える。
 *   - 非 admin: 本人所有のみ（共有されない限り他人を数えない）。
 *   - admin: 個人バケツの全員ぶん（「他のメンバー」で監視できるものをそのまま数える）。
 *
 * `opts.caseSpaceIds`（閲覧可能な case スペースの id 集合）未指定時は後方互換で
 * 「この個人スペース or null」を母集団にする。`opts.isAdmin` 既定 false / `opts.viewerId`
 * 未指定 (no-auth 単独利用) は owner 絞りをしない。
 */
export function countRunningTasksForSpace(
  tasks: LocalTask[],
  space: { id: string; kind: 'personal' | 'case' },
  opts?: { viewerId?: string | null; isAdmin?: boolean; caseSpaceIds?: ReadonlySet<string> },
): number {
  const isPersonal = space.kind === 'personal';
  const viewerId = opts?.viewerId ?? null;
  const isAdmin = opts?.isAdmin ?? false;
  const caseSpaceIds = opts?.caseSpaceIds;
  return tasks.filter((t) => {
    if (t.latestJob?.status !== 'running') return false;
    if (!isPersonal) return t.spaceId === space.id;
    const inBucket =
      t.spaceId == null ||
      (caseSpaceIds ? !caseSpaceIds.has(t.spaceId) : t.spaceId === space.id);
    if (!inBucket) return false;
    // 個人スペース: 非adminは本人のみ。admin は監視のため個人バケツ全員を数える。
    if (!isAdmin && viewerId != null && t.ownerId !== viewerId) return false;
    return true;
  }).length;
}
