import { browser } from '$app/environment';
import type { CsvImportProfile, CsvImportTab } from '$lib/csv-import-session';

const VALID_PROFILES: CsvImportProfile[] = [
	'customs_brokers',
	'clients_providers',
	'exchange_rates',
	'pedimentos',
	'material_classes',
	'vehicles',
	'drivers',
	'trailers',
	'transporters',
	'part_numbers',
	'boms',
	'exportacion',
	'imports'
];

const VALID_TABS: CsvImportTab[] = ['catalogos', 'transportes', 'importacion', 'exportacion'];

export const CSV_IMPORT_PENDING_KEY = 'anexo76_csv_pending_v1';

export const CSV_IMPORT_PENDING_CHANGED = 'csvImportPendingChanged';

const MAX_ITEMS = 20;

export interface CsvImportPendingEntry {
	companyId: number;
	jobId: string;
	profile: CsvImportProfile;
	activeModelTarget: string | null;
	activeTab: CsvImportTab;
	label?: string | null;
	savedAt: string;
	totalRows?: number;
	validRows?: number;
}

interface PendingStoreV1 {
	v: 1;
	items: CsvImportPendingEntry[];
}

function notifyPendingChanged() {
	if (browser) {
		window.dispatchEvent(new CustomEvent(CSV_IMPORT_PENDING_CHANGED));
	}
}

function parseStore(raw: string | null): PendingStoreV1 {
	if (!raw) return { v: 1, items: [] };
	try {
		const data = JSON.parse(raw) as Partial<PendingStoreV1>;
		if (data.v !== 1 || !Array.isArray(data.items)) return { v: 1, items: [] };
		return { v: 1, items: data.items.filter(isValidEntry) };
	} catch {
		return { v: 1, items: [] };
	}
}

function isValidEntry(x: unknown): x is CsvImportPendingEntry {
	if (!x || typeof x !== 'object') return false;
	const o = x as Record<string, unknown>;
	return (
		typeof o.companyId === 'number' &&
		typeof o.jobId === 'string' &&
		typeof o.profile === 'string' &&
		VALID_PROFILES.includes(o.profile as CsvImportProfile) &&
		typeof o.savedAt === 'string' &&
		(o.activeModelTarget === null || typeof o.activeModelTarget === 'string') &&
		typeof o.activeTab === 'string' &&
		VALID_TABS.includes(o.activeTab as CsvImportTab)
	);
}

function writeStore(store: PendingStoreV1, notify = true) {
	if (!browser) return;
	try {
		localStorage.setItem(CSV_IMPORT_PENDING_KEY, JSON.stringify(store));
		if (notify) notifyPendingChanged();
	} catch {
		//
	}
}

export function readCsvImportPendingStore(): PendingStoreV1 {
	if (!browser) return { v: 1, items: [] };
	return parseStore(localStorage.getItem(CSV_IMPORT_PENDING_KEY));
}

export function listCsvImportPendingForCompany(companyId: number | undefined): CsvImportPendingEntry[] {
	if (companyId === undefined) return [];
	const { items } = readCsvImportPendingStore();
	return items
		.filter((i) => i.companyId === companyId)
		.sort((a, b) => (a.savedAt < b.savedAt ? 1 : -1));
}

export function countCsvImportPendingForCompany(companyId: number | undefined): number {
	return listCsvImportPendingForCompany(companyId).length;
}

/** Inserta o actualiza por jobId; mantiene como máximo MAX_ITEMS (más recientes primero). */
export function upsertCsvImportPending(partial: Omit<CsvImportPendingEntry, 'savedAt'> & { savedAt?: string }): void {
	if (!browser) return;
	const store = readCsvImportPendingStore();
	const now = partial.savedAt ?? new Date().toISOString();
	const next: CsvImportPendingEntry = {
		companyId: partial.companyId,
		jobId: partial.jobId,
		profile: partial.profile,
		activeModelTarget: partial.activeModelTarget,
		activeTab: partial.activeTab,
		savedAt: now,
		...(partial.label !== undefined && partial.label !== null && String(partial.label).trim()
			? { label: String(partial.label).trim() }
			: {}),
		...(typeof partial.totalRows === 'number' ? { totalRows: partial.totalRows } : {}),
		...(typeof partial.validRows === 'number' ? { validRows: partial.validRows } : {})
	};
	const without = store.items.filter((i) => i.jobId !== next.jobId);
	const merged = [next, ...without].sort((a, b) => (a.savedAt < b.savedAt ? 1 : -1)).slice(0, MAX_ITEMS);
	writeStore({ v: 1, items: merged });
}

export function removeCsvImportPending(jobId: string): void {
	if (!browser) return;
	const store = readCsvImportPendingStore();
	const filtered = store.items.filter((i) => i.jobId !== jobId);
	if (filtered.length === store.items.length) return;
	writeStore({ v: 1, items: filtered });
}

export function updateCsvImportPendingSnapshot(
	jobId: string,
	patch: Pick<CsvImportPendingEntry, 'totalRows' | 'validRows'>
): void {
	if (!browser) return;
	const store = readCsvImportPendingStore();
	const idx = store.items.findIndex((i) => i.jobId === jobId);
	if (idx < 0) return;
	const cur = store.items[idx];
	store.items[idx] = {
		...cur,
		...(typeof patch.totalRows === 'number' ? { totalRows: patch.totalRows } : {}),
		...(typeof patch.validRows === 'number' ? { validRows: patch.validRows } : {})
	};
	writeStore({ v: 1, items: [...store.items] }, false);
}
