/**
 * API Client — Canifa Note (Memos backend)
 * Uses Memos access-token for auth
 */

// Default API base URL
const DEFAULT_API_BASE_URL = 'http://172.16.2.210:5230';

// ========== Config ==========

async function getApiBase(): Promise<string> {
  const result = await chrome.storage.local.get(['apiBaseUrl']);
  const baseUrl = result.apiBaseUrl || DEFAULT_API_BASE_URL;
  return `${baseUrl}/api/v1`;
}

export async function getApiBaseUrl(): Promise<string> {
  const result = await chrome.storage.local.get(['apiBaseUrl']);
  return result.apiBaseUrl || DEFAULT_API_BASE_URL;
}

export async function setApiBaseUrl(url: string): Promise<void> {
  const cleaned = url.trim().replace(/\/+$/, '');
  if (cleaned && !cleaned.startsWith('http://') && !cleaned.startsWith('https://')) {
    throw new Error('URL must start with http:// or https://');
  }
  await chrome.storage.local.set({ apiBaseUrl: cleaned });
}

// ========== Auth ==========

async function getAuthToken(): Promise<string | null> {
  const result = await chrome.storage.local.get(['memosAccessToken', 'clerkSessionToken', 'authToken']);
  // Priority: Memos token > Clerk token > manual token
  if (result.memosAccessToken) return result.memosAccessToken;
  if (result.clerkSessionToken) return result.clerkSessionToken;
  return result.authToken || null;
}

export async function setAuthToken(token: string): Promise<void> {
  await chrome.storage.local.set({ authToken: token });
}

export async function getAuthStatus(): Promise<{ isConnected: boolean; tokenLength: number }> {
  const token = await getAuthToken();
  return {
    isConnected: !!token && token.length > 0,
    tokenLength: token?.length || 0,
  };
}

// ========== API Helpers ==========

async function apiHeaders(): Promise<Record<string, string>> {
  const token = await getAuthToken();
  const headers: Record<string, string> = { 'Content-Type': 'application/json' };
  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }
  return headers;
}

// ========== Memo CRUD ==========

export interface CreateMemoRequest {
  content: string;
  tags?: string[];
  visibility?: string;
}

export interface MemoResponse {
  id: string;
  content: string;
  tags: string[];
  created_at: string;
}

export async function createMemo(data: CreateMemoRequest): Promise<MemoResponse> {
  const apiBase = await getApiBase();
  const headers = await apiHeaders();

  const response = await fetch(`${apiBase}/memos`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      content: data.content,
      tags: data.tags || [],
      visibility: data.visibility || 'PRIVATE',
    }),
  });

  if (!response.ok) {
    await response.text();
    throw new Error(`Failed to create memo (${response.status})`);
  }

  const result = await response.json();
  return result;
}

/**
 * Create a memo using a direct token
 */
export async function createMemoWithToken(token: string, data: CreateMemoRequest): Promise<MemoResponse> {
  const apiBase = await getApiBase();

  const response = await fetch(`${apiBase}/memos`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`,
    },
    body: JSON.stringify({
      content: data.content,
      tags: data.tags || [],
      visibility: data.visibility || 'PRIVATE',
    }),
  });

  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`Failed to save (${response.status}): ${errorText.substring(0, 100)}`);
  }

  return await response.json();
}

// ========== Tags ==========

export async function fetchTags(): Promise<string[]> {
  try {
    const apiBase = await getApiBase();
    const headers = await apiHeaders();

    const response = await fetch(`${apiBase}/memos`, { headers });
    if (!response.ok) return [];

    const memos: any[] = await response.json();

    const tagSet = new Set<string>();
    for (const memo of memos) {
      if (Array.isArray(memo.tags)) {
        memo.tags.forEach((t: string) => tagSet.add(t));
      }
      const hashTags = (memo.content || '').match(/#([a-zA-Z0-9_\u00C0-\u024F\u1E00-\u1EFF]+)/g);
      if (hashTags) {
        hashTags.forEach((t: string) => tagSet.add(t.slice(1)));
      }
    }

    return Array.from(tagSet).sort();
  } catch {
    return [];
  }
}

// ========== Workspaces ==========

export interface WorkspaceItem {
  id: number;
  title: string;
  filter: string;
}

export async function fetchWorkspaces(): Promise<WorkspaceItem[]> {
  try {
    const apiBase = await getApiBase();
    const headers = await apiHeaders();

    const response = await fetch(`${apiBase}/shortcuts`, { headers });
    if (!response.ok) return [];

    const data = await response.json();
    const shortcuts = Array.isArray(data) ? data : data.shortcuts || [];
    return shortcuts.map((s: any) => ({
      id: s.id,
      title: s.title || s.name || `Workspace ${s.id}`,
      filter: s.filter || '',
    }));
  } catch {
    return [];
  }
}

// ========== Connection Test ==========

export async function testConnection(): Promise<{ ok: boolean; message: string }> {
  try {
    const apiBase = await getApiBase();
    const headers = await apiHeaders();

    const response = await fetch(`${apiBase}/memos`, {
      method: 'GET',
      headers,
      signal: AbortSignal.timeout(5000),
    });

    if (response.ok) {
      return { ok: true, message: 'Connected successfully!' };
    } else {
      return { ok: false, message: `Server error: ${response.status}` };
    }
  } catch (error) {
    return { ok: false, message: `Cannot reach server: ${(error as Error).message}` };
  }
}

// ========== Recently Used Tags (local) ==========

export async function getRecentTags(): Promise<string[]> {
  const result = await chrome.storage.local.get(['recentTags']);
  return result.recentTags || [];
}

export async function saveRecentTags(tags: string[]): Promise<void> {
  const unique = [...new Set(tags)].slice(0, 20);
  await chrome.storage.local.set({ recentTags: unique });
}
