<?php
/**
 * Phân hệ Soạn & Duyệt bài SEO — Sun Reaches plan.
 * Bài viết là post WordPress thật (post_type=post), xem trước dùng cơ chế
 * preview gốc của WordPress nên hiển thị đúng 100% theme/giao diện live.
 * Quy trình: Nháp → Chờ duyệt (submitted, hạn 2 ngày làm việc kể từ khi gửi,
 *            có đếm ngược & cảnh báo — áp dụng từ 03/09/2026) → người duyệt bấm Duyệt
 *            → TỰ ĐỘNG xuất bản (published) & bắt đầu đo KPI theo ma trận từ khóa,
 *            hoặc Cần sửa (rejected).
 * Được require từ seo-console.php.
 */
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/* =========================================================================
 * QUYỀN DUYỆT — email người duyệt cấu hình tại Cài đặt kết nối
 * ========================================================================= */
function ttseo_art_client_emails() {
	$raw  = ttseo_opt( 'client_emails' );
	$list = array_filter( array_map( 'trim', explode( "\n", (string) $raw ) ) );
	return array_map( 'strtolower', $list );
}
function ttseo_is_client_reviewer() {
	if ( ! is_user_logged_in() ) {
		return false;
	}
	$emails = ttseo_art_client_emails();
	if ( empty( $emails ) ) {
		return ttseo_access(); // chưa cấu hình → mọi tài khoản có quyền truy cập đều duyệt được
	}
	$user = wp_get_current_user();
	return in_array( strtolower( $user->user_email ), $emails, true );
}
function ttseo_notify_email() {
	return ttseo_opt( 'notify_email', get_option( 'admin_email' ) );
}
function ttseo_art_notify( $item, $type, $note ) {
	$to = ttseo_notify_email();
	if ( ! $to || ! is_email( $to ) ) {
		return;
	}
	if ( 'approved' === $type ) {
		$subject = '[SEO Console] ' . ttseo_t( 'Đã duyệt & xuất bản:', 'Approved & published:' ) . ' ' . $item->title;
		$body    = ttseo_t( 'Bài viết', 'The post' ) . " \"{$item->title}\" " . ttseo_t( 'đã được DUYỆT và TỰ ĐỘNG XUẤT BẢN lên website, bắt đầu đo lường KPI.', 'was APPROVED and AUTOMATICALLY PUBLISHED to the website — KPI tracking has started.' ) . "\n" . ( $note ? $note . "\n" : '' ) . "\n" . admin_url( 'admin.php?page=ttseo-articles&action=edit&item=' . $item->id );
	} else {
		$subject = '[SEO Console] ' . ttseo_t( 'Yêu cầu chỉnh sửa:', 'Changes requested:' ) . ' ' . $item->title;
		$body    = ttseo_t( 'Yêu cầu CHỈNH SỬA bài viết', 'CHANGES were requested for the post' ) . " \"{$item->title}\":\n\n{$note}\n\n" . admin_url( 'admin.php?page=ttseo-articles&action=edit&item=' . $item->id );
	}
	wp_mail( $to, $subject, $body );
}

/* =========================================================================
 * TIỆN ÍCH
 * ========================================================================= */
function ttseo_art_feedback_log( $raw ) {
	$log = json_decode( (string) $raw, true );
	return is_array( $log ) ? $log : array();
}
function ttseo_add_business_days( $mysql_dt, $days ) {
	if ( ! $mysql_dt || '0000-00-00 00:00:00' === $mysql_dt ) {
		return null;
	}
	$ts    = strtotime( $mysql_dt );
	$added = 0;
	while ( $added < $days ) {
		$ts  = strtotime( '+1 day', $ts );
		$dow = (int) gmdate( 'N', $ts );
		if ( $dow < 6 ) {
			$added++;
		}
	}
	return $ts;
}
/* =========================================================================
 * HẠN DUYỆT & CẢNH BÁO THỜI GIAN CÒN LẠI
 * Áp dụng cho bài gửi duyệt TỪ 03/09/2026 trở đi (mốc vận hành quy trình mới).
 * Bài gửi trước mốc này giữ nguyên cách hiển thị hạn cũ (không tính đếm ngược).
 * ========================================================================= */
if ( ! defined( 'TTSEO_DEADLINE_START' ) ) {
	define( 'TTSEO_DEADLINE_START', '2026-09-03 00:00:00' );
}
function ttseo_art_deadline_applies( $item ) {
	if ( empty( $item->submitted_at ) || '0000-00-00 00:00:00' === $item->submitted_at ) {
		return false;
	}
	return strtotime( $item->submitted_at ) >= strtotime( TTSEO_DEADLINE_START );
}
/**
 * Trạng thái đếm ngược hạn duyệt (2 ngày làm việc) cho 1 bài đang "submitted".
 * Trả về null nếu không áp dụng (không đang chờ duyệt, hoặc gửi trước mốc 03/09/2026).
 */
function ttseo_art_deadline_state( $item ) {
	if ( 'submitted' !== $item->status || ! ttseo_art_deadline_applies( $item ) ) {
		return null;
	}
	$start = strtotime( $item->submitted_at );
	$due   = ttseo_add_business_days( $item->submitted_at, 2 );
	if ( ! $due ) {
		return null;
	}
	$now       = time();
	$total     = max( 1, $due - $start );
	$remaining = $due - $now;
	$pct       = max( 0, min( 100, round( ( 1 - $remaining / $total ) * 100 ) ) );
	$overdue   = $remaining < 0;
	$abs       = abs( $remaining );
	$h         = floor( $abs / 3600 );
	$m         = floor( ( $abs % 3600 ) / 60 );
	$human     = ttseo_t( ( $h > 0 ? $h . 'g ' : '' ) . $m . 'p', ( $h > 0 ? $h . 'h ' : '' ) . $m . 'm' );

	if ( $overdue ) {
		$level = 'crit';
		$label = '🔴 ' . ttseo_t( 'Quá hạn', 'Overdue by' ) . ' ' . $human;
	} elseif ( $remaining <= 6 * HOUR_IN_SECONDS ) {
		$level = 'crit';
		$label = '🔴 ' . ttseo_t( 'Còn', 'Left:' ) . ' ' . $human . ' — ' . ttseo_t( 'GẤP', 'URGENT' );
	} elseif ( $remaining <= 24 * HOUR_IN_SECONDS ) {
		$level = 'warn';
		$label = '🟠 ' . ttseo_t( 'Còn', 'Left:' ) . ' ' . $human;
	} else {
		$level = 'ok';
		$label = '🟢 ' . ttseo_t( 'Còn', 'Left:' ) . ' ' . $human;
	}
	return array(
		'due'       => $due,
		'remaining' => $remaining,
		'pct'       => $pct,
		'overdue'   => $overdue,
		'level'     => $level,
		'label'     => $label,
	);
}
/** Vẽ badge + thanh tiến độ đếm ngược hạn duyệt. */
function ttseo_art_render_countdown( $item, $compact = false ) {
	$st = ttseo_art_deadline_state( $item );
	if ( ! $st ) {
		if ( 'submitted' === $item->status && $item->submitted_at ) {
			// Gửi trước mốc 03/09/2026 — chỉ hiện ngày hạn, không đếm ngược.
			$due = ttseo_add_business_days( $item->submitted_at, 2 );
			echo $due ? '<span style="color:#646970;font-size:12px;">' . esc_html( date_i18n( 'd/m H:i', $due ) ) . '</span>' : '—';
		} else {
			echo '—';
		}
		return;
	}
	$colors = array( 'ok' => '#1a7f5a', 'warn' => '#c77d16', 'crit' => '#c0392b' );
	$col    = $colors[ $st['level'] ];
	echo '<div style="min-width:130px;">';
	echo '<span style="font-size:12px;font-weight:700;color:' . esc_attr( $col ) . ';">' . esc_html( $st['label'] ) . '</span>';
	if ( ! $compact ) {
		echo '<div style="color:#8a8f94;font-size:10px;margin-top:1px;">' . esc_html( ttseo_t( 'hạn', 'due' ) ) . ' ' . esc_html( date_i18n( 'd/m H:i', $st['due'] ) ) . '</div>';
	}
	echo '<div style="background:#eef0f2;border-radius:4px;height:5px;margin-top:4px;overflow:hidden;"><div style="width:' . (int) $st['pct'] . '%;height:100%;background:' . esc_attr( $col ) . ';"></div></div>';
	echo '</div>';
}

/* =========================================================================
 * MA TRẬN TỪ KHÓA KPI — đếm bao nhiêu từ khóa KPI đã xuất hiện trong bài
 * ========================================================================= */
function ttseo_art_kpi_keywords() {
	$kpi = get_option( 'ttseo_kpi', array() );
	return array_values( array_filter( array_map( 'trim', (array) ( $kpi['keywords'] ?? array() ) ) ) );
}
/** Trả về mảng con của các từ khóa KPI thực sự xuất hiện trong nội dung/tiêu đề bài. */
function ttseo_art_match_keywords( $post_id ) {
	$kws = ttseo_art_kpi_keywords();
	if ( ! $kws || ! $post_id ) {
		return array();
	}
	$post = get_post( $post_id );
	if ( ! $post ) {
		return array();
	}
	$haystack = strtolower( $post->post_title . ' ' . wp_strip_all_tags( $post->post_content ) . ' ' . (string) get_post_meta( $post_id, 'rank_math_description', true ) );
	$matched  = array();
	foreach ( $kws as $kw ) {
		if ( '' !== $kw && false !== strpos( $haystack, strtolower( $kw ) ) ) {
			$matched[] = $kw;
		}
	}
	return $matched;
}
/** Cập nhật cột kw_matched_* cho 1 item (gọi khi xuất bản). */
function ttseo_art_refresh_keyword_matrix( $item_id, $post_id ) {
	global $wpdb;
	$table   = ttseo_wf_table();
	$matched = ttseo_art_match_keywords( $post_id );
	$wpdb->update( $table, array(
		'kw_matched_count' => count( $matched ),
		'kw_matched_json'  => wp_json_encode( $matched ),
	), array( 'id' => $item_id ) );
	return $matched;
}

function ttseo_art_badge( $status ) {
	$labels = array(
		'draft'     => ttseo_t( 'Nháp', 'Draft' ),
		'submitted' => ttseo_t( 'Chờ duyệt', 'Pending review' ),
		'approved'  => ttseo_t( 'Đã duyệt', 'Approved' ),
		'published' => ttseo_t( 'Đã xuất bản', 'Published' ),
		'rejected'  => ttseo_t( 'Cần sửa', 'Needs changes' ),
	);
	$colors = array( 'draft' => '#8a8f94', 'submitted' => '#c77d16', 'approved' => '#1a7f5a', 'published' => '#1f5c93', 'rejected' => '#c0392b' );
	$lab    = $labels[ $status ] ?? $status;
	$col    = $colors[ $status ] ?? '#8a8f94';
	return '<span style="display:inline-block;font-size:11px;font-weight:700;color:' . $col . ';border:1px solid ' . $col . '33;background:' . $col . '14;border-radius:12px;padding:2px 9px;">' . esc_html( $lab ) . '</span>';
}

/* =========================================================================
 * MENU
 * ========================================================================= */
add_action( 'admin_menu', function () {
	if ( ttseo_module_on( 'articles' ) ) {
		add_submenu_page( 'ttseo-dashboard', ttseo_t( 'Soạn & Duyệt bài SEO', 'SEO Content & Approval' ), ttseo_t( 'Soạn & Duyệt bài SEO', 'SEO Content & Approval' ), 'ttseo_access', 'ttseo-articles', 'ttseo_render_articles' );
	}
}, 20 );

/* =========================================================================
 * HANDLERS
 * ========================================================================= */
add_action( 'admin_init', function () {
	if ( ! ttseo_access() || ! function_exists( 'ttseo_is_unlocked' ) || ! ttseo_is_unlocked() ) {
		return;
	}
	global $wpdb;
	$table = ttseo_wf_table();

	if ( isset( $_POST['ttseo_art_action'] ) ) {
		check_admin_referer( 'ttseo_art_save' );
		ttseo_art_handle_save();
	}

	if ( isset( $_GET['ttseo_art_approve'], $_GET['id'] ) ) {
		check_admin_referer( 'ttseo_art_approve' );
		ttseo_art_handle_approve( (int) $_GET['id'] );
	}

	if ( isset( $_GET['ttseo_art_publish'], $_GET['id'] ) ) {
		check_admin_referer( 'ttseo_art_publish' );
		ttseo_art_handle_publish( (int) $_GET['id'] );
	}

	if ( isset( $_POST['ttseo_art_reject'] ) ) {
		check_admin_referer( 'ttseo_art_reject' );
		ttseo_art_handle_reject();
	}

	if ( isset( $_GET['ttseo_art_delete'], $_GET['id'] ) ) {
		check_admin_referer( 'ttseo_art_delete' );
		ttseo_art_handle_delete( (int) $_GET['id'] );
	}
} );

function ttseo_art_handle_save() {
	global $wpdb;
	$table   = ttseo_wf_table();
	$item_id = (int) ( $_POST['item_id'] ?? 0 );
	$submit  = 'submit' === ( $_POST['ttseo_art_action'] ?? '' );

	$title = sanitize_text_field( wp_unslash( $_POST['title'] ?? '' ) );
	if ( '' === trim( $title ) ) {
		wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles&action=edit&item=' . $item_id . '&err=title' ) );
		exit;
	}
	$slug      = sanitize_title( wp_unslash( $_POST['slug'] ?? '' ) );
	$keyword   = sanitize_text_field( wp_unslash( $_POST['keyword'] ?? '' ) );
	$meta_desc = sanitize_text_field( wp_unslash( $_POST['meta_desc'] ?? '' ) );
	$content   = wp_kses_post( wp_unslash( $_POST['content'] ?? '' ) );
	$cat_id    = (int) ( $_POST['category_id'] ?? 0 );
	$thumb_id  = (int) ( $_POST['thumbnail_id'] ?? 0 );
	$period    = preg_replace( '/[^0-9\-]/', '', (string) ( $_POST['period'] ?? gmdate( 'Y-m' ) ) );
	$intent    = sanitize_key( $_POST['intent'] ?? '' );
	$audience  = sanitize_text_field( wp_unslash( $_POST['audience'] ?? '' ) );
	$brief     = sanitize_textarea_field( wp_unslash( $_POST['brief'] ?? '' ) );
	$notes     = sanitize_textarea_field( wp_unslash( $_POST['notes'] ?? '' ) );

	$item = $item_id ? $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE id=%d", $item_id ) ) : null;

	$postarr = array(
		'post_title'   => $title,
		'post_name'    => $slug ? $slug : sanitize_title( $title ),
		'post_content' => $content,
		'post_status'  => $submit ? 'pending' : 'draft',
		'post_type'    => 'post',
	);
	if ( $cat_id ) {
		$postarr['post_category'] = array( $cat_id );
	}

	$post_id = ( $item && $item->post_id && get_post( $item->post_id ) ) ? (int) $item->post_id : 0;
	if ( $post_id ) {
		$postarr['ID'] = $post_id;
		wp_update_post( $postarr );
	} else {
		$postarr['post_author'] = get_current_user_id();
		$post_id                = wp_insert_post( $postarr, true );
		if ( is_wp_error( $post_id ) ) {
			wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles&action=edit&item=' . $item_id . '&err=post' ) );
			exit;
		}
	}
	if ( $thumb_id ) {
		set_post_thumbnail( $post_id, $thumb_id );
	}
	update_post_meta( $post_id, 'rank_math_title', $title );
	if ( $keyword ) {
		update_post_meta( $post_id, 'rank_math_focus_keyword', $keyword );
	}
	if ( $meta_desc ) {
		update_post_meta( $post_id, 'rank_math_description', $meta_desc );
	}

	$now    = current_time( 'mysql' );
	$status = $submit ? 'submitted' : 'draft';
	$data   = array(
		'type'       => 'content',
		'title'      => $title,
		'url'        => get_permalink( $post_id ),
		'status'     => $status,
		'period'     => $period ? $period : gmdate( 'Y-m' ),
		'notes'      => $notes,
		'intent'     => $intent,
		'audience'   => $audience,
		'brief'      => $brief,
		'post_id'    => $post_id,
		'updated_at' => $now,
	);
	if ( $submit ) {
		$data['submitted_at'] = $now;
	}

	if ( $item ) {
		$wpdb->update( $table, $data, array( 'id' => $item->id ) );
		$item_id = $item->id;
	} else {
		$data['created_at'] = $now;
		$wpdb->insert( $table, $data );
		$item_id = $wpdb->insert_id;
	}
	update_post_meta( $post_id, '_ttseo_item_id', $item_id );

	wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles&action=edit&item=' . $item_id . '&saved=1' ) );
	exit;
}

/**
 * Duyệt bài = xuất bản NGAY LẬP TỨC (không còn bước "Xuất bản" thủ công riêng).
 * Ngay khi publish, tính luôn ma trận từ khóa KPI để bắt đầu đo lường.
 */
function ttseo_art_handle_approve( $id ) {
	if ( ! ttseo_is_client_reviewer() ) {
		wp_die( esc_html( ttseo_t( 'Bạn không có quyền duyệt bài này.', 'You do not have permission to approve this post.' ) ) );
	}
	global $wpdb;
	$table = ttseo_wf_table();
	$item  = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE id=%d", $id ) );
	if ( ! $item ) {
		wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles' ) );
		exit;
	}
	$user    = wp_get_current_user();
	$now     = current_time( 'mysql' );
	$matched = array();
	if ( $item->post_id && get_post( $item->post_id ) ) {
		wp_update_post( array( 'ID' => $item->post_id, 'post_status' => 'publish' ) );
		$matched = ttseo_art_match_keywords( $item->post_id );
	}
	$wpdb->update( $table, array(
		'status'           => 'published',
		'url'              => $item->post_id ? get_permalink( $item->post_id ) : $item->url,
		'reviewed_at'      => $now,
		'reviewed_by'      => $user->display_name,
		'kw_matched_count' => count( $matched ),
		'kw_matched_json'  => wp_json_encode( $matched ),
		'updated_at'       => $now,
	), array( 'id' => $id ) );
	ttseo_art_notify( $item, 'approved', count( $matched ) . '/' . count( ttseo_art_kpi_keywords() ) . ' ' . ttseo_t( 'từ khóa KPI đã có trong bài.', 'KPI keyword(s) present in the post.' ) );
	wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles&published=1' ) );
	exit;
}

/** Dự phòng cho các bài còn kẹt ở trạng thái "approved" từ trước khi bật auto-publish. */
function ttseo_art_handle_publish( $id ) {
	global $wpdb;
	$table = ttseo_wf_table();
	$item  = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE id=%d", $id ) );
	if ( ! $item || ! $item->post_id ) {
		wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles' ) );
		exit;
	}
	wp_update_post( array( 'ID' => $item->post_id, 'post_status' => 'publish' ) );
	$matched = ttseo_art_refresh_keyword_matrix( $id, $item->post_id );
	$wpdb->update( $table, array(
		'status'     => 'published',
		'url'        => get_permalink( $item->post_id ),
		'updated_at' => current_time( 'mysql' ),
	), array( 'id' => $id ) );
	wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles&published=1' ) );
	exit;
}

function ttseo_art_handle_reject() {
	$id = (int) ( $_POST['item_id'] ?? 0 );
	if ( ! ttseo_is_client_reviewer() ) {
		wp_die( esc_html( ttseo_t( 'Bạn không có quyền yêu cầu chỉnh sửa.', 'You do not have permission to request changes.' ) ) );
	}
	$feedback = sanitize_textarea_field( wp_unslash( $_POST['feedback'] ?? '' ) );
	if ( '' === trim( $feedback ) ) {
		wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles&action=edit&item=' . $id . '&err=feedback' ) );
		exit;
	}
	global $wpdb;
	$table = ttseo_wf_table();
	$item  = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE id=%d", $id ) );
	if ( ! $item ) {
		wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles' ) );
		exit;
	}
	$user = wp_get_current_user();
	$log  = ttseo_art_feedback_log( $item->feedback );
	$log[] = array( 'at' => current_time( 'mysql' ), 'by' => $user->display_name, 'note' => $feedback );

	if ( $item->post_id ) {
		wp_update_post( array( 'ID' => $item->post_id, 'post_status' => 'draft' ) );
	}
	$wpdb->update( $table, array(
		'status'      => 'rejected',
		'feedback'    => wp_json_encode( $log ),
		'reviewed_at' => current_time( 'mysql' ),
		'reviewed_by' => $user->display_name,
		'updated_at'  => current_time( 'mysql' ),
	), array( 'id' => $id ) );
	ttseo_art_notify( $item, 'rejected', $feedback );
	wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles&action=edit&item=' . $id . '&rejected=1' ) );
	exit;
}

function ttseo_art_handle_delete( $id ) {
	global $wpdb;
	$table = ttseo_wf_table();
	$item  = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE id=%d AND type='content'", $id ) );
	if ( $item ) {
		if ( $item->post_id ) {
			wp_trash_post( $item->post_id );
		}
		$wpdb->delete( $table, array( 'id' => $id ) );
	}
	wp_safe_redirect( admin_url( 'admin.php?page=ttseo-articles' ) );
	exit;
}

/* =========================================================================
 * TRANG SOẠN & DUYỆT BÀI
 * ========================================================================= */
function ttseo_render_articles() {
	if ( function_exists( 'ttseo_is_unlocked' ) && ! ttseo_is_unlocked() ) {
		ttseo_render_gate();
		return;
	}
	ttseo_styles();
	if ( ! ttseo_is_pro() ) {
		echo '<div class="wrap ttseo-wrap">'; ttseo_brand_header();
		ttseo_render_upgrade_notice( ttseo_t( 'Soạn & Duyệt bài SEO', 'SEO Content & Approval' ) );
		ttseo_brand_footer(); echo '</div>';
		return;
	}
	$action = sanitize_key( $_GET['action'] ?? 'list' );
	echo '<div class="wrap ttseo-wrap">';
	ttseo_brand_header();
	if ( 'edit' === $action ) {
		ttseo_render_article_editor();
	} else {
		ttseo_render_article_list();
	}
	ttseo_brand_footer();
	echo '</div>';
}

function ttseo_render_article_list() {
	global $wpdb;
	$table       = ttseo_wf_table();
	$items       = $wpdb->get_results( "SELECT * FROM $table WHERE type='content' ORDER BY updated_at DESC" );
	$is_reviewer = ttseo_is_client_reviewer();

	echo '<h1 style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">📝 ' . esc_html( ttseo_t( 'Soạn & Duyệt bài SEO', 'SEO Content & Approval' ) );
	echo ' <a href="' . esc_url( admin_url( 'admin.php?page=ttseo-articles&action=edit&item=0' ) ) . '" class="button button-primary">＋ ' . esc_html( ttseo_t( 'Viết bài mới', 'Write new post' ) ) . '</a></h1>';
	echo '<p class="ttseo-subtle" style="margin-left:0;">' . esc_html( ttseo_t( 'Bài xem trước hiển thị đúng như trên website live (dùng đúng theme thật).', 'The preview renders exactly as it will on the live site (using the real theme).' ) ) . ' '
		. ( $is_reviewer ? esc_html( ttseo_t( 'Bạn đang đăng nhập với quyền duyệt bài.', 'You are logged in with content approval rights.' ) ) : esc_html( ttseo_t( 'Chỉ tài khoản được cấp quyền (cấu hình ở Cài đặt kết nối) mới duyệt/từ chối được.', 'Only accounts granted approval rights (configured in Settings) can approve/reject.' ) ) ) . '</p>';

	foreach ( array( 'saved' => ttseo_t( 'Đã lưu bài viết.', 'Post saved.' ), 'approved' => ttseo_t( 'Đã duyệt bài.', 'Post approved.' ), 'published' => ttseo_t( 'Đã xuất bản lên website.', 'Published to the website.' ), 'rejected' => ttseo_t( 'Đã gửi yêu cầu chỉnh sửa.', 'Change request sent.' ) ) as $k => $msg ) {
		if ( isset( $_GET[ $k ] ) ) {
			echo '<div class="notice notice-success is-dismissible"><p>' . esc_html( $msg ) . '</p></div>';
		}
	}

	$period     = gmdate( 'Y-m' );
	$this_month = array_filter( $items, function ( $it ) use ( $period ) { return $it->period === $period; } );
	$done       = 0;
	foreach ( $this_month as $it ) {
		if ( in_array( $it->status, array( 'approved', 'published' ), true ) ) {
			$done++;
		}
	}
	echo '<div class="ttseo-strip">';
	ttseo_kpi( ttseo_t( 'Chỉ tiêu tháng', 'Quota for' ) . ' ' . gmdate( 'm/Y' ), ttseo_t( '10 bài/tháng', '10 posts/month' ), ttseo_t( 'theo kế hoạch GĐ2-3', 'per Phase 2-3 plan' ), '#1f5c93' );
	ttseo_kpi( ttseo_t( 'Đã duyệt/xuất bản', 'Approved/published' ), $done . '/10', gmdate( 'm/Y' ), $done >= 10 ? '#1a7f5a' : '#c77d16' );
	ttseo_kpi( ttseo_t( 'Chờ duyệt', 'Pending review' ), (string) count( array_filter( $items, function ( $it ) { return 'submitted' === $it->status; } ) ), ttseo_t( 'toàn dự án', 'project-wide' ), '#c77d16' );
	ttseo_kpi( ttseo_t( 'Tổng số bài', 'Total posts' ), (string) count( $items ), ttseo_t( 'toàn dự án', 'project-wide' ), '#6b3fb5' );
	echo '</div>';

	if ( empty( $items ) ) {
		echo '<p class="ttseo-subtle">' . esc_html( ttseo_t( 'Chưa có bài viết nào. Bấm "＋ Viết bài mới" để bắt đầu theo kế hoạch nội dung 10 bài/tháng.', 'No posts yet. Click "＋ Write new post" to start the 10-posts/month content plan.' ) ) . '</p>';
		return;
	}

	$kpi_kws = ttseo_art_kpi_keywords();
	echo '<div class="ttseo-table"><table><thead><tr><th>' . esc_html( ttseo_t( 'Bài viết', 'Post' ) ) . '</th><th>' . esc_html( ttseo_t( 'Từ khóa mục tiêu', 'Target keyword' ) ) . '</th><th>' . esc_html( ttseo_t( 'Trạng thái', 'Status' ) ) . '</th><th>' . esc_html( ttseo_t( 'Hạn duyệt (2 ngày làm việc)', 'Approval deadline (2 business days)' ) ) . '</th><th>' . esc_html( ttseo_t( 'Từ khóa KPI trong bài', 'KPI keywords in post' ) ) . '</th><th>' . esc_html( ttseo_t( 'Cập nhật', 'Updated' ) ) . '</th><th>' . esc_html( ttseo_t( 'Thao tác', 'Actions' ) ) . '</th></tr></thead><tbody>';
	foreach ( $items as $it ) {
		$post = $it->post_id ? get_post( $it->post_id ) : null;
		$kw   = $post ? get_post_meta( $it->post_id, 'rank_math_focus_keyword', true ) : '';

		echo '<tr><td><b>' . esc_html( $it->title ) . '</b>';
		if ( $it->audience ) {
			echo '<br><span class="ttseo-src src-a">👤 ' . esc_html( $it->audience ) . '</span>';
		}
		echo '<br><span style="color:#8a8f94;font-size:11px;">' . esc_html( ttseo_t( 'Kỳ', 'Period' ) ) . ' ' . esc_html( $it->period ) . '</span></td>';
		echo '<td>' . esc_html( $kw ? $kw : '—' ) . '</td>';
		echo '<td>' . ttseo_art_badge( $it->status ) . '</td>';

		echo '<td>';
		ttseo_art_render_countdown( $it );
		echo '</td>';

		echo '<td>';
		if ( $kpi_kws && $it->post_id ) {
			// Duyệt xong (published) dùng đúng snapshot đã chốt lúc xuất bản; còn nháp/chờ duyệt
			// thì tính "sống" trên nội dung hiện tại để chuyên viên biết cần bổ sung từ khóa nào.
			if ( 'published' === $it->status ) {
				$matched = json_decode( (string) $it->kw_matched_json, true );
				$matched = is_array( $matched ) ? $matched : array();
			} else {
				$matched = ttseo_art_match_keywords( $it->post_id );
			}
			$n     = count( $matched );
			$total = count( $kpi_kws );
			$col   = $n >= (int) ceil( $total / 2 ) ? '#1a7f5a' : ( $n > 0 ? '#c77d16' : '#c0392b' );
			echo '<b style="color:' . esc_attr( $col ) . ';" title="' . esc_attr( $matched ? implode( ', ', $matched ) : ttseo_t( 'Chưa có từ khóa KPI nào trong bài', 'No KPI keywords in the post yet' ) ) . '">' . $n . '/' . $total . '</b>';
			if ( $matched ) {
				echo '<div style="font-size:10.5px;color:#8a8f94;margin-top:2px;max-width:180px;">' . esc_html( implode( ' · ', array_slice( $matched, 0, 3 ) ) ) . ( count( $matched ) > 3 ? '…' : '' ) . '</div>';
			}
		} else {
			echo '—';
		}
		echo '</td>';
		echo '<td style="color:#8a8f94;font-size:11px;">' . esc_html( mysql2date( 'd/m H:i', $it->updated_at ) ) . '</td>';

		echo '<td style="white-space:nowrap;">';
		echo '<a href="' . esc_url( admin_url( 'admin.php?page=ttseo-articles&action=edit&item=' . $it->id ) ) . '" style="font-size:11px;margin-right:8px;">✎ ' . esc_html( ttseo_t( 'Soạn/Sửa', 'Edit' ) ) . '</a>';
		if ( $post ) {
			echo '<a href="' . esc_url( get_preview_post_link( $post ) ) . '" target="_blank" rel="noopener" style="font-size:11px;margin-right:8px;">👁 ' . esc_html( ttseo_t( 'Xem trước', 'Preview' ) ) . '</a>';
		}
		if ( 'submitted' === $it->status && $is_reviewer ) {
			$ap = wp_nonce_url( admin_url( 'admin.php?page=ttseo-articles&ttseo_art_approve=1&id=' . $it->id ), 'ttseo_art_approve' );
			echo '<a href="' . esc_url( $ap ) . '" style="font-size:11px;margin-right:8px;color:#1a7f5a;font-weight:700;" onclick="return confirm(\'' . esc_js( ttseo_t( 'Duyệt và xuất bản bài này ngay?', 'Approve and publish this post now?' ) ) . '\')">✔ ' . esc_html( ttseo_t( 'Duyệt & xuất bản', 'Approve & publish' ) ) . '</a>';
		}
		if ( 'approved' === $it->status ) {
			$pub = wp_nonce_url( admin_url( 'admin.php?page=ttseo-articles&ttseo_art_publish=1&id=' . $it->id ), 'ttseo_art_publish' );
			echo '<a href="' . esc_url( $pub ) . '" style="font-size:11px;margin-right:8px;color:#1f5c93;font-weight:700;" onclick="return confirm(\'' . esc_js( ttseo_t( 'Xuất bản bài này lên website ngay?', 'Publish this post to the website now?' ) ) . '\')">🚀 ' . esc_html( ttseo_t( 'Xuất bản', 'Publish' ) ) . '</a>';
		}
		$del = wp_nonce_url( admin_url( 'admin.php?page=ttseo-articles&ttseo_art_delete=1&id=' . $it->id ), 'ttseo_art_delete' );
		echo '<a href="' . esc_url( $del ) . '" onclick="return confirm(\'' . esc_js( ttseo_t( 'Xóa mục này? (bài WordPress liên kết sẽ chuyển vào thùng rác)', 'Delete this item? (the linked WordPress post will be moved to trash)' ) ) . '\')" style="color:#c0392b;font-size:11px;">' . esc_html( ttseo_t( 'Xóa', 'Delete' ) ) . '</a>';
		echo '</td></tr>';
	}
	echo '</tbody></table></div>';
	echo '<p class="ttseo-subtle">' . esc_html( ttseo_t(
		'Quy trình: Nháp → Gửi duyệt → người duyệt bấm Duyệt & xuất bản (bài lên website ngay lập tức, không qua bước xuất bản riêng) hoặc Yêu cầu chỉnh sửa (trong trang Soạn/Sửa). Hạn phản hồi 2 ngày làm việc — có đếm ngược & cảnh báo thời gian còn lại. Ngay khi xuất bản, hệ thống tự đếm số từ khóa KPI đã có trong bài để bắt đầu đo lường.',
		'Workflow: Draft → Submit for review → the reviewer clicks Approve & publish (the post goes live immediately, no separate publish step) or Request changes (in the Edit page). Response deadline: 2 business days — with a countdown & time-remaining alerts. As soon as a post is published, the system counts its KPI keywords to start measurement.'
	) ) . ' ' . esc_html( ttseo_t( 'Áp dụng cho bài gửi duyệt từ', 'Applies to posts submitted from' ) ) . ' ' . esc_html( date_i18n( 'd/m/Y', strtotime( TTSEO_DEADLINE_START ) ) ) . '.</p>';

	ttseo_render_kw_coverage_matrix( $items, $kpi_kws );
}

/**
 * Ma trận theo dõi: mỗi từ khóa KPI đã "phủ" được bao nhiêu bài viết đã xuất bản.
 * Dùng để nhìn nhanh còn từ khóa nào trong bộ KPI chưa có bài viết nào nhắm tới.
 */
function ttseo_render_kw_coverage_matrix( $items, $kpi_kws ) {
	if ( ! $kpi_kws ) {
		echo '<p class="ttseo-subtle">' . esc_html( ttseo_t( 'Chưa khai báo bộ từ khóa KPI (vào', 'The KPI keyword set hasn\'t been defined yet (go to' ) ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=ttseo-kpi' ) ) . '">' . esc_html( ttseo_t( 'KPI & Tiến độ', 'KPI & Progress' ) ) . '</a> ' . esc_html( ttseo_t( 'để nhập 20 từ khóa) nên chưa dựng được ma trận theo dõi.', 'to enter the 20 keywords) so the coverage matrix can\'t be built yet.' ) ) . '</p>';
		return;
	}
	$published = array_filter( $items, function ( $it ) { return 'published' === $it->status; } );
	$coverage  = array();
	foreach ( $kpi_kws as $kw ) {
		$coverage[ $kw ] = array();
	}
	foreach ( $published as $it ) {
		$matched = json_decode( (string) $it->kw_matched_json, true );
		if ( ! is_array( $matched ) ) {
			continue;
		}
		foreach ( $matched as $kw ) {
			if ( isset( $coverage[ $kw ] ) ) {
				$coverage[ $kw ][] = $it;
			}
		}
	}
	$covered_ct = count( array_filter( $coverage, function ( $a ) { return ! empty( $a ); } ) );

	echo '<h2 class="ttseo-sec" style="--b:#6b3fb5;margin-top:30px;">🧩 ' . esc_html( ttseo_t( 'Ma trận theo dõi từ khóa KPI × bài viết đã xuất bản', 'KPI keyword × published post coverage matrix' ) ) . '</h2>';
	echo '<p class="ttseo-subtle">' . esc_html( ttseo_t( 'Đối chiếu bộ', 'Cross-checking the set of' ) ) . ' ' . count( $kpi_kws ) . ' ' . esc_html( ttseo_t( 'từ khóa KPI với', 'KPI keywords against' ) ) . ' ' . count( $published ) . ' ' . esc_html( ttseo_t( 'bài đã xuất bản — từ khóa nào đã có bài "phủ" (được đo KPI) và từ khóa nào còn thiếu nội dung.', 'published post(s) — which keywords already have "coverage" (are being measured) and which still lack content.' ) ) . '</p>';
	echo '<div class="ttseo-strip">';
	ttseo_kpi( ttseo_t( 'Từ khóa đã có bài phủ', 'Keywords with coverage' ), $covered_ct . '/' . count( $kpi_kws ), ttseo_t( 'ít nhất 1 bài xuất bản', 'at least 1 published post' ), $covered_ct >= count( $kpi_kws ) ? '#1a7f5a' : '#c77d16' );
	ttseo_kpi( ttseo_t( 'Từ khóa chưa có bài', 'Keywords with no post' ), (string) ( count( $kpi_kws ) - $covered_ct ), ttseo_t( 'cần lên kế hoạch viết', 'needs to be planned' ), '#c0392b' );
	echo '</div>';

	echo '<div class="ttseo-table"><table><thead><tr><th>' . esc_html( ttseo_t( 'Từ khóa KPI', 'KPI keyword' ) ) . '</th><th>' . esc_html( ttseo_t( 'Số bài đã phủ', 'Posts covering it' ) ) . '</th><th>' . esc_html( ttseo_t( 'Bài viết', 'Posts' ) ) . '</th></tr></thead><tbody>';
	foreach ( $coverage as $kw => $arts ) {
		$n = count( $arts );
		echo '<tr><td><b>' . esc_html( $kw ) . '</b></td>';
		echo '<td><span style="font-weight:700;color:' . ( $n > 0 ? '#1a7f5a' : '#c0392b' ) . ';">' . $n . '</span></td>';
		echo '<td style="font-size:12px;">';
		if ( $n ) {
			$links = array();
			foreach ( $arts as $a ) {
				$links[] = '<a href="' . esc_url( admin_url( 'admin.php?page=ttseo-articles&action=edit&item=' . $a->id ) ) . '">' . esc_html( $a->title ) . '</a>';
			}
			echo implode( ' · ', $links );
		} else {
			echo '<span style="color:#c0392b;">— ' . esc_html( ttseo_t( 'chưa có bài nào nhắm từ khóa này', 'no post targets this keyword yet' ) ) . ' —</span>';
		}
		echo '</td></tr>';
	}
	echo '</tbody></table></div>';
}

function ttseo_render_article_editor() {
	global $wpdb;
	$table = ttseo_wf_table();
	$id    = (int) ( $_GET['item'] ?? 0 );
	$item  = $id ? $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE id=%d", $id ) ) : null;
	$post  = ( $item && $item->post_id ) ? get_post( $item->post_id ) : null;

	$is_reviewer = ttseo_is_client_reviewer();
	$title       = $post ? $post->post_title : ( $item->title ?? '' );
	$slug        = $post ? $post->post_name : '';
	$content     = $post ? $post->post_content : '';
	$keyword     = $post ? get_post_meta( $post->ID, 'rank_math_focus_keyword', true ) : '';
	$meta_desc   = $post ? get_post_meta( $post->ID, 'rank_math_description', true ) : '';
	$thumb_id    = $post ? get_post_thumbnail_id( $post->ID ) : 0;
	$cats        = $post ? wp_get_post_categories( $post->ID ) : array();
	$cat_id      = $cats ? (int) $cats[0] : 0;

	echo '<h1><a href="' . esc_url( admin_url( 'admin.php?page=ttseo-articles' ) ) . '" style="text-decoration:none;">← ' . esc_html( ttseo_t( 'Danh sách', 'List' ) ) . '</a> · ' . ( $item ? esc_html( ttseo_t( 'Sửa bài', 'Edit post' ) ) : esc_html( ttseo_t( 'Viết bài mới', 'Write new post' ) ) ) . '</h1>';

	$errs = array(
		'title'    => ttseo_t( 'Vui lòng nhập tiêu đề.', 'Please enter a title.' ),
		'post'     => ttseo_t( 'Không lưu được bài viết, thử lại.', 'Could not save the post, please try again.' ),
		'feedback' => ttseo_t( 'Vui lòng nhập nội dung yêu cầu chỉnh sửa.', 'Please enter the change request details.' ),
	);
	if ( isset( $_GET['err'] ) && isset( $errs[ $_GET['err'] ] ) ) {
		echo '<div class="notice notice-error"><p>' . esc_html( $errs[ $_GET['err'] ] ) . '</p></div>';
	}
	if ( isset( $_GET['saved'] ) ) {
		echo '<div class="notice notice-success is-dismissible"><p>' . esc_html( ttseo_t( 'Đã lưu bài viết.', 'Post saved.' ) ) . '</p></div>';
	}

	if ( $item && $post ) {
		echo '<p><a href="' . esc_url( get_preview_post_link( $post ) ) . '" target="_blank" rel="noopener" class="button button-secondary">👁 ' . esc_html( ttseo_t( 'Xem trước như trên website live', 'Preview as on the live website' ) ) . '</a></p>';
	}

	/* ---------- Panel duyệt bài ---------- */
	if ( $item ) {
		echo '<div id="review" style="background:#fff;border:1px solid #dcdfe3;border-left:4px solid #c77d16;border-radius:8px;padding:14px 16px;margin:14px 0;">';
		echo '<h3 style="margin-top:0;">' . esc_html( ttseo_t( 'Trạng thái duyệt:', 'Review status:' ) ) . ' ' . ttseo_art_badge( $item->status ) . '</h3>';
		if ( $item->reviewed_by ) {
			echo '<p class="ttseo-subtle" style="margin-left:0;">' . esc_html( ttseo_t( 'Cập nhật lần cuối bởi', 'Last updated by' ) ) . ' <b>' . esc_html( $item->reviewed_by ) . '</b> ' . esc_html( ttseo_t( 'lúc', 'at' ) ) . ' ' . esc_html( mysql2date( 'd/m/Y H:i', $item->reviewed_at ) ) . '</p>';
		}
		$log = ttseo_art_feedback_log( $item->feedback );
		if ( $log ) {
			echo '<h4>' . esc_html( ttseo_t( 'Lịch sử trao đổi', 'Discussion history' ) ) . '</h4><div style="display:grid;gap:8px;margin-bottom:12px;">';
			foreach ( array_reverse( $log ) as $l ) {
				echo '<div style="background:#f6f7f8;border-radius:6px;padding:8px 12px;font-size:13px;"><b>' . esc_html( $l['by'] ) . '</b> — <span style="color:#8a8f94;">' . esc_html( mysql2date( 'd/m H:i', $l['at'] ) ) . '</span><br>' . nl2br( esc_html( $l['note'] ) ) . '</div>';
			}
			echo '</div>';
		}
		// Xem trước ma trận từ khóa KPI ngay khi đang soạn/chờ duyệt (tính sống trên nội dung
		// hiện tại) — giúp chuyên viên bổ sung từ khóa còn thiếu trước khi gửi duyệt.
		if ( 'published' !== $item->status && $item->post_id ) {
			$kpi_kws = ttseo_art_kpi_keywords();
			if ( $kpi_kws ) {
				$matched = ttseo_art_match_keywords( $item->post_id );
				$missing = array_values( array_diff( $kpi_kws, $matched ) );
				echo '<div style="background:#f6f7f8;border-radius:6px;padding:10px 12px;margin-bottom:12px;">';
				echo '<b>🔎 ' . esc_html( ttseo_t( 'Từ khóa KPI trong bài (xem trước)', 'KPI keywords in post (preview)' ) ) . '</b> — ' . esc_html( ttseo_t( 'hiện có', 'currently has' ) ) . ' <b style="color:#6b3fb5;">' . count( $matched ) . '/' . count( $kpi_kws ) . '</b>.';
				if ( $matched ) {
					echo '<div style="margin-top:6px;">';
					foreach ( $matched as $kw ) {
						echo '<span class="ttseo-src" style="background:#e8f6ee;color:#1a7f5a;margin:0 5px 5px 0;">✓ ' . esc_html( $kw ) . '</span>';
					}
					echo '</div>';
				}
				if ( $missing ) {
					echo '<div style="margin-top:4px;">';
					foreach ( array_slice( $missing, 0, 10 ) as $kw ) {
						echo '<span class="ttseo-src" style="background:#f6f7f8;color:#8a8f94;border:1px dashed #dcdfe3;margin:0 5px 5px 0;">' . esc_html( $kw ) . '</span>';
					}
					if ( count( $missing ) > 10 ) {
						echo '<span style="color:#8a8f94;font-size:11px;">+' . ( count( $missing ) - 10 ) . ' ' . esc_html( ttseo_t( 'từ khóa khác chưa có', 'more keyword(s) missing' ) ) . '</span>';
					}
					echo '</div>';
				}
				echo '</div>';
			}
		}

		if ( 'submitted' === $item->status ) {
			$dl = ttseo_art_deadline_state( $item );
			if ( $dl ) {
				$colors = array( 'ok' => '#1a7f5a', 'warn' => '#c77d16', 'crit' => '#c0392b' );
				$col    = $colors[ $dl['level'] ];
				echo '<div style="background:#f6f7f8;border-radius:6px;padding:10px 12px;margin-bottom:12px;">';
				echo '<b style="color:' . esc_attr( $col ) . ';font-size:15px;">' . esc_html( $dl['label'] ) . '</b>';
				echo '<div style="color:#8a8f94;font-size:12px;margin-top:2px;">' . esc_html( ttseo_t( 'Hạn duyệt:', 'Review deadline:' ) ) . ' ' . esc_html( date_i18n( 'd/m/Y H:i', $dl['due'] ) ) . ' (' . esc_html( ttseo_t( '2 ngày làm việc kể từ khi gửi duyệt', '2 business days from submission' ) ) . ')</div>';
				echo '<div style="background:#eef0f2;border-radius:4px;height:7px;margin-top:8px;overflow:hidden;"><div style="width:' . (int) $dl['pct'] . '%;height:100%;background:' . esc_attr( $col ) . ';"></div></div>';
				echo '</div>';
			}
			if ( $is_reviewer ) {
				$ap = wp_nonce_url( admin_url( 'admin.php?page=ttseo-articles&ttseo_art_approve=1&id=' . $item->id ), 'ttseo_art_approve' );
				echo '<p><a href="' . esc_url( $ap ) . '" class="button button-primary" onclick="return confirm(\'' . esc_js( ttseo_t( 'Duyệt và xuất bản bài này ngay lên website?', 'Approve and publish this post to the website now?' ) ) . '\')">✔ ' . esc_html( ttseo_t( 'Duyệt & xuất bản ngay', 'Approve & publish now' ) ) . '</a></p>';
				echo '<form method="post"><input type="hidden" name="item_id" value="' . esc_attr( $item->id ) . '">';
				wp_nonce_field( 'ttseo_art_reject' );
				echo '<label><b>' . esc_html( ttseo_t( 'Hoặc yêu cầu chỉnh sửa', 'Or request changes' ) ) . '</b> (' . esc_html( ttseo_t( 'mô tả cụ thể chỗ cần sửa', 'describe specifically what needs fixing' ) ) . ')<br><textarea name="feedback" rows="3" class="large-text" required></textarea></label>';
				echo '<p><button class="button" name="ttseo_art_reject" value="1">↩ ' . esc_html( ttseo_t( 'Gửi yêu cầu chỉnh sửa', 'Send change request' ) ) . '</button></p></form>';
			} else {
				echo '<p class="ttseo-subtle" style="margin-left:0;">' . esc_html( ttseo_t( 'Bài đang chờ duyệt. Duyệt xong bài sẽ tự động xuất bản ngay, không cần thao tác thêm.', 'The post is pending review. Once approved it will publish automatically — no further action needed.' ) ) . '</p>';
			}
		} elseif ( 'approved' === $item->status ) {
			echo '<p class="ttseo-subtle" style="margin-left:0;color:#1a7f5a;">✔ ' . esc_html( ttseo_t( 'Đã được duyệt — sẵn sàng xuất bản.', 'Approved — ready to publish.' ) ) . '</p>';
			$pub = wp_nonce_url( admin_url( 'admin.php?page=ttseo-articles&ttseo_art_publish=1&id=' . $item->id ), 'ttseo_art_publish' );
			echo '<p><a href="' . esc_url( $pub ) . '" class="button button-primary" onclick="return confirm(\'' . esc_js( ttseo_t( 'Xuất bản bài này lên website ngay?', 'Publish this post to the website now?' ) ) . '\')">🚀 ' . esc_html( ttseo_t( 'Xuất bản lên website', 'Publish to website' ) ) . '</a></p>';
		} elseif ( 'published' === $item->status ) {
			echo '<p class="ttseo-subtle" style="margin-left:0;color:#1f5c93;">🚀 ' . esc_html( ttseo_t( 'Đã xuất bản:', 'Published:' ) ) . ' <a href="' . esc_url( $item->url ) . '" target="_blank" rel="noopener">' . esc_html( $item->url ) . '</a></p>';
			$kpi_kws = ttseo_art_kpi_keywords();
			if ( $kpi_kws ) {
				$matched = json_decode( (string) $item->kw_matched_json, true );
				$matched = is_array( $matched ) ? $matched : array();
				echo '<div style="background:#f6f7f8;border-radius:6px;padding:10px 12px;margin-top:10px;">';
				echo '<b>📈 ' . esc_html( ttseo_t( 'Bắt đầu đo KPI', 'KPI tracking started' ) ) . '</b> — ' . esc_html( ttseo_t( 'bài chứa', 'the post contains' ) ) . ' <b style="color:#6b3fb5;">' . count( $matched ) . '/' . count( $kpi_kws ) . '</b> ' . esc_html( ttseo_t( 'từ khóa KPI mục tiêu.', 'target KPI keyword(s).' ) );
				if ( $matched ) {
					echo '<div style="margin-top:6px;">';
					foreach ( $matched as $kw ) {
						echo '<span class="ttseo-src" style="background:#f0e9fb;color:#6b3fb5;margin:0 5px 5px 0;">' . esc_html( $kw ) . '</span>';
					}
					echo '</div>';
				}
				echo '</div>';
			}
		} elseif ( 'rejected' === $item->status ) {
			echo '<p class="ttseo-subtle" style="margin-left:0;color:#c0392b;">✎ ' . esc_html( ttseo_t( 'Yêu cầu chỉnh sửa — xem lịch sử trao đổi ở trên, sửa nội dung rồi gửi duyệt lại.', 'Changes requested — see the discussion history above, edit the content, then resubmit for review.' ) ) . '</p>';
		}
		echo '</div>';
	}

	/* ---------- Form soạn bài ---------- */
	echo '<form method="post" style="background:#fff;border:1px solid #dcdfe3;border-radius:8px;padding:16px 18px;">';
	wp_nonce_field( 'ttseo_art_save' );
	echo '<input type="hidden" name="item_id" value="' . esc_attr( $item->id ?? 0 ) . '">';
	echo '<table class="form-table">';
	echo '<tr><th>' . esc_html( ttseo_t( 'Tiêu đề bài viết', 'Post title' ) ) . '</th><td><input type="text" name="title" class="large-text" value="' . esc_attr( $title ) . '" required></td></tr>';
	echo '<tr><th>' . esc_html( ttseo_t( 'Đường dẫn (slug)', 'URL slug' ) ) . '</th><td><input type="text" name="slug" class="regular-text" value="' . esc_attr( $slug ) . '" placeholder="' . esc_attr( ttseo_t( 'để trống = tự tạo từ tiêu đề', 'leave empty to auto-generate from the title' ) ) . '"></td></tr>';
	echo '<tr><th>' . esc_html( ttseo_t( 'Từ khóa mục tiêu', 'Target keyword' ) ) . '</th><td><input type="text" name="keyword" class="regular-text" value="' . esc_attr( $keyword ) . '"></td></tr>';
	echo '<tr><th>' . esc_html( ttseo_t( 'Mô tả SEO (meta description)', 'SEO description (meta description)' ) ) . '</th><td><textarea name="meta_desc" rows="2" class="large-text" maxlength="160">' . esc_textarea( $meta_desc ) . '</textarea></td></tr>';
	echo '<tr><th>' . esc_html( ttseo_t( 'Chuyên mục', 'Category' ) ) . '</th><td>' . wp_dropdown_categories( array( 'name' => 'category_id', 'selected' => $cat_id, 'show_option_none' => '— ' . ttseo_t( 'Chọn', 'Select' ) . ' —', 'hide_empty' => false, 'echo' => 0 ) ) . '</td></tr>';
	echo '<tr><th>' . esc_html( ttseo_t( 'Ảnh đại diện', 'Featured image' ) ) . '</th><td><div id="ttseo-thumb-wrap">';
	if ( $thumb_id ) {
		echo wp_get_attachment_image( $thumb_id, 'thumbnail' );
	}
	echo '</div><input type="hidden" id="ttseo_thumb_id" name="thumbnail_id" value="' . esc_attr( $thumb_id ) . '">';
	echo '<p><button type="button" class="button" id="ttseo-thumb-pick">' . esc_html( ttseo_t( 'Chọn ảnh', 'Choose image' ) ) . '</button></p></td></tr>';
	echo '<tr><th>' . esc_html( ttseo_t( 'Nội dung bài viết', 'Post content' ) ) . '</th><td>';
	wp_editor( $content, 'ttseo_content', array( 'textarea_name' => 'content', 'textarea_rows' => 18, 'media_buttons' => true ) );
	echo '</td></tr>';
	echo '<tr><th>Search Intent</th><td><select name="intent">';
	echo '<option value="">— ' . esc_html( ttseo_t( 'chọn', 'select' ) ) . ' —</option>';
	foreach ( ttseo_wf_intents() as $k => $v ) {
		echo '<option value="' . esc_attr( $k ) . '" ' . selected( $item->intent ?? '', $k, false ) . '>' . esc_html( $v ) . '</option>';
	}
	echo '</select></td></tr>';
	echo '<tr><th>' . esc_html( ttseo_t( 'Nhóm khách hàng mục tiêu', 'Target audience' ) ) . '</th><td><input type="text" name="audience" class="large-text" value="' . esc_attr( $item->audience ?? '' ) . '" placeholder="' . esc_attr( ttseo_t( 'VD: Nhà thầu FDI, chủ đầu tư kho xưởng', 'e.g. FDI contractors, warehouse developers' ) ) . '"></td></tr>';
	echo '<tr><th>' . esc_html( ttseo_t( 'Brief / dàn ý', 'Brief / outline' ) ) . '</th><td><textarea name="brief" rows="3" class="large-text">' . esc_textarea( $item->brief ?? '' ) . '</textarea></td></tr>';
	echo '<tr><th>' . esc_html( ttseo_t( 'Kỳ (tháng)', 'Period (month)' ) ) . '</th><td><input type="month" name="period" value="' . esc_attr( $item->period ?? gmdate( 'Y-m' ) ) . '"></td></tr>';
	echo '<tr><th>' . esc_html( ttseo_t( 'Ghi chú nội bộ', 'Internal notes' ) ) . '</th><td><input type="text" name="notes" class="large-text" value="' . esc_attr( $item->notes ?? '' ) . '"></td></tr>';
	echo '</table>';
	echo '<p>';
	echo '<button class="button" name="ttseo_art_action" value="draft">💾 ' . esc_html( ttseo_t( 'Lưu nháp', 'Save draft' ) ) . '</button> ';
	echo '<button class="button button-primary" name="ttseo_art_action" value="submit" style="background:#1a7f5a;border-color:#1a7f5a;">📨 ' . esc_html( ttseo_t( 'Gửi duyệt', 'Submit for review' ) ) . '</button>';
	echo '</p>';
	echo '</form>';

	wp_enqueue_media();
	?>
	<script>
	jQuery(function($){
		var frame;
		$('#ttseo-thumb-pick').on('click', function(e){
			e.preventDefault();
			if (frame) { frame.open(); return; }
			frame = wp.media({ title: '<?php echo esc_js( ttseo_t( 'Chọn ảnh đại diện', 'Choose featured image' ) ); ?>', multiple: false, library: { type: 'image' } });
			frame.on('select', function(){
				var a = frame.state().get('selection').first().toJSON();
				$('#ttseo_thumb_id').val(a.id);
				var src = (a.sizes && a.sizes.thumbnail) ? a.sizes.thumbnail.url : a.url;
				$('#ttseo-thumb-wrap').html('<img src="'+ src +'" style="max-width:150px;">');
			});
			frame.open();
		});
	});
	</script>
	<?php
}
