import { getApiBaseUrl } from '$lib/api';
import { authenticatedFetch } from '$lib/auth';

// === Types ===

export interface UploadResult {
	id: string;
	filename: string;
	totalRows: number;
	columns: string[];
	detectedFormat: string;
	suggestedMapping: Record<string, string>;
	preview: PreviewRow[];
}

export interface PreviewRow {
	line: number;
	data: Record<string, string>;
	valid: boolean;
	errors: RowError[];
}

export interface RowError {
	column: string;
	message: string;
}

export interface MappingResult {
	id: string;
	mapping: Record<string, string>;
	totalRows: number;
}

export interface PreviewResult {
	id: string;
	totalRows: number;
	validCount: number;
	errorCount: number;
	rows: PreviewRow[];
	unknownSubjects: string[];
	unknownClasses: string[];
}

export interface ConfirmResult {
	id: string;
	status: string;
	message: string;
}

export interface ImportStatus {
	id: string;
	status: 'pending' | 'processing' | 'completed' | 'failed';
	totalRows: number;
	importedCount: number;
	errorCount: number;
	progression: number;
	completedAt: string | null;
}

export interface ImportReport {
	id: string;
	status: string;
	totalRows: number;
	importedCount: number;
	errorCount: number;
	report: string[];
	errors: { line: number; errors: RowError[] }[];
}

// === API Functions ===

/**
 * Upload un fichier CSV ou XLSX pour l'import d'enseignants.
 */
export async function uploadFile(file: File): Promise<UploadResult> {
	const apiUrl = getApiBaseUrl();
	const formData = new FormData();
	formData.append('file', file);

	const response = await authenticatedFetch(`${apiUrl}/import/teachers/upload`, {
		method: 'POST',
		body: formData
	});

	if (!response.ok) {
		const data = await response.json().catch(() => null);
		throw new Error(
			data?.['hydra:description'] ?? data?.message ?? data?.detail ?? "Erreur lors de l'upload"
		);
	}

	return await response.json();
}

/**
 * Applique le mapping des colonnes.
 */
export async function applyMapping(
	batchId: string,
	mapping: Record<string, string>,
	format: string
): Promise<MappingResult> {
	const apiUrl = getApiBaseUrl();
	const response = await authenticatedFetch(`${apiUrl}/import/teachers/${batchId}/mapping`, {
		method: 'POST',
		headers: { 'Content-Type': 'application/json' },
		body: JSON.stringify({ mapping, format })
	});

	if (!response.ok) {
		const data = await response.json().catch(() => null);
		throw new Error(
			data?.['hydra:description'] ?? data?.message ?? data?.detail ?? 'Erreur lors du mapping'
		);
	}

	return await response.json();
}

/**
 * Récupère la preview avec validation.
 */
export async function fetchPreview(batchId: string): Promise<PreviewResult> {
	const apiUrl = getApiBaseUrl();
	const response = await authenticatedFetch(`${apiUrl}/import/teachers/${batchId}/preview`);

	if (!response.ok) {
		throw new Error('Erreur lors de la validation');
	}

	return await response.json();
}

/**
 * Confirme et lance l'import.
 */
export async function confirmImport(
	batchId: string,
	options: { createMissingSubjects: boolean; importValidOnly: boolean; updateExisting: boolean }
): Promise<ConfirmResult> {
	const apiUrl = getApiBaseUrl();
	const response = await authenticatedFetch(`${apiUrl}/import/teachers/${batchId}/confirm`, {
		method: 'POST',
		headers: { 'Content-Type': 'application/json' },
		body: JSON.stringify(options)
	});

	if (!response.ok) {
		const data = await response.json().catch(() => null);
		throw new Error(
			data?.['hydra:description'] ??
				data?.message ??
				data?.detail ??
				'Erreur lors de la confirmation'
		);
	}

	return await response.json();
}

/**
 * Récupère le statut et la progression de l'import.
 */
export async function fetchImportStatus(batchId: string): Promise<ImportStatus> {
	const apiUrl = getApiBaseUrl();
	const response = await authenticatedFetch(`${apiUrl}/import/teachers/${batchId}/status`);

	if (!response.ok) {
		throw new Error('Erreur lors de la récupération du statut');
	}

	return await response.json();
}

/**
 * Récupère le rapport détaillé de l'import.
 */
export async function fetchImportReport(batchId: string): Promise<ImportReport> {
	const apiUrl = getApiBaseUrl();
	const response = await authenticatedFetch(`${apiUrl}/import/teachers/${batchId}/report`);

	if (!response.ok) {
		throw new Error('Erreur lors de la récupération du rapport');
	}

	return await response.json();
}
