/**
 * Global Setup - Seed the database with test users via Better Auth API
 * and insert supporting data (berths, system_settings) via direct SQL.
 *
 * This runs BEFORE any test spec via Playwright's `dependencies` config.
 */
import { test as setup } from '@playwright/test';

const BASE = 'http://localhost:3000';

// ── Test user credentials ───────────────────────────────────────────────────
export const USERS = {
  super_admin: {
    email: 'admin@portnimara.test',
    password: 'SuperAdmin12345!',
    name: 'Test Admin',
  },
  sales_agent: {
    email: 'agent@portnimara.test',
    password: 'SalesAgent12345!',
    name: 'Test Agent',
  },
  viewer: {
    email: 'viewer@portnimara.test',
    password: 'ViewerUser12345!',
    name: 'Test Viewer',
  },
};

// ── Helpers ─────────────────────────────────────────────────────────────────

/** Sign up a user via Better Auth REST API */
async function signUpUser(email: string, password: string, name: string) {
  const headers = {
    'Content-Type': 'application/json',
    Origin: BASE,
    Referer: `${BASE}/`,
  };

  const res = await fetch(`${BASE}/api/auth/sign-up/email`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ email, password, name }),
  });

  if (res.ok) {
    const data = (await res.json()) as any;
    return data.user?.id ?? data.id;
  }

  // User may already exist - try sign-in instead
  const loginRes = await fetch(`${BASE}/api/auth/sign-in/email`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ email, password }),
  });

  if (loginRes.ok) {
    const loginData = (await loginRes.json()) as any;
    return loginData.user?.id ?? loginData.id;
  }

  const errorBody = await loginRes.text().catch(() => 'no body');
  throw new Error(`Failed to create or sign in user ${email}: ${loginRes.status} ${errorBody}`);
}

/** Run raw SQL via docker psql using stdin piping */
async function runSQL(sql: string) {
  const { execSync } = await import('child_process');
  execSync(
    `docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T postgres psql -U crm -d port_nimara_crm`,
    { cwd: process.cwd(), input: sql, stdio: ['pipe', 'pipe', 'pipe'] },
  );
}

// ── Setup ───────────────────────────────────────────────────────────────────

setup('seed test database', async () => {
  setup.setTimeout(120_000);

  console.log('🔧 Creating test users via Better Auth...');

  // 1. Create users via Better Auth sign-up endpoint
  const adminId = await signUpUser(
    USERS.super_admin.email,
    USERS.super_admin.password,
    USERS.super_admin.name,
  );
  console.log(`  ✓ super_admin created: ${adminId}`);

  const agentId = await signUpUser(
    USERS.sales_agent.email,
    USERS.sales_agent.password,
    USERS.sales_agent.name,
  );
  console.log(`  ✓ sales_agent created: ${agentId}`);

  const viewerId = await signUpUser(USERS.viewer.email, USERS.viewer.password, USERS.viewer.name);
  console.log(`  ✓ viewer created: ${viewerId}`);

  // 2. Get portId and roleIds from seed data
  console.log('🔧 Linking users to port and roles...');

  // Create user_profiles + user_port_roles for each test user
  // The super_admin profile already exists from db:seed with a placeholder userId.
  // We need to update it and create profiles for agent + viewer.

  await runSQL(`
    -- Update super_admin profile to match the real auth user ID
    UPDATE user_profiles SET user_id = '${adminId}' WHERE user_id = 'super-admin-matt-portnimara';

    -- If that didn't match (profile might not exist), insert it
    INSERT INTO user_profiles (id, user_id, display_name, is_super_admin, is_active, preferences)
    VALUES (gen_random_uuid()::text, '${adminId}', 'Test Admin', true, true, '{}')
    ON CONFLICT (user_id) DO UPDATE SET is_super_admin = true, is_active = true;

    -- Create sales_agent profile
    INSERT INTO user_profiles (id, user_id, display_name, is_super_admin, is_active, preferences)
    VALUES (gen_random_uuid()::text, '${agentId}', 'Test Agent', false, true, '{}')
    ON CONFLICT (user_id) DO NOTHING;

    -- Create viewer profile
    INSERT INTO user_profiles (id, user_id, display_name, is_super_admin, is_active, preferences)
    VALUES (gen_random_uuid()::text, '${viewerId}', 'Test Viewer', false, true, '{}')
    ON CONFLICT (user_id) DO NOTHING;
  `);

  await runSQL(`
    -- Assign super_admin role to admin user
    INSERT INTO user_port_roles (id, user_id, port_id, role_id)
    SELECT gen_random_uuid()::text, '${adminId}', p.id, r.id
    FROM ports p, roles r
    WHERE p.slug = 'port-nimara' AND r.name = 'super_admin'
    ON CONFLICT DO NOTHING;

    -- Assign sales_agent role to agent user
    INSERT INTO user_port_roles (id, user_id, port_id, role_id)
    SELECT gen_random_uuid()::text, '${agentId}', p.id, r.id
    FROM ports p, roles r
    WHERE p.slug = 'port-nimara' AND r.name = 'sales_agent'
    ON CONFLICT DO NOTHING;

    -- Assign viewer role to viewer user
    INSERT INTO user_port_roles (id, user_id, port_id, role_id)
    SELECT gen_random_uuid()::text, '${viewerId}', p.id, r.id
    FROM ports p, roles r
    WHERE p.slug = 'port-nimara' AND r.name = 'viewer'
    ON CONFLICT DO NOTHING;
  `);

  console.log('  ✓ Users linked to port-nimara with correct roles');

  // 3. Seed berths for testing
  console.log('🔧 Seeding berths...');
  await runSQL(`
    INSERT INTO berths (id, port_id, mooring_number, area, status, length_ft, width_ft, price, tenure_type)
    SELECT gen_random_uuid()::text, p.id, 'A1', 'Marina A', 'available', '60', '20', '150000', 'permanent'
    FROM ports p WHERE p.slug = 'port-nimara'
    ON CONFLICT DO NOTHING;

    INSERT INTO berths (id, port_id, mooring_number, area, status, length_ft, width_ft, price, tenure_type)
    SELECT gen_random_uuid()::text, p.id, 'A2', 'Marina A', 'available', '80', '25', '250000', 'permanent'
    FROM ports p WHERE p.slug = 'port-nimara'
    ON CONFLICT DO NOTHING;

    INSERT INTO berths (id, port_id, mooring_number, area, status, length_ft, width_ft, price, tenure_type)
    SELECT gen_random_uuid()::text, p.id, 'B1', 'Marina B', 'under_offer', '45', '15', '95000', 'fixed_term'
    FROM ports p WHERE p.slug = 'port-nimara'
    ON CONFLICT DO NOTHING;
  `);
  console.log('  ✓ 3 berths seeded');

  // 4. Seed system settings
  console.log('🔧 Seeding system settings...');
  await runSQL(`
    INSERT INTO system_settings (key, value, port_id)
    SELECT 'invoice_prefix', '"INV"'::jsonb, p.id FROM ports p WHERE p.slug = 'port-nimara'
    ON CONFLICT DO NOTHING;

    INSERT INTO system_settings (key, value, port_id)
    SELECT 'default_payment_terms', '"net30"'::jsonb, p.id FROM ports p WHERE p.slug = 'port-nimara'
    ON CONFLICT DO NOTHING;
  `);
  console.log('  ✓ System settings seeded');

  console.log('✅ Global setup complete!');
});
