// #region DatasetReviewApi [C:3] [TYPE Module] [SEMANTICS dataset, review, api, session, conflict]
// @BRIEF Dataset review session-scoped API helpers — optimistic-lock propagation, conflict detection, DTO normalization.
// @LAYER API
// @RELATION DEPENDS_ON -> [ApiModule]
// @PRE All mutations go through requestApi with X-Session-Version header when version is known.
// @POST Returns typed API responses, conflict detection booleans, or normalized session shapes.

import { requestApi } from '$lib/api';
import type { FetchOptions } from '$lib/types/api';

// #region buildDatasetReviewRequestOptions [C:2] [TYPE Function] [SEMANTICS dataset, review, headers, version]
// @BRIEF Attach optimistic-lock session version header when the current version is known.
// @PRE sessionVersion may be null when no loaded session version exists yet.
// @POST Returns requestApi-compatible options object with optional X-Session-Version header.
export function buildDatasetReviewRequestOptions(sessionVersion: string | number | null | undefined): FetchOptions {
	if (sessionVersion === null || sessionVersion === undefined || sessionVersion === '') {
		return {};
	}
	return {
		headers: {
			'X-Session-Version': String(sessionVersion),
		},
	};
}
// #endregion buildDatasetReviewRequestOptions

// #region requestDatasetReviewApi [C:2] [TYPE Function] [SEMANTICS dataset, review, mutation, proxy]
// @BRIEF Proxy dataset review mutations through requestApi with optional optimistic-lock headers.
// @PRE endpoint and method are valid requestApi inputs.
// @POST Executes requestApi with X-Session-Version only when a session version is known.
// @RELATION DEPENDS_ON -> [ApiModule.requestApi]
export function requestDatasetReviewApi<T = unknown>(
	endpoint: string,
	method: string = 'GET',
	body: unknown = null,
	sessionVersion: string | number | null = null,
): Promise<T> {
	const requestOptions = buildDatasetReviewRequestOptions(sessionVersion);
	if (requestOptions.headers) {
		return requestApi<T>(endpoint, method, body, requestOptions);
	}
	return requestApi<T>(endpoint, method, body);
}
// #endregion requestDatasetReviewApi

// #region isDatasetReviewConflictError [C:1] [TYPE Function] [SEMANTICS dataset, review, conflict]
// @BRIEF Detect optimistic-lock conflicts from dataset review mutations.
// @PRE error may be null or a normalized API error.
// @POST Returns true when the mutation failed with 409 conflict semantics.
export function isDatasetReviewConflictError(error: { status?: number } | null | undefined): boolean {
	return Number(error?.status) === 409;
}
// #endregion isDatasetReviewConflictError

// #region getDatasetReviewConflictMessage [C:1] [TYPE Function] [SEMANTICS dataset, review, conflict, message]
// @BRIEF Return user-facing 409-style guidance for stale dataset review mutations.
// @PRE error may be null or a normalized API error.
// @POST Returns a user-facing conflict message string.
export function getDatasetReviewConflictMessage(error: { message?: string } | null | undefined): string {
	return (
		error?.message ||
		'This review session changed in another action. Reload the latest session state and retry the update.'
	);
}
// #endregion getDatasetReviewConflictMessage

// #region extractDatasetReviewVersion [C:2] [TYPE Function] [SEMANTICS dataset, review, version, extraction]
// @BRIEF Resolve the latest session version from refreshed DTO fragments.
// @PRE payload may be a session summary, a detail payload, or a mutation fragment.
// @POST Returns the newest known session version or null.
// @RATIONALE Recursively walks nested session/version fields because the API response shape
//           varies between list (summary), detail (nested), and mutation (flat) endpoints.
export function extractDatasetReviewVersion(payload: Record<string, unknown> | unknown[] | null | undefined): string | number | null {
	if (!payload) {
		return null;
	}

	if (Array.isArray(payload)) {
		for (const item of payload) {
			const version = extractDatasetReviewVersion(item as Record<string, unknown>);
			if (version !== null) {
				return version;
			}
		}
		return null;
	}

	const obj = payload as Record<string, unknown>;
	if (obj.session_version !== undefined && obj.session_version !== null) {
		return obj.session_version as string | number;
	}
	if (obj.version !== undefined && obj.version !== null) {
		return obj.version as string | number;
	}
	if (obj.session) {
		return extractDatasetReviewVersion(obj.session as Record<string, unknown>);
	}

	return null;
}
// #endregion extractDatasetReviewVersion

// #region normalizeDatasetReviewDetail [C:2] [TYPE Function] [SEMANTICS dataset, review, normalize, dto]
// @BRIEF Normalize refreshed session-detail DTOs into the legacy route-friendly workspace shape.
// @PRE detail may already be legacy-flat or refreshed with nested session/session_version fields.
// @POST Returns a shape with flattened summary fields plus refreshed collections and version metadata.
export function normalizeDatasetReviewDetail<T extends Record<string, unknown> | null | undefined>(detail: T): Record<string, unknown> | null {
	if (!detail) {
		return null;
	}

	const obj = detail as Record<string, unknown>;
	if (!obj.session && obj.session_id) {
		return obj;
	}

	const summary = (obj.session || {}) as Record<string, unknown>;
	const preview = obj.preview || null;

	return {
		...summary,
		session_version:
			obj.session_version ?? summary.session_version ?? summary.version ?? null,
		version: obj.session_version ?? summary.session_version ?? summary.version ?? null,
		profile: obj.profile || null,
		findings: obj.findings || [],
		semantic_sources: obj.semantic_sources || [],
		semantic_fields: obj.semantic_fields || [],
		imported_filters: obj.filters || obj.imported_filters || [],
		template_variables: obj.template_variables || [],
		execution_mappings: obj.mappings || obj.execution_mappings || [],
		clarification: obj.clarification || null,
		clarification_sessions: obj.clarification
			? [(obj.clarification as Record<string, unknown>).clarification_session].filter(Boolean)
			: obj.clarification_sessions || [],
		previews: preview ? [preview] : obj.previews || [],
		preview,
		latest_run_context: obj.latest_run_context || null,
	};
}
// #endregion normalizeDatasetReviewDetail
// #endregion DatasetReviewApi
