import 'dotenv/config';

declare const fetch: typeof globalThis.fetch;

export type ExcelRow = string[];
export type TableRows = {
  values: ExcelRow[];
};

function requireEnv(name: string): string {
  const val = process.env[name];
  if (!val) throw new Error(`Missing required env: ${name}`);
  return val;
}

export async function createSession(userToken: string, persist: boolean = true): Promise<string> {
  const driveId = requireEnv('DRIVE_ID');
  const itemId = requireEnv('ITEM_ID');
  const url = `https://graph.microsoft.com/v1.0/drives/${driveId}/items/${itemId}/workbook/createSession`;
  const resp = await fetch(url, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${userToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ persistChanges: persist }),
  });
  if (!(resp as any).ok) {
    const text = await (resp as any).text();
    throw new Error(`CreateSession failed: ${(resp as any).status} ${text}`);
  }
  const data = await (resp as any).json();
  return data?.id as string;
}

export async function getTableColumns(userToken: string, sessionId: string): Promise<string[]> {
  const driveId = requireEnv('DRIVE_ID');
  const itemId = requireEnv('ITEM_ID');
  const tablePath = requireEnv('EXCEL_TABLE');
  const tableName = tablePath.split('/').pop() as string;
  const url = `https://graph.microsoft.com/v1.0/drives/${driveId}/items/${itemId}/workbook/tables/${encodeURIComponent(tableName)}/columns`;
  const resp = await fetch(url, {
    method: 'GET',
    headers: {
      Authorization: `Bearer ${userToken}`,
      'workbook-session-id': sessionId,
    },
  });
  if (!(resp as any).ok) {
    const text = await (resp as any).text();
    throw new Error(`GetTableColumns failed: ${(resp as any).status} ${text}`);
  }
  const data = await (resp as any).json();
  const columns = data?.value ?? [];
  return columns.map((col: any) => col.name);
}

export async function getTableRows(userToken: string, sessionId: string): Promise<TableRows> {
  const driveId = requireEnv('DRIVE_ID');
  const itemId = requireEnv('ITEM_ID');
  const tablePath = requireEnv('EXCEL_TABLE');
  // Prefer table name; EXCEL_TABLE may include full path, but we'll assume name at the end
  const tableName = tablePath.split('/').pop() as string;
  const url = `https://graph.microsoft.com/v1.0/drives/${driveId}/items/${itemId}/workbook/tables/${encodeURIComponent(tableName)}/rows`;
  const resp = await fetch(url, {
    method: 'GET',
    headers: {
      Authorization: `Bearer ${userToken}`,
      'workbook-session-id': sessionId,
    },
  });
  if (!(resp as any).ok) {
    const text = await (resp as any).text();
    throw new Error(`GetTableRows failed: ${(resp as any).status} ${text}`);
  }
  const data = await (resp as any).json();
  // Rows come as { value: [ { index, values: [[...]] } ] } in table rows API
  // Flatten to single array of row values
  const rows: ExcelRow[] = [];
  const value = data?.value ?? [];
  for (const row of value) {
    const v = row?.values?.[0] ?? [];
    rows.push(v);
  }
  return { values: rows };
}
