// api.ts から分割（挙動不変）: タスク共有リンク + 公開アプリ共有リンク。
import { BASE } from './client';
import type { LocalTask, LocalTaskComment, SubtaskActivity } from './tasks';
import type { LocalFileEntry } from './task-files';
import type { SubtaskFiles } from './subtasks';

// --- Share ---
export async function shareTask(taskId: number): Promise<{ shareToken: string; shareUrl: string }> {
  const res = await fetch(`${BASE}/local/tasks/${taskId}/share`, { method: 'POST' });
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Failed to share task');
  return data;
}

export async function unshareTask(taskId: number): Promise<void> {
  const res = await fetch(`${BASE}/local/tasks/${taskId}/share`, { method: 'DELETE' });
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Failed to unshare task');
}

export async function fetchSharedTask(token: string): Promise<LocalTask> {
  const res = await fetch(`${BASE}/shared/${token}`);
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Not found');
  return data.task;
}

export async function fetchSharedTaskComments(token: string): Promise<LocalTaskComment[]> {
  const res = await fetch(`${BASE}/shared/${token}/comments`);
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Failed to fetch comments');
  return data.comments ?? [];
}

export async function fetchSharedFiles(token: string, path: string = ''): Promise<{ basePath: string; path: string; entries: LocalFileEntry[] }> {
  const params = new URLSearchParams();
  if (path) params.set('path', path);
  const res = await fetch(`${BASE}/shared/${token}/files?${params.toString()}`);
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Failed to list files');
  return data;
}

export async function fetchSharedFileContent(token: string, path: string): Promise<string> {
  const params = new URLSearchParams({ path });
  const res = await fetch(`${BASE}/shared/${token}/files/content?${params.toString()}`);
  if (!res.ok) throw new Error('Failed to read file');
  return res.text();
}

export function getSharedFileRawUrl(token: string, path: string): string {
  const params = new URLSearchParams({ path });
  return `${BASE}/shared/${token}/files/raw?${params.toString()}`;
}

export async function fetchSharedSubtaskActivities(token: string): Promise<SubtaskActivity[]> {
  const res = await fetch(`${BASE}/shared/${token}/subtasks/activities`);
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Failed to fetch subtask activities');
  return data.subtasks ?? [];
}

// 個別サブタスク（共有・read-only）。本体の fetchSubtaskActivity / fetchSubtaskFiles の
// 共有版。TaskDataSource(shared) から使う。封じ込めはサーバ側（share-api.ts）。
export async function fetchSharedSubtaskActivity(token: string, jobId: string): Promise<string> {
  const res = await fetch(`${BASE}/shared/${encodeURIComponent(token)}/subtasks/${jobId}/activity`);
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(data?.error ?? 'Failed to fetch subtask activity');
  return data.activityLog ?? '';
}

export async function fetchSharedSubtaskFiles(token: string, jobId: string): Promise<SubtaskFiles> {
  const res = await fetch(`${BASE}/shared/${encodeURIComponent(token)}/subtasks/${jobId}/files`);
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(data?.error ?? 'Failed to fetch subtask files');
  return { files: data.files ?? [], categories: data.categories ?? {} };
}

export function sharedSubtaskFileRawUrl(token: string, jobId: string, filePath: string): string {
  return `${BASE}/shared/${encodeURIComponent(token)}/subtasks/${jobId}/files/${filePath}`;
}

// --- 公開アプリ共有リンク（read-only・認証なし） ---
// スペース内の 1 ワークスペースアプリ（apps/{app}/）をログイン不要の公開トークンで
// read-only 配信する。公開取得（/api/app-share/:token/*）は認証なし、発行/失効
// （/api/local/spaces/:id/apps/:app/share）は canManageSpace（owner/admin）が必要。
// サーバ側で apps/{app}/＋output/ にパス封じ込め。詳細は src/bridge/app-share-api.ts。

// 公開アプリのメタ。entryPath は entry HTML（apps/{app}/index.html 等）。空アプリ等で
// 見つからなければ null になりうる（呼び出し側で 404 表示）。失効/不正トークンは throw。
export async function fetchAppShareMeta(token: string): Promise<{ appName: string; entryPath: string | null }> {
  const res = await fetch(`${BASE}/app-share/${token}`);
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(data?.error ?? 'Not found');
  return data.app;
}

export async function fetchAppShareFileContent(token: string, path: string): Promise<string> {
  const params = new URLSearchParams({ path });
  const res = await fetch(`${BASE}/app-share/${token}/files/content?${params.toString()}`);
  if (!res.ok) {
    const data = await res.json().catch(() => ({}));
    throw new Error(data?.error ?? 'Failed to read file');
  }
  return res.text();
}

export async function fetchAppShareFiles(
  token: string,
  dir: string = '',
): Promise<{ basePath: string; path: string; entries: LocalFileEntry[] }> {
  const params = new URLSearchParams();
  if (dir) params.set('dir', dir);
  const qs = params.toString();
  const res = await fetch(`${BASE}/app-share/${token}/files/list${qs ? `?${qs}` : ''}`);
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(data?.error ?? 'Failed to list files');
  return data;
}

export function getAppShareRawUrl(token: string, path: string): string {
  const params = new URLSearchParams({ path });
  return `${BASE}/app-share/${token}/files/raw?${params.toString()}`;
}

// 発行/失効/取得（canManageSpace）。shareUrl は相対パス（/ui/app/:token）。表示時は
// window.location.origin を前置する。
export async function createAppShareLink(
  spaceId: string,
  app: string,
): Promise<{ token: string; shareUrl: string }> {
  const res = await fetch(`${BASE}/local/spaces/${spaceId}/apps/${encodeURIComponent(app)}/share`, {
    method: 'POST',
  });
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(data?.error ?? 'Failed to create share link');
  return data as { token: string; shareUrl: string };
}

export async function getAppShareLink(
  spaceId: string,
  app: string,
): Promise<{ token: string | null; shareUrl?: string; revokedAt?: string | null }> {
  const res = await fetch(`${BASE}/local/spaces/${spaceId}/apps/${encodeURIComponent(app)}/share`);
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(data?.error ?? 'Failed to fetch share link');
  return data as { token: string | null; shareUrl?: string; revokedAt?: string | null };
}

export async function revokeAppShareLink(spaceId: string, app: string): Promise<{ ok: true }> {
  const res = await fetch(`${BASE}/local/spaces/${spaceId}/apps/${encodeURIComponent(app)}/share`, {
    method: 'DELETE',
  });
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(data?.error ?? 'Failed to revoke share link');
  return data as { ok: true };
}
