/**
 * D-series: /collective/manage → dissolve (Fase 10.3, CU-H08).
 *
 * ⚠️ This suite must NOT dissolve the seed collective. We create an auxiliary
 * collective per test, manipulate it, then either let the test dissolve it
 * (D-01) or clean it up in afterEach.
 */
import { test, expect } from '@playwright/test';
import { USERS } from '../fixtures/users.js';
import { loginAs } from '../fixtures/login.js';
import { closePool, sql } from '@colectivo/test-utils';

test.describe.configure({ mode: 'serial' });

const aux: { id: string | null } = { id: null };
const auxName = `Aux dissolve ${Date.now()}`;

/**
 * Create an auxiliary collective owned (created_by) by Borja but with Ana
 * as the sole admin (Borja is dropped from membership). This lets Ana
 * dissolve it from the UI without touching the seed.
 */
async function createAuxCollective(): Promise<string> {
	const r = await sql(
		`INSERT INTO public.collectives (name, emoji, created_by)
		 VALUES ($1, '💥', $2) RETURNING id`,
		[auxName, USERS.borja.id]
	);
	const id = r.rows[0].id as string;
	await sql(
		`INSERT INTO public.collective_members (collective_id, user_id, role)
		 VALUES ($1, $2, 'admin'), ($1, $3, 'member')`,
		[id, USERS.ana.id, USERS.borja.id]
	);
	return id;
}

test.describe('Dissolve collective (CU-H08)', () => {
	test.afterEach(async () => {
		if (aux.id) {
			// Best-effort cleanup if the test didn't dissolve it.
			await sql('DELETE FROM public.collectives WHERE id = $1', [aux.id]);
			aux.id = null;
		}
	});

	test.afterAll(async () => {
		await closePool();
	});

	test('D-03: Borja (member) does NOT see the dissolve button', async ({ page }) => {
		aux.id = await createAuxCollective();
		await loginAs(page, USERS.borja);
		// Switch active collective to the aux one in localStorage, then reload.
		await page.evaluate((id) => localStorage.setItem('activeCollectiveId', id), aux.id);
		await page.goto('/collective/manage');
		// Make sure the page is hydrated by waiting on a known member row.
		await expect(page.getByTestId(`member-row-${USERS.ana.id}`)).toBeVisible({ timeout: 15_000 });
		// Borja must not see the dissolve button (admin-gated).
		await expect(page.getByTestId('dissolve-collective-button')).toHaveCount(0);
	});

	test('D-02: dissolve button disabled until input matches collective name exactly', async ({
		page
	}) => {
		aux.id = await createAuxCollective();
		await loginAs(page, USERS.ana);
		await page.evaluate((id) => localStorage.setItem('activeCollectiveId', id), aux.id);
		await page.goto('/collective/manage');
		await page.getByTestId('dissolve-collective-button').click();

		const confirm = page.getByTestId('dissolve-confirm-button');
		await expect(confirm).toBeDisabled();

		await page.getByTestId('dissolve-confirm-input').fill('wrong name');
		await expect(confirm).toBeDisabled();

		await page.getByTestId('dissolve-confirm-input').fill(auxName);
		await expect(confirm).toBeEnabled();
	});

	test('D-01: Ana dissolves auxiliary collective → redirect + row gone', async ({ page }) => {
		aux.id = await createAuxCollective();
		await loginAs(page, USERS.ana);
		await page.evaluate((id) => localStorage.setItem('activeCollectiveId', id), aux.id);
		await page.goto('/collective/manage');
		await page.getByTestId('dissolve-collective-button').click();

		await page.getByTestId('dissolve-confirm-input').fill(auxName);
		await page.getByTestId('dissolve-confirm-button').click();

		// After dissolve we either land on /lists (other collectives remain) or
		// /onboarding (no collectives). Ana still has the seed one, so /lists.
		await expect(page).toHaveURL(/\/(lists|onboarding)$/, { timeout: 15_000 });

		const r = await sql('SELECT count(*)::int AS n FROM public.collectives WHERE id = $1', [
			aux.id
		]);
		expect(r.rows[0].n).toBe(0);
		// Test cleanup already happened via cascade.
		aux.id = null;
	});
});
