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-f03, .apply-btn-desc, .delete-analysis-f03, #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 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 formatQuotaLineFromMeta(res, xhr) {
		const q =
			res?.data?.meta?.quota ||
			res?.meta?.quota ||
			xhr?.responseJSON?.data?.meta?.quota ||
			xhr?.responseJSON?.meta?.quota;

		if (!q || typeof q !== 'object') return '';

		const limit = Number(q.limit_tokens || 0);
		const used  = Number(q.used_tokens || 0);
		const rem   = Number(q.remaining_tokens || Math.max(0, limit - used));

		if (!limit) return '';

		let resetTxt = '';
		const resetsAt = typeof q.resets_at === 'string' ? q.resets_at : '';
		if (resetsAt) {
			const dt = new Date(resetsAt);
			if (!isNaN(dt.getTime())) {
				resetTxt = ` ${dt.getHours()}:${String(dt.getMinutes()).padStart(2, '0')}リセット`;
			}
		}

		return `（本日トークン: ${used.toLocaleString()} / ${limit.toLocaleString()}｜残: ${rem.toLocaleString()}）${resetTxt}`;
	}

	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 = formatQuotaLineFromMeta(res, xhr);
			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-f03');
		if (!$btns.length) return;

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

		$btns.each(function() {
			const $b = $(this);

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

			if ($b.data('prev-disabled') == null) {
				$b.data('prev-disabled', $b.prop('disabled') ? 1 : 0);
			}
		});

		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) return;

					const prevDisabled = Number($b.data('prev-disabled') || 0) === 1;
					$b.prop('disabled', prevDisabled).toggleClass('ui-locked', prevDisabled);
					$b.removeData('prev-disabled');
				});
				return;
			}

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

	function runF03(postId, mode) {
		const dfd = $.Deferred();

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

		xhr.done(function(res) {
			if (res?.success) dfd.resolve(res, xhr);
			else dfd.reject(res, xhr);
		});

		xhr.fail(function(xhr2) {
			if (xhr2 && xhr2.statusText === 'abort') {
				dfd.reject({ aborted: true }, xhr2);
				return;
			}
			dfd.reject(null, xhr2);
		});

		return { promise: dfd.promise(), xhr: xhr };
	}

	$('#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-f03&mode=' + encodeURIComponent(newMode);
	});

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

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

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

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

		if (isProcessing) return;

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

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

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

		const r = runF03(postId, mode);
		singleXhr = r.xhr;

		r.promise
			.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 pendingIds = $('.run-single-f03.button-primary').map(function() {
			return Number($(this).data('id') || 0);
		}).get().filter(Boolean);

		if (!pendingIds.length) {
			alert(t('no_pending_posts', '未分析の投稿はありません。'));
			return;
		}

		const confirmMsg = t('bulk_confirm', '未分析の %d 件を順番に分析します。よろしいですか？').replace('%d', pendingIds.length);
		if (!confirm(confirmMsg)) return;

		setUILock(true);

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

		function nextTick(newDelay) {
			delayMs = Math.max(minDelay, Math.min(maxDelay, newDelay));
			setTimeout(runNext, delayMs);
		}

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

			const postId = pendingIds[i];
			const mode = getCurrentMode();

			const $btn = $('#post-row-' + postId).find('.run-single-f03');
			$btn.text(`${i + 1}/${pendingIds.length} ${t('analyzing', '分析中...')}`);

			const r = runF03(postId, mode);

			r.promise
				.done(function(res) {
					updateRow(postId, res.data.html);
					nextTick(delayMs * 0.9);
				})
				.fail(function(res, xhr) {
					console.warn('bulk fail', 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 ((xhr?.status || 0) === 429) {
						$btn.text(t('waiting_due_to_congestion', '混雑のため待機中'));
						nextTick(delayMs + 1200);
					} else {
						$btn.text(t('failed_skip_next', '失敗（次へ進みます）'));
						nextTick(delayMs + 600);
					}
				})
				.always(function() {
					if (window.rllmRefreshQuota) window.rllmRefreshQuota();
					i++;
				});
		}

		runNext();
	});

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

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

		if (!desc) {
			alert(t('description_empty', 'ディスクリプションが空です。'));
			return;
		}

		if (!confirm(t('apply_confirm', 'このディスクリプションを適用しますか？'))) return;

		setUILock(true);

		$.post(ajaxurl, {
			action: 'r_llm_seo_apply_ai_description',
			post_id: postId,
			new_desc: desc,
			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-f03', 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_f03',
			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_f03',
				nonce: nonce
			}
		}).done(function(res) {
			if (res?.success) {
				alert(t('bulk_delete_complete', '一括消去しました。'));
				location.reload();
			} else {
				handleAjaxError('bulk-delete-f03', res);
				setUILock(false);
			}
		}).fail(function(xhr) {
			handleAjaxError('bulk-delete-f03-fail', null, xhr);
			setUILock(false);
		});

		return false;
	});
});