//追加・削除・リセット

// JSON レスポンス検証用ユーティリティ関数
function validateJsonResponse(response, expectedStructure) {
	if (!response) {
		console.error('Empty response received');
		return { isValid: false, error: 'レスポンスが空です' };
	}

	// 基本的な型チェック
	if (typeof response !== 'object') {
		console.error('Response is not an object:', typeof response);
		return { isValid: false, error: 'レスポンスの形式が不正です' };
	}

	// エラーレスポンスのチェック
	if (response.error) {
		console.error('Server error:', response.error);
		return { isValid: false, error: response.error };
	}

	// 期待される構造のチェック
	if (expectedStructure) {
		for (let key in expectedStructure) {
			if (expectedStructure[key].required && !(key in response)) {
				console.error('Missing required field:', key);
				return { isValid: false, error: `必須フィールド「${key}」が見つかりません` };
			}

			if (key in response && expectedStructure[key].type) {
				let actualType = Array.isArray(response[key]) ? 'array' : typeof response[key];
				if (actualType !== expectedStructure[key].type) {
					console.error(`Type mismatch for ${key}:`, actualType, 'expected:', expectedStructure[key].type);
					return { isValid: false, error: `フィールド「${key}」の型が不正です` };
				}
			}
		}
	}

	return { isValid: true };
}

// 配列データの検証
function validateArrayData(data) {
	if (!Array.isArray(data)) {
		return { isValid: false, error: 'データが配列ではありません' };
	}

	// 配列の各要素を検証
	for (let i = 0; i < data.length; i++) {
		let item = data[i];
		
		if (!item || typeof item !== 'object') {
			return { isValid: false, error: `データ[${i}]が不正な形式です` };
		}

		// 必須フィールドの存在確認
		let requiredFields = ['name', 'label'];
		for (let field of requiredFields) {
			if (!(field in item) || typeof item[field] !== 'string') {
				return { isValid: false, error: `データ[${i}]に必須フィールド「${field}」がありません` };
			}
		}

		// 見出しレベル（h1-h6）の存在確認
		for (let j = 1; j <= 6; j++) {
			let headingKey = 'h' + j;
			if (!(headingKey in item)) {
				return { isValid: false, error: `データ[${i}]に見出し「${headingKey}」がありません` };
			}
		}
	}

	return { isValid: true };
}

// 安全なリダイレクト処理
function safeRedirect(url) {
	// URLの検証
	if (typeof url !== 'string' || url.trim() === '') {
		console.error('Invalid redirect URL:', url);
		alert('リダイレクトURLが不正です');
		return false;
	}

	// 相対URLかどうかを確認（XSS対策）
	if (!url.startsWith('/') && !url.startsWith(window.location.origin)) {
		console.error('Unsafe redirect URL:', url);
		alert('安全でないリダイレクトURLです');
		return false;
	}

	try {
		window.location.href = url;
		return true;
	} catch (error) {
		console.error('Redirect failed:', error);
		alert('リダイレクトに失敗しました');
		return false;
	}
}

// 数値の安全な取得
function getSafeNumber(value, min = 0, max = Number.MAX_SAFE_INTEGER) {
	let num = parseInt(value, 10);
	
	if (isNaN(num)) {
		return null;
	}
	
	if (num < min || num > max) {
		return null;
	}
	
	return num;
}

jQuery(function($) {
	$(function () {
		// Add
		$('.nishiki-pro-add-heading').click(function() {
			if( ! confirm( '新しいスタイルを追加しますか？' ) ) {
				return false;
			}

			$.ajax({
				url: nishiki_pro_add_heading_ajax.ajax_url,
				type: 'post',
				data: {
					'action': nishiki_pro_add_heading_ajax.action,
					'nonce': nishiki_pro_add_heading_ajax.nonce
				},
				dataType: 'json',
				timeout: 10000, // 10秒タイムアウト
			}).done(function (response) {
				console.log('Add response:', response);

				// レスポンスの基本検証
				let validation = validateJsonResponse(response, {
					success: { type: 'boolean', required: false },
					data: { type: 'array', required: true }
				});

				if (!validation.isValid) {
					console.error('Response validation failed:', validation.error);
					alert('エラー: ' + validation.error);
					return;
				}

				// データ配列の検証
				if (response.data) {
					let dataValidation = validateArrayData(response.data);
					if (!dataValidation.isValid) {
						console.error('Data validation failed:', dataValidation.error);
						alert('データエラー: ' + dataValidation.error);
						return;
					}
				}

				// 成功時の処理
				window.location.reload();
			}).fail(function (xhr, status, error) {
				console.error('Ajax request failed:', status, error);
				console.error('Response text:', xhr.responseText);
				
				let errorMessage = 'リクエストが失敗しました';
				
				if (xhr.responseText) {
					try {
						let errorResponse = JSON.parse(xhr.responseText);
						if (errorResponse.error) {
							errorMessage = errorResponse.error;
						}
					} catch (parseError) {
						console.error('Could not parse error response:', parseError);
					}
				}
				
				alert(errorMessage);
			}).always(function () {
				// 処理完了後の共通処理
			});
		});

		// Delete
		$('.nishiki-pro-delete-heading').click(function() {
			if( ! confirm( 'このスタイルを削除しますか？一度削除すると元に戻せません。' ) ) {
				return false;
			}

			let headingNum = this.getAttribute('data-heading-num');
			let safeNum = getSafeNumber(headingNum, 0, 999);
			
			if (safeNum === null) {
				alert('削除対象のIDが不正です');
				return false;
			}

			$.ajax({
				url: nishiki_pro_delete_heading_ajax.ajax_url,
				type: 'post',
				data: {
					'action': nishiki_pro_delete_heading_ajax.action,
					'nonce': nishiki_pro_delete_heading_ajax.nonce,
					'num': safeNum
				},
				dataType: 'json',
				timeout: 10000,
				context: safeNum
			}).done(function (response) {
				console.log('Delete response:', response);

				// レスポンスの基本検証
				let validation = validateJsonResponse(response, {
					success: { type: 'boolean', required: false },
					data: { type: 'array', required: true }
				});

				if (!validation.isValid) {
					console.error('Response validation failed:', validation.error);
					alert('エラー: ' + validation.error);
					return;
				}

				// データ配列の検証
				if (response.data) {
					let dataValidation = validateArrayData(response.data);
					if (!dataValidation.isValid) {
						console.error('Data validation failed:', dataValidation.error);
						alert('データエラー: ' + dataValidation.error);
						return;
					}
				}

				// 成功時の処理
				window.location.reload();
			}).fail(function (xhr, status, error) {
				console.error('Ajax request failed:', status, error);
				console.error('Response text:', xhr.responseText);
				
				let errorMessage = '削除に失敗しました';
				
				if (xhr.responseText) {
					try {
						let errorResponse = JSON.parse(xhr.responseText);
						if (errorResponse.error) {
							errorMessage = errorResponse.error;
						}
					} catch (parseError) {
						console.error('Could not parse error response:', parseError);
					}
				}
				
				alert(errorMessage);
			}).always(function () {
				// 処理完了後の共通処理
			});
		});

		// Reset
		$('.nishiki-pro-reset-heading').click(function() {
			if( ! confirm( 'すべての見出しスタイルをリセットしますか？この操作は元に戻せません。' ) ) {
				return false;
			}

			$.ajax({
				url: nishiki_pro_reset_heading_ajax.ajax_url,
				type: 'post',
				data: {
					'action': nishiki_pro_reset_heading_ajax.action,
					'nonce': nishiki_pro_reset_heading_ajax.nonce
				},
				dataType: 'json',
				timeout: 10000,
			}).done(function (response) {
				console.log('Reset response:', response);

				// レスポンスの基本検証
				let validation = validateJsonResponse(response, {
					success: { type: 'boolean', required: false },
					data: { type: 'array', required: false }
				});

				if (!validation.isValid) {
					console.error('Response validation failed:', validation.error);
					alert('エラー: ' + validation.error);
					return;
				}

				// 成功時の処理
				window.location.reload();
			}).fail(function (xhr, status, error) {
				console.error('Ajax request failed:', status, error);
				console.error('Response text:', xhr.responseText);
				
				let errorMessage = 'リセットに失敗しました';
				
				if (xhr.responseText) {
					try {
						let errorResponse = JSON.parse(xhr.responseText);
						if (errorResponse.error) {
							errorMessage = errorResponse.error;
						}
					} catch (parseError) {
						console.error('Could not parse error response:', parseError);
					}
				}
				
				alert(errorMessage);
			}).always(function () {
				// 処理完了後の共通処理
			});
		});

		// Update
		$('.nishiki-pro-update-heading').click(function(e) {
			$(this).html('保存中...');
			$(this).addClass('disable');
			$(this).addClass('is-busy');

			let headingNum = this.getAttribute('data-heading-num');
			let headingCode = this.getAttribute('data-heading-code');
			
			let safeNum = getSafeNumber(headingNum, 0, 999);
			
			if (safeNum === null) {
				alert('更新対象のIDが不正です');
				e.target.innerHTML = '保存';
				e.target.classList.remove('disable');
				e.target.classList.remove('is-busy');
				return false;
			}

			// JSON文字列の事前検証
			if (!headingCode || typeof headingCode !== 'string') {
				alert('更新データが不正です');
				e.target.innerHTML = '保存';
				e.target.classList.remove('disable');
				e.target.classList.remove('is-busy');
				return false;
			}

			// JSONパース試行
			let parsedData;
			try {
				parsedData = JSON.parse(headingCode);
			} catch (parseError) {
				console.error('JSON parse error:', parseError);
				alert('更新データの形式が不正です');
				e.target.innerHTML = '保存';
				e.target.classList.remove('disable');
				e.target.classList.remove('is-busy');
				return false;
			}

			// 必須フィールドの確認
			let requiredFields = ['name', 'label', 'code'];
			for (let field of requiredFields) {
				if (!(field in parsedData)) {
					alert(`必須フィールド「${field}」が見つかりません`);
					e.target.innerHTML = '保存';
					e.target.classList.remove('disable');
					e.target.classList.remove('is-busy');
					return false;
				}
			}

			$.ajax({
				url: nishiki_pro_update_heading_ajax.ajax_url,
				type: 'post',
				data: {
					'action': nishiki_pro_update_heading_ajax.action,
					'nonce': nishiki_pro_update_heading_ajax.nonce,
					'num': safeNum,
					'code': headingCode,
				},
				dataType: 'json',
				timeout: 15000, // 更新は時間がかかる可能性があるため15秒
				custom: $(this),
				context: headingCode
			}).done(function (response) {
				console.log('Update response:', response);

				// レスポンスの基本検証
				let validation = validateJsonResponse(response, {
					success: { type: 'boolean', required: false },
					message: { type: 'string', required: false }
				});

				
				// 成功時の処理
				e.target.innerHTML = '保存しました';
				e.target.classList.remove('disable');
				e.target.classList.remove('is-busy');
				
				// 少し待ってからリロード
				setTimeout(function() {
					window.location.reload();
				}, 1000);
				
			}).fail(function (xhr, status, error) {
				console.error('Update failed:', status, error);
				console.error('Response text:', xhr.responseText);
				
				let errorMessage = '保存に失敗しました';
				
				if (xhr.responseText) {
					try {
						let errorResponse = JSON.parse(xhr.responseText);
						if (errorResponse.error) {
							errorMessage = errorResponse.error;
						}
					} catch (parseError) {
						console.error('Could not parse error response:', parseError);
					}
				}
				
				alert(errorMessage);
				e.target.innerHTML = '保存失敗';
				e.target.classList.remove('disable');
				e.target.classList.remove('is-busy');
			}).always(function () {
				// 処理完了後の共通処理
			});
		});

		// Template - JSON検証強化版
		$('.nishiki-pro-template-heading').click(function() {
			let previewElement = this.querySelector('.preview');
			let text = previewElement ? previewElement.innerText : 'テンプレート';
			let templateName = this.getAttribute('data-heading-template');

			if (!templateName || typeof templateName !== 'string' || templateName.trim() === '') {
				alert('テンプレート名が不正です');
				return false;
			}

			// テンプレート名のホワイトリスト検証
			let allowedTemplates = [
				'dot01', 'polka-dot01', 'color01', 'baloon01', 'accent01', 'accent02',
				'stripe01', 'stitch01', 'border01', 'border02', 'border03', 'border04',
				'bracket01', 'bracket02'
			];

			if (!allowedTemplates.includes(templateName)) {
				alert('許可されていないテンプレートです');
				return false;
			}

			if( ! confirm( text + ' を追加しますか？' ) ) {
				return false;
			}

			$.ajax({
				url: nishiki_pro_template_heading_ajax.ajax_url,
				type: 'post',
				data: {
					'action': nishiki_pro_template_heading_ajax.action,
					'nonce': nishiki_pro_template_heading_ajax.nonce,
					'template_name': templateName
				},
				dataType: 'json',
				timeout: 15000,
				context: templateName
			}).done(function (response) {
				console.log('Template response:', response);

				// レスポンスの基本検証
				let validation = validateJsonResponse(response, {
					success: { type: 'boolean', required: false },
					data: { type: 'array', required: true }
				});

				if (!validation.isValid) {
					console.error('Response validation failed:', validation.error);
					alert('エラー: ' + validation.error);
					return;
				}

				// データ配列の検証
				let dataArray = response.data;
				let dataValidation = validateArrayData(dataArray);
				
				if (!dataValidation.isValid) {
					console.error('Data validation failed:', dataValidation.error);
					alert('データエラー: ' + dataValidation.error);
					return;
				}

				// インデックス計算と検証
				if (dataArray.length === 0) {
					alert('データが空です');
					return;
				}

				let num = dataArray.length - 1;
				
				if (typeof num !== 'number' || isNaN(num) || num < 0) {
					console.error('Invalid index calculated:', num);
					alert('リダイレクト用のインデックスが不正です');
					return;
				}

				// 安全なURL構築
				let params = new URLSearchParams({
					page: 'nishiki-pro-block-editor.php',
					select: 'headings',
					edit: num.toString()
				});
				
				let url = window.location.pathname + '?' + params.toString();
				
				console.log('Redirecting to:', url);
				
				// 安全なリダイレクト実行
				if (!safeRedirect(url)) {
					// リダイレクトに失敗した場合はリロード
					window.location.reload();
				}
				
			}).fail(function (xhr, status, error) {
				console.error('Template request failed:', status, error);
				console.error('Response text:', xhr.responseText);
				
				let errorMessage = 'テンプレートの追加に失敗しました';
				
				if (xhr.responseText) {
					try {
						let errorResponse = JSON.parse(xhr.responseText);
						if (errorResponse.error) {
							errorMessage = errorResponse.error;
						}
					} catch (parseError) {
						console.error('Could not parse error response:', parseError);
					}
				}
				
				alert(errorMessage);
			}).always(function () {
				// 処理完了後の共通処理
			});
		});
	});
});