/**
 * Integration tests — verify Appwrite backend is reachable and configured correctly.
 * These tests make real network calls; they require NUXT_PUBLIC_APPWRITE_* env vars
 * from .env.local and a live Appwrite instance.
 */
import { describe, it, expect, beforeAll } from 'vitest';
import { Client, Account, Databases, AppwriteException } from 'appwrite';

const endpoint = process.env.NUXT_PUBLIC_APPWRITE_ENDPOINT;
const projectId = process.env.NUXT_PUBLIC_APPWRITE_PROJECT_ID;

function makeClient(): Client {
  return new Client().setEndpoint(endpoint!).setProject(projectId!);
}

describe('Appwrite configuration', () => {
  it('has NUXT_PUBLIC_APPWRITE_ENDPOINT set', () => {
    expect(endpoint, 'NUXT_PUBLIC_APPWRITE_ENDPOINT is missing from .env.local').toBeTruthy();
  });

  it('has NUXT_PUBLIC_APPWRITE_PROJECT_ID set', () => {
    expect(projectId, 'NUXT_PUBLIC_APPWRITE_PROJECT_ID is missing from .env.local').toBeTruthy();
  });
});

describe('Appwrite health', () => {
  // Some Appwrite deployments restrict /health to authenticated requests (returns 401).
  // Either 200 or 401 confirms the server is reachable and responding.
  it('health endpoint is reachable', async () => {
    const res = await fetch(`${endpoint}/health`);
    expect([200, 401], `Unexpected status ${res.status} — is ${endpoint} correct?`).toContain(res.status);
  });

  it('health DB endpoint is reachable', async () => {
    const res = await fetch(`${endpoint}/health/db`);
    expect([200, 401], `Unexpected status ${res.status} — is ${endpoint} correct?`).toContain(res.status);
  });
});

describe('Appwrite account service', () => {
  let client: Client;

  beforeAll(() => {
    client = makeClient();
  });

  it('rejects unauthenticated session with 401 (not a network error)', async () => {
    const account = new Account(client);
    await expect(account.get()).rejects.toSatisfy(
      (e: unknown) => e instanceof AppwriteException && e.code === 401
    );
  });

  it('can request a magic URL token (email delivery not verified here)', async () => {
    const account = new Account(client);
    // Use a clearly synthetic address so no real user is affected.
    // A 429 (rate limit) also confirms the endpoint is reachable.
    try {
      await account.createMagicURLToken('test-probe', 'probe@example.invalid');
      // If it succeeds, the endpoint responded (unusual for a fake address but acceptable)
    } catch (e: unknown) {
      expect(e).toBeInstanceOf(AppwriteException);
      // Any AppwriteException means we reached the server
      expect((e as AppwriteException).code).not.toBe(0);
    }
  });
});

describe('Appwrite database service', () => {
  let client: Client;

  beforeAll(() => {
    client = makeClient();
  });

  it('database "bab_prod" exists (unauthenticated returns 401, not 404)', async () => {
    const db = new Databases(client);
    try {
      await db.listDocuments('bab_prod', 'boat');
      // Authenticated session — collection is readable
    } catch (e: unknown) {
      expect(e).toBeInstanceOf(AppwriteException);
      // 401 = reached DB but not authenticated; 403 = authenticated but no permission
      // Either confirms the database and collection exist
      expect((e as AppwriteException).code).not.toBe(404);
    }
  });

  // task, taskTags, skillTags are parked — not yet implemented in bab_prod
  const collections = ['boat', 'reservation', 'interval', 'intervalTemplate'];

  it.each(collections)('collection "%s" exists in bab_prod', async (collection) => {
    const db = new Databases(client);
    try {
      await db.listDocuments('bab_prod', collection);
    } catch (e: unknown) {
      expect(e).toBeInstanceOf(AppwriteException);
      expect(
        (e as AppwriteException).code,
        `Collection "${collection}" returned 404. ` +
        `Verify it exists in Appwrite dashboard under database "bab_prod" ` +
        `and that the collection ID matches exactly (case-sensitive).`
      ).not.toBe(404);
    }
  });
});
