import { __ } from '@wordpress/i18n';
import { getAjaxNonce } from '@admin/utilities';
import {
	type FetchSettings,
	type UpdateSettings,
	type DeleteSettings,
	type GetSubmissionCountSettings,
	type GetCSVExampleSettings,
	UPDATE_ACTION,
	FETCH_ACTION,
	DELETE_ACTION,
} from './consts';
import type {
	FieldKey,
	FieldType,
} from '@admin/sections/EditFields/FormBuilder/consts';
import { getAllPossibleFields } from '@admin/context/FormBuilderContext';

export const fetchSubmissions = async ({
	currentPage = 1,
	formID,
	perPage = 100,
	order,
	orderby,
	onSuccess = (data) => { },
}: FetchSettings) => {
	if (!formID) {
		console.error('Submission fetch error: missing the form id');
		return;
	}

	const finalQuery = new URLSearchParams();

	finalQuery.set('action', FETCH_ACTION);
	finalQuery.set('page', String(currentPage));
	finalQuery.set('form_id', String(formID));
	finalQuery.set('per_page', String(perPage));

	if (order && ['asc', 'desc'].indexOf(order) !== -1) {
		finalQuery.set('order', order);
	}

	if (orderby) {
		finalQuery.set('orderby', orderby);
	}

	finalQuery.set('petitioner_nonce', getAjaxNonce());

	try {
		const request = await fetch(`${ajaxurl}?${finalQuery.toString()}`);
		const response = await request.json();

		if (response.success) {
			onSuccess(response.data);
		} else {
			console.error('Failed to fetch data');
		}
	} catch (error) {
		console.error('Error fetching data:', error);
	}
};

export const updateSubmissions = async ({
	data,
	onSuccess = () => { },
	onError = (msg: string) => { },
}: UpdateSettings) => {
	if (!data?.id) {
		onError('Submission update error: missing the submission id');
		return;
	}

	const finalQuery = new URLSearchParams();

	finalQuery.set('action', UPDATE_ACTION);

	const finalData = new FormData();

	Object.entries(data).forEach(([key, value]) => {
		if (value !== undefined && value !== null) {
			finalData.append(key, String(value));
		}
	});

	finalData.append('petitioner_nonce', getAjaxNonce());

	try {
		const request = await fetch(`${ajaxurl}?${finalQuery.toString()}`, {
			method: 'POST',
			body: finalData,
		});

		const response = await request.json();

		if (response.success) {
			onSuccess(response.data);
		} else {
			onError('Failed to update data');
		}
	} catch (error) {
		onError('Error updating data: ' + error);
	}
};

export const deleteSubmissions = async ({
	id,
	onSuccess,
	onError,
}: DeleteSettings) => {
	if (!id) {
		onError('Submission delete error: missing the submission id');
		return;
	}

	const finalQuery = new URLSearchParams();

	finalQuery.set('action', DELETE_ACTION);

	const finalData = new FormData();

	finalData.append('id', String(id));
	finalData.append('petitioner_nonce', getAjaxNonce());

	try {
		const request = await fetch(`${ajaxurl}?${finalQuery.toString()}`, {
			method: 'POST',
			body: finalData,
		});

		const response = await request.json();

		if (response.success) {
			onSuccess();
		} else {
			onError('Failed to delete data');
		}
	} catch (error) {
		onError('Error deleting data: ' + error);
	}
};

/**
 * @deprecated Use getCSVExample instead
 */
export const getSubmissionCount = async ({
	formID,
	filters,
	onSuccess = () => { },
	onError = () => { },
}: GetSubmissionCountSettings) => {
	const finalQuery = new URLSearchParams();
	finalQuery.set('action', 'petitioner_get_submission_count');

	const finalData = new FormData();
	finalData.append('form_id', String(formID));
	finalData.append('petitioner_nonce', getAjaxNonce());

	if (filters) {
		finalData.append('conditional_logic', JSON.stringify(filters));
	}

	try {
		const request = await fetch(`${ajaxurl}?${finalQuery.toString()}`, {
			method: 'POST',
			body: finalData,
		});

		const response = await request.json();

		if (response.success) {
			onSuccess(response.data.count);
		} else {
			onError(response.message);
		}
	} catch (error) {
		onError('Error getting submission count: ' + (error as Error)?.message);
	}
};

export const getCSVExample = async ({
	formID,
	filters,
	csv_column_config,
	onSuccess = () => { },
	onError = () => { },
}: GetCSVExampleSettings) => {
	const finalQuery = new URLSearchParams();
	finalQuery.set('action', 'petitioner_get_csv_example');

	const finalData = new FormData();
	finalData.append('form_id', String(formID));
	finalData.append('petitioner_nonce', getAjaxNonce());

	if (filters) {
		finalData.append('conditional_logic', JSON.stringify(filters));
	}

	if (csv_column_config) {
		finalData.append('csv_column_config', csv_column_config);
	}

	try {
		const request = await fetch(`${ajaxurl}?${finalQuery.toString()}`, {
			method: 'POST',
			body: finalData,
		});

		if (!request.ok) {
			onError(__('HTTP error: ', 'petitioner') + request.status);
			return;
		}

		const response = await request.json();

		if (response.success) {
			onSuccess(response.data);
		} else {
			const errorMessage = response.data?.message || response.message || __('Failed to get CSV example', 'petitioner');
			onError(errorMessage);
		}
	} catch (error) {
		onError(__('Error getting CSV example: ', 'petitioner') + (error as Error)?.message);
	}
};


/**
 * Returns a mapping from fieldKey to label for all available form fields.
 */
export const getFieldLabels = (): Record<string, string> => {
	const fieldMap: Record<string, string> = {};

	const allPossibleFields = getAllPossibleFields();

	allPossibleFields.forEach((field) => {
		if (field?.fieldKey) {
			fieldMap[field.fieldKey] = field.label;
		}
	});

	return {
		...fieldMap,
		name: __('First/Last name', 'petitioner'),
		accept_tos: __('Consent', 'petitioner'),
		submitted_at: __('Submitted at', 'petitioner'),
		approval_status: __('Status', 'petitioner'),
	};
};

/**
 * Converts a given value into a human-readable string for display in submission tables.
 * - For empty/undefined/null values, returns a localized "(empty)" string.
 * - For boolean `true` or string `'1'`, returns a localized "True" string.
 * - For boolean `false` or string `'0'`, returns a localized "False" string.
 * - For all other values, returns their string representation.
 *
 * @param {string} val - The value to convert.
 * @param {string} type - the value type
 * @returns {string} Human-readable representation of the value.
 */
export const getHumanValue = (val: string, type: string): string => {
	if (val.length === 0) {
		return __('(empty)', 'petitioner');
	}

	if (type === 'checkbox') {
		return val === '1' ? '✅' : '❌';
	}

	if (type === 'date') {
		// Append time to force UTC interpretation and avoid timezone shifts
		const date = new Date(val + 'T00:00:00');

		if (!isNaN(date.getTime())) {
			return date.toLocaleDateString(undefined, {
				day: 'numeric',
				month: 'short',
				year: 'numeric',
			});
		}
	}

	return val;
};

/**
 * Returns the FieldType for a given FieldKey.
 * If the key is 'submitted_at', returns 'date'.
 * Otherwise, looks up the type from the allPossibleFields list.
 * Falls back to 'text' if the field or type is not found.
 */
export const getSubmissionValType = (label: FieldKey): FieldType => {
	if (label === 'submitted_at') {
		return 'date';
	}

	const allPossibleFields = getAllPossibleFields();

	const correctItem = allPossibleFields.find(
		(item) => item.fieldKey === label
	);

	return correctItem?.type || 'text';
};

export const getExportURL = () => {
	const urlString = String(window?.petitionerData?.export_url);

	if (urlString.length === 0) {
		console.warn('Petitioner warning: export url is not defined');
	}

	return urlString;
};
