// #region TargetSchemaHintTest [C:2] [TYPE Module] [SEMANTICS test, translate, target-schema, hint, component]
// @BRIEF Contract-focused unit tests for TargetSchemaHint.svelte component.
// @LAYER Tests
// @RELATION BINDS_TO -> [EXT:spec:TargetSchemaHint:Component]
// @TEST_CONTRACT: TargetSchemaHint -> idle, checking, complete, error UX states
// @TEST_EDGE: idle_state -> Renders button with "Check Target Schema" text
// @TEST_EDGE: button_disabled_no_table -> Button disabled when targetTable is empty
// @TEST_EDGE: button_disabled_no_database -> Button disabled when targetDatabaseId is empty
// @TEST_EDGE: checking_state -> Checking state with spinner and disabled button
// @TEST_EDGE: complete_all_present -> All columns present shows green border
// @TEST_EDGE: complete_missing_columns -> Missing columns shows yellow border
// @TEST_EDGE: error_state -> Error state shows red border
//
// NOTE: This test uses fs-based source inspection rather than @testing-library/svelte
// because the component uses Tailwind opacity modifiers (e.g., bg-green-50/50) in
// class: directives, which Svelte 5 compiler cannot parse in vitest.
// All existing component tests in this project follow the same fs pattern.

import { describe, it, expect } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';

const COMPONENT_PATH = path.resolve(
	process.cwd(),
	'src/lib/components/translate/TargetSchemaHint.svelte'
);

describe('TargetSchemaHint Component', () => {
	// #region test_component_exists [TYPE Function]
	// @PURPOSE: Verify component file exists.
	it('component file exists', () => {
		const exists = fs.existsSync(COMPONENT_PATH);
		expect(exists).toBe(true);
	});

	// #endregion test_component_exists

	// #region test_ux_state_contracts [TYPE Function]
	// @PURPOSE: Component contains required UX state tags.
	it('contains required UX state tags and contract annotations', () => {
		const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');

		expect(source).toContain('@UX_STATE Idle');
		expect(source).toContain('@UX_STATE Checking');
		expect(source).toContain('@UX_STATE Complete');
		expect(source).toContain('@UX_STATE Error');
		expect(source).toContain('@UX_FEEDBACK');
		expect(source).toContain('@UX_REACTIVITY');
		expect(source).toContain('checkTargetTableSchema');
	});

	// #endregion test_ux_state_contracts

	// #region test_props_definition [TYPE Function]
	// @PURPOSE: Component accepts required props.
	it('accepts environmentId, targetDatabaseId, targetSchema, targetTable props', () => {
		const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');

		expect(source).toContain('environmentId');
		expect(source).toContain('targetDatabaseId');
		expect(source).toContain('targetSchema');
		expect(source).toContain('targetTable');
		expect(source).toContain('targetKeyCols');
	});

	// #endregion test_props_definition

	// #region test_button_check_disabled_logic [TYPE Function]
	// @PURPOSE: Button disabled logic: canCheck derived checks all required props.
	it('has button disabled when canCheck is false', () => {
		const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');

		expect(source).toContain('disabled={!canCheck || state === \'checking\'}');
	});

	// #endregion test_button_check_disabled_logic

	// #region test_idle_state [TYPE Function]
	// @PURPOSE: Idle state shows hint text and check button.
	it('implements idle UX state with hint text', () => {
		const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');

		expect(source).toContain("state === 'idle'");
		expect(source).toContain('translate.target_schema.press_button');
	});

	// #endregion test_idle_state

	// #region test_checking_state [TYPE Function]
	// @PURPOSE: Checking state shows spinner and disables button.
	it('implements checking UX state with spinner', () => {
		const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');

		expect(source).toContain("state === 'checking'");
		expect(source).toContain('animate-spin');
		expect(source).toContain('aria-busy={state === \'checking\'');
	});

	// #endregion test_checking_state

	// #region test_complete_state [TYPE Function]
	// @PURPOSE: Complete state shows result with green/yellow/red indicators.
	it('implements complete UX state with color indicators', () => {
		const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');

		expect(source).toContain("state === 'complete'");
		expect(source).toContain('result?.all_present');
		expect(source).toContain('result?.table_exists');
		expect(source).toContain('res?.missing_columns');
	});

	// #endregion test_complete_state

	// #region test_error_state [TYPE Function]
	// @PURPOSE: Error state shows connection error message.
	it('implements error UX state with retry prompt', () => {
		const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');

		expect(source).toContain("state === 'error'");
		expect(source).toContain('translate.target_schema.check_error');
	});

	// #endregion test_error_state

	// #region test_i18n_usage [TYPE Function]
	// @PURPOSE: Component uses i18n _() for all user-facing strings with fallbacks.
	it('uses i18n for all user-facing strings', () => {
		const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');

		expect(source).toContain("_('translate.target_schema.title')");
		expect(source).toContain("_('translate.target_schema.check_button')");
		expect(source).toContain("_('translate.target_schema.checking')");
		expect(source).toContain("_('translate.target_schema.check_again')");
		expect(source).toContain("_('translate.target_schema.all_present')");
		expect(source).toContain("_('translate.target_schema.table_not_found')");
		expect(source).toContain("_('translate.target_schema.check_error')");
		expect(source).toContain("_('translate.target_schema.enter_table')");
		expect(source).toContain("_('translate.target_schema.select_database')");
		expect(source).toContain("_('translate.target_schema.missing_columns_title')");
		expect(source).toContain("_('translate.target_schema.expected_columns')");
		expect(source).toContain("_('translate.target_schema.add_columns')");
	});

	// #endregion test_i18n_usage

	// #region test_abort_controller [TYPE Function]
	// @PURPOSE: Component uses AbortController for request cancellation.
	it('implements AbortController for request cancellation', () => {
		const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');

		expect(source).toContain('AbortController');
		expect(source).toContain('abortController.abort()');
		expect(source).toContain('signal.aborted');
	});

	// #endregion test_abort_controller
});
// #endregion TargetSchemaHintTest
