jQuery(document).ready(function($) {
	let isProcessing = false;
	let singleXhr = null;
	let allCooldownTimer = null;

	const vars = window.r_llm_seo_vars || {};
	const i18n = vars.i18n || {};
	const nonce = vars.nonce || '';
	const ajaxurl = vars.ajaxurl || window.ajaxurl || '';

	function t(key, fallback) {
		const value = i18n[key];
		return (typeof value === 'string' && value !== '') ? value : (fallback || '');
	}

	function getCurrentMode() {
		const v = $('#analysis-mode').val();
		return (v === 'keep' || v === 'pro') ? v : 'pro';
	}

	function setUILock(lock) {
		isProcessing = lock;
		const targets = '.run-single, .apply-btn, .delete-analysis, #analysis-mode, #run-bulk-analysis, #reset-bulk-analysis';
		$(targets).prop('disabled', lock).toggleClass('ui-locked', lock);
	}

	function updateRow(postId, html) {
		$('#post-row-' + postId).html(html);
		if (typeof tb_init === 'function') {
			tb_init('a.thickbox, area.thickbox, input.thickbox');
		}
	}

	function isRetryable(res, xhr) {
		const http = xhr?.status || 0;
		const code = (res && (res.data?.code || res.code)) ? String(res.data?.code || res.code) : '';
		return (http === 429 || code === 'TOO_MANY_REQUESTS' || code === 'LLM_ERROR');
	}

	function getRetryDelayMs(res, xhr, fallbackMs) {
		fallbackMs = fallbackMs || 2500;

		const ra = res?.data?.retry_after_seconds;
		if (typeof ra === 'number' && isFinite(ra) && ra > 0) {
			return Math.min(20000, Math.max(1000, ra * 1000));
		}

		try {
			const h = xhr?.getResponseHeader?.('Retry-After');
			if (h && /^\d+$/.test(h)) {
				return Math.min(20000, Math.max(1000, parseInt(h, 10) * 1000));
			}
		} catch (e) {}

		return fallbackMs;
	}

	function pickMessage(res, xhr) {
		const m1 = res?.data?.message;
		if (typeof m1 === 'string' && m1.trim() !== '') return m1.trim();

		const m2 = res?.message;
		if (typeof m2 === 'string' && m2.trim() !== '') return m2.trim();

		const m3 = xhr?.responseJSON?.data?.message || xhr?.responseJSON?.message;
		if (typeof m3 === 'string' && m3.trim() !== '') return m3.trim();

		return '';
	}

	function pickCode(res, xhr) {
		const c1 = res?.data?.code ?? res?.code;
		if (typeof c1 === 'string' && c1 !== '') return c1;

		const c2 = xhr?.responseJSON?.data?.code ?? xhr?.responseJSON?.code;
		if (typeof c2 === 'string' && c2 !== '') return c2;

		return '';
	}

	function readLastQuotaLine() {
		const text = $('#r-llm-seo-quota-line').text();
		return (typeof text === 'string' && text.trim() !== '') ? text.trim() : '';
	}

	function toUserMessage(res, xhr) {
		const http = xhr?.status || 0;
		const code = pickCode(res, xhr);
		const serverMsg = pickMessage(res, xhr);

		if (code === 'DAILY_TOKEN_QUOTA_EXCEEDED') {
			const qline = readLastQuotaLine();
			return t('daily_quota_exceeded', '本日のトークン上限に達しました。翌日以降に再実行してください。') + (qline ? '\n' + qline : '');
		}

		if (code === 'TRIAL_EXPIRED' || code === 'SUBSCRIPTION_CANCELED') {
			return serverMsg || t('contract_unavailable', '契約状態により利用できません。マイページからご確認ください。');
		}

		if (code === 'config_error') {
			return t('config_error', 'APIキーが設定されていません。設定ページからAPIキーを入力してください。');
		}

		if (code === 'INVALID_KEY') {
			return serverMsg || t('invalid_key', 'APIキーまたはサイトURLが正しくありません。設定をご確認ください。');
		}

		if (code === 'FEATURE_NOT_ALLOWED') {
			return serverMsg || t('feature_not_allowed', 'このプランでは利用できない機能です。プランをご確認ください。');
		}

		if (http === 429 || code === 'TOO_MANY_REQUESTS' || code === 'LLM_ERROR') {
			return t('ai_busy', 'AI処理が混み合っています。数秒待ってからもう一度お試しください。');
		}

		if (http === 504 || code === 'UPSTREAM_TIMEOUT') {
			return t('ai_timeout', 'AIの応答がタイムアウトしました。文章を少し短くして再度お試しください。');
		}

		if (http === 502 || http === 503) {
			return t('ai_server_unstable', 'AIサーバーが不安定です。少し待ってからもう一度お試しください。');
		}

		if (code === 'DUPLICATE_REQUEST') {
			return t('duplicate_request', '処理中です。少し待ってから再度お試しください。');
		}

		if (http === 0 && xhr?.statusText === 'abort') {
			return '';
		}

		if (serverMsg) return serverMsg;
		if (http) return `${t('generic_error', '処理に失敗しました。時間をおいて再度お試しください。')}（HTTP ${http}）`;
		return t('generic_error', '処理に失敗しました。時間をおいて再度お試しください。');
	}

	function handleAjaxError(tag, res, xhr) {
		console.error('AJAX ERROR:', tag, res, xhr?.status, xhr?.responseText);
		const msg = toUserMessage(res, xhr);
		if (msg) alert(msg);
	}

	function cooldownAllAnalysisButtons(seconds) {
		seconds = Number(seconds || 3);

		const $btns = $('.run-single');
		if (!$btns.length) return;

		if (allCooldownTimer) {
			clearInterval(allCooldownTimer);
			allCooldownTimer = null;
		}

		$btns.each(function() {
			const $b = $(this);
			const txt = ($b.data('original-text') || $b.text() || '').trim();
			if (!$b.data('original-text')) {
				$b.data('original-text', txt || t('analysis', '分析'));
			}
		});

		let remain = seconds;

		$btns.prop('disabled', true).addClass('ui-locked');
		$btns.each(function() {
			const $b = $(this);
			$b.text(`${$b.data('original-text')}（${remain}）`);
		});

		allCooldownTimer = setInterval(function() {
			remain--;

			if (remain <= 0) {
				clearInterval(allCooldownTimer);
				allCooldownTimer = null;

				$btns.each(function() {
					const $b = $(this);
					$b.text($b.data('original-text'));
				});

				if (!isProcessing) {
					$btns.prop('disabled', false).removeClass('ui-locked');
				}
				return;
			}

			$btns.each(function() {
				const $b = $(this);
				$b.text(`${$b.data('original-text')}（${remain}）`);
			});
		}, 1000);
	}

	function runF01(postId, mode, opts) {
		opts = opts || {};
		const retryOnce = opts.retryOnce === true;
		const onProgress = typeof opts.onProgress === 'function' ? opts.onProgress : null;
		const keepSingleXhr = opts.keepSingleXhr === true;
		const dfd = $.Deferred();

		function exec(attempt) {
			if (onProgress) {
				onProgress(attempt);
			}

			const xhr = $.ajax({
				type: 'POST',
				url: ajaxurl,
				timeout: 120000,
				data: {
					action: 'r_llm_seo_run_ai_analysis',
					post_id: postId,
					mode: mode,
					nonce: nonce
				}
			});

			if (keepSingleXhr) {
				singleXhr = xhr;
			}

			xhr.done(function(res) {
				if (res?.success) {
					dfd.resolve(res, xhr);
				} else {
					if (retryOnce && attempt === 1 && isRetryable(res, xhr)) {
						const wait = getRetryDelayMs(res, xhr, 2500);
						setTimeout(function() {
							exec(2);
						}, wait);
						return;
					}
					dfd.reject(res, xhr);
				}
			});

			xhr.fail(function(xhr2) {
				if (xhr2 && xhr2.statusText === 'abort') {
					dfd.reject({ aborted: true }, xhr2);
					return;
				}
				if (retryOnce && attempt === 1 && xhr2?.status === 429) {
					const wait = getRetryDelayMs(null, xhr2, 2500);
					setTimeout(function() {
						exec(2);
					}, wait);
					return;
				}
				dfd.reject(null, xhr2);
			});

			return xhr;
		}

		exec(1);
		return dfd.promise();
	}

	$('#analysis-mode').on('change', function() {
		if (isProcessing) return;

		const newMode = getCurrentMode();
		const baseUrl = ajaxurl.replace('admin-ajax.php', 'admin.php');
		window.location.href = baseUrl + '?page=r-llm-seo-f01&mode=' + encodeURIComponent(newMode);
	});

	$(document).on('input', '.ai-title-textarea', function() {
		const $textarea = $(this);
		const selector = $textarea.data('target-button');
		if (!selector) return;

		const $button = $(selector);
		if ($button.length) {
			$button.attr('data-title', $textarea.val());
		}
	});

	$(document).on('click', '.run-single', function() {
		const $btn = $(this);

		if (singleXhr && singleXhr.readyState !== 4) {
			try {
				singleXhr.abort();
			} catch (e) {}
			singleXhr = null;
		}

		if (isProcessing) return;

		const postId = $btn.data('id');
		const mode = getCurrentMode();

		const baseLabel = $btn.text().trim() || t('analysis', '分析');
		$btn.data('original-text', baseLabel);

		setUILock(true);
		$btn.prop('disabled', true);
		$btn.text(t('analyzing', '分析中...'));

		const p = runF01(postId, mode, {
			retryOnce: true,
			keepSingleXhr: true,
			onProgress: function(attempt) {
				$btn.text(attempt === 1 ? t('analyzing', '分析中...') : t('retrying', '再試行中...'));
			}
		});

		p.done(function(res) {
			updateRow(postId, res.data.html);
		}).fail(function(res, xhr) {
			if (res && res.aborted) return;
			handleAjaxError('single', res, xhr);
		}).always(function() {
			if (window.rllmRefreshQuota) {
				window.rllmRefreshQuota();
			}
			setUILock(false);
			cooldownAllAnalysisButtons(3);
		});
	});

	$('#run-bulk-analysis').on('click', function() {
		if (isProcessing) return;

		const pending = $('.run-single.is-pending');
		if (pending.length === 0) {
			alert(t('no_pending_posts', '現在、未分析の投稿はありません。'));
			return;
		}

		const confirmMsg = t('bulk_confirm', '未分析の %d 件を分析します。混雑状況に応じて間隔を調整しながら実行します。よろしいですか？').replace('%d', pending.length);
		if (!confirm(confirmMsg)) return;

		setUILock(true);

		let i = 0;
		let delayMs = 1200;
		const minDelay = 900;
		const maxDelay = 8000;

		function clampDelay(v) {
			return Math.max(minDelay, Math.min(maxDelay, v));
		}

		function scheduleNext(v) {
			delayMs = clampDelay(v);
			setTimeout(runNext, delayMs);
		}

		function runNext() {
			if (i >= pending.length) {
				setUILock(false);
				cooldownAllAnalysisButtons(3);
				alert(t('bulk_complete', '一括分析が完了しました。'));
				return;
			}

			const $btn = $(pending[i]);
			const postId = $btn.data('id');
			const mode = getCurrentMode();

			$btn.text((i + 1) + '/' + pending.length + ' ' + t('analyzing', '分析中...'));

			runF01(postId, mode, { retryOnce: true })
				.done(function(res) {
					updateRow(postId, res.data.html);
					scheduleNext(delayMs * 0.9);
				})
				.fail(function(res, xhr) {
					console.warn('bulk fail', postId, res, xhr?.status);

					const code = pickCode(res, xhr);
					if (code === 'config_error') {
						setUILock(false);
						$btn.text($btn.data('original-text') || t('analysis', '分析'));
						alert(t('config_error', 'APIキーが設定されていません。設定ページからAPIキーを入力してください。'));
						return;
					}

					if (isRetryable(res, xhr) || xhr?.status === 429) {
						$btn.text(t('waiting_due_to_congestion', '混雑のため待機中'));
						scheduleNext(delayMs + 1500);
					} else {
						$btn.text(t('failed_skip_next', '失敗（次へ進みます）'));
						scheduleNext(delayMs + 400);
					}
				})
				.always(function() {
					if (window.rllmRefreshQuota) {
						window.rllmRefreshQuota();
					}
					i++;
				});
		}

		runNext();
	});

	$(document).on('click', '.apply-btn', function() {
		if (isProcessing) return;

		const $btn = $(this);
		const postId = $btn.data('id');
		const title = String($btn.attr('data-title') || '').trim();

		if (!title) {
			alert(t('title_empty', 'タイトルが空です。'));
			return;
		}

		const confirmMsg = t('apply_confirm', '以下のAI提案タイトルを投稿へ適用します。よろしいですか？') + '\n\n「' + title + '」';
		if (!confirm(confirmMsg)) return;

		setUILock(true);

		$.post(ajaxurl, {
			action: 'r_llm_seo_apply_ai_title',
			post_id: postId,
			new_title: title,
			nonce: nonce
		}).done(function(res) {
			if (res?.success) {
				updateRow(postId, res.data.html);
			} else {
				handleAjaxError('apply', res);
			}
		}).fail(function(xhr) {
			handleAjaxError('apply-ajax-fail', null, xhr);
		}).always(function() {
			setUILock(false);
		});
	});

	$(document).on('click', '.delete-analysis', function() {
		if (isProcessing) return;

		const $btn = $(this);
		const postId = $btn.data('id');

		if (!confirm(t('delete_confirm', 'この投稿の分析データを消去します。よろしいですか？'))) return;

		setUILock(true);

		$.post(ajaxurl, {
			action: 'r_llm_seo_delete_ai_analysis',
			post_id: postId,
			nonce: nonce
		}).done(function(res) {
			if (res?.success) {
				updateRow(postId, res.data.html);
			} else {
				handleAjaxError('delete', res);
			}
		}).fail(function(xhr) {
			handleAjaxError('delete-ajax-fail', null, xhr);
		}).always(function() {
			setUILock(false);
		});
	});

	$('#reset-bulk-analysis').on('click', function(e) {
		e.preventDefault();
		e.stopPropagation();

		if (isProcessing) return false;
		if (!confirm(t('bulk_delete_confirm', 'すべての投稿の分析結果を一括消去します。この操作は取り消せません。本当によろしいですか？※投稿データに影響はありません。'))) {
			return false;
		}

		setUILock(true);

		$.ajax({
			type: 'POST',
			url: ajaxurl,
			dataType: 'json',
			data: {
				action: 'r_llm_seo_bulk_delete_analysis',
				nonce: nonce
			}
		}).done(function(res) {
			if (res?.success) {
				alert(t('bulk_delete_complete', '一括消去しました。'));
				location.reload();
			} else {
				handleAjaxError('bulk-delete', res, { status: 200, responseJSON: res });
				setUILock(false);
			}
		}).fail(function(xhr) {
			handleAjaxError('bulk-delete-fail', null, xhr);
			setUILock(false);
		});

		return false;
	});
});