<?php
/**
 * Phân hệ Snapshot KPI & Đối chiếu nghiệm thu — Sun Reaches plan.
 * Tự động chụp & lưu trữ số liệu GSC/GA4/Bing theo từng tháng (không chỉ xem live),
 * đối chiếu với công thức KPI trong "Kế hoạch triển khai GĐ2-3" (Baseline B/C/R,
 * mục tiêu Top20/10/5/3 theo tháng) và tiến độ đăng bài SEO thực tế (post đã publish).
 * Được require từ seo-console.php.
 */
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

define( 'TTSEO_KPI_SNAP_DBVER', '1' );

/* =========================================================================
 * BẢNG SNAPSHOT — 1 dòng / 1 kỳ (tháng), UPSERT theo period
 * ========================================================================= */
function ttseo_kpi_snapshot_table() {
	global $wpdb;
	return $wpdb->prefix . 'ttseo_kpi_snapshots';
}
function ttseo_kpi_snap_install() {
	if ( get_option( 'ttseo_kpi_snap_dbver' ) === TTSEO_KPI_SNAP_DBVER ) {
		return;
	}
	global $wpdb;
	$table   = ttseo_kpi_snapshot_table();
	$charset = $wpdb->get_charset_collate();
	require_once ABSPATH . 'wp-admin/includes/upgrade.php';
	dbDelta( "CREATE TABLE $table (
		id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
		period VARCHAR(7) NOT NULL DEFAULT '',
		captured_at DATETIME NOT NULL DEFAULT '1970-01-01 00:00:00',
		traffic_sessions BIGINT NOT NULL DEFAULT 0,
		gsc_clicks BIGINT NOT NULL DEFAULT 0,
		gsc_impressions BIGINT NOT NULL DEFAULT 0,
		avg_position DECIMAL(6,2) NOT NULL DEFAULT 0,
		top20 SMALLINT NOT NULL DEFAULT 0,
		top10 SMALLINT NOT NULL DEFAULT 0,
		top5 SMALLINT NOT NULL DEFAULT 0,
		top3 SMALLINT NOT NULL DEFAULT 0,
		bing_clicks BIGINT NOT NULL DEFAULT 0,
		bing_impressions BIGINT NOT NULL DEFAULT 0,
		keywords_json LONGTEXT NULL,
		source VARCHAR(20) NOT NULL DEFAULT 'auto',
		PRIMARY KEY (id),
		UNIQUE KEY period (period)
	) $charset;" );
	update_option( 'ttseo_kpi_snap_dbver', TTSEO_KPI_SNAP_DBVER );
}
add_action( 'admin_init', 'ttseo_kpi_snap_install' );

/* =========================================================================
 * CHỤP SNAPSHOT — gọi tự động (cron tuần) hoặc thủ công (nút bấm)
 * ========================================================================= */
function ttseo_kpi_capture_snapshot( $period = null, $source = 'auto' ) {
	if ( ! $period ) {
		$period = gmdate( 'Y-m' );
	}
	$kpi = get_option( 'ttseo_kpi', array() );
	$kws = $kpi['keywords'] ?? array();

	$traffic = 0;
	if ( function_exists( 'ttseo_ga4_report' ) && ttseo_opt( 'ga4_property_id' ) ) {
		$ov = ttseo_ga4_report( array( 'sessions' ) );
		if ( ! is_wp_error( $ov ) ) {
			$traffic = (int) ttseo_ga4_metric_val( $ov, 0 );
		}
	}

	$clicks = 0; $imp = 0; $avgpos = 0;
	$top      = array( 20 => 0, 10 => 0, 5 => 0, 3 => 0 );
	$kw_detail = array();
	if ( function_exists( 'ttseo_gsc_query' ) && ttseo_opt( 'gsc_property' ) ) {
		$tot = ttseo_gsc_query( array(), 1 );
		if ( ! is_wp_error( $tot ) && ! empty( $tot ) ) {
			$clicks = (int) ( $tot[0]['clicks'] ?? 0 );
			$imp    = (int) ( $tot[0]['impressions'] ?? 0 );
		}
		$q = ttseo_gsc_query( array( 'query' ), 500 );
		if ( ! is_wp_error( $q ) ) {
			$map = array();
			foreach ( (array) $q as $row ) {
				$map[ strtolower( $row['keys'][0] ?? '' ) ] = $row;
			}
			$pos_sum = 0; $pos_ct = 0;
			foreach ( $kws as $kw ) {
				$row = $map[ strtolower( $kw ) ] ?? null;
				$pos = $row ? (float) $row['position'] : null;
				if ( null !== $pos ) {
					$pos_sum += $pos; $pos_ct++;
					if ( $pos <= 20 ) { $top[20]++; }
					if ( $pos <= 10 ) { $top[10]++; }
					if ( $pos <= 5 )  { $top[5]++; }
					if ( $pos <= 3 )  { $top[3]++; }
				}
				$kw_detail[] = array( 'kw' => $kw, 'pos' => $pos, 'clicks' => $row ? (int) $row['clicks'] : 0, 'imp' => $row ? (int) $row['impressions'] : 0 );
			}
			if ( $pos_ct ) {
				$avgpos = round( $pos_sum / $pos_ct, 2 );
			}
		}
	}

	$bc = 0; $bi = 0;
	if ( function_exists( 'ttseo_bing_call' ) && ttseo_opt( 'bing_apikey' ) ) {
		$b = ttseo_bing_call( 'GetRankAndTrafficStats' );
		if ( ! is_wp_error( $b ) ) {
			foreach ( (array) $b as $r ) {
				$bc += (int) ( $r['Clicks'] ?? 0 );
				$bi += (int) ( $r['Impressions'] ?? 0 );
			}
		}
	}

	global $wpdb;
	$table       = ttseo_kpi_snapshot_table();
	$existing_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $table WHERE period=%s", $period ) );
	$data        = array(
		'period'           => $period,
		'captured_at'      => current_time( 'mysql' ),
		'traffic_sessions' => $traffic,
		'gsc_clicks'       => $clicks,
		'gsc_impressions'  => $imp,
		'avg_position'     => $avgpos,
		'top20'            => $top[20],
		'top10'            => $top[10],
		'top5'             => $top[5],
		'top3'             => $top[3],
		'bing_clicks'      => $bc,
		'bing_impressions' => $bi,
		'keywords_json'    => wp_json_encode( $kw_detail ),
		'source'           => $source,
	);
	if ( $existing_id ) {
		$wpdb->update( $table, $data, array( 'id' => $existing_id ) );
	} else {
		$wpdb->insert( $table, $data );
	}
	return true;
}

/* Cron: chụp mỗi tuần để tích lũy dữ liệu — không đánh giá bằng 1 lần tra cứu thủ công đơn lẻ. */
add_filter( 'cron_schedules', function ( $s ) {
	if ( ! isset( $s['ttseo_weekly'] ) ) {
		$s['ttseo_weekly'] = array( 'interval' => 7 * DAY_IN_SECONDS, 'display' => ttseo_t( 'Mỗi tuần (SEO KPI snapshot)', 'Weekly (SEO KPI snapshot)' ) );
	}
	return $s;
} );
add_action( 'init', function () {
	if ( ! wp_next_scheduled( 'ttseo_kpi_snapshot_cron' ) ) {
		wp_schedule_event( time(), 'ttseo_weekly', 'ttseo_kpi_snapshot_cron' );
	}
} );
add_action( 'ttseo_kpi_snapshot_cron', function () {
	ttseo_kpi_capture_snapshot( gmdate( 'Y-m' ), 'auto' );
} );

/* Nút chụp thủ công */
add_action( 'admin_init', function () {
	if ( ! ttseo_access() || ! function_exists( 'ttseo_is_unlocked' ) || ! ttseo_is_unlocked() ) {
		return;
	}
	if ( isset( $_GET['ttseo_kpi_snapshot'] ) && check_admin_referer( 'ttseo_kpi_snapshot' ) ) {
		ttseo_kpi_capture_snapshot( gmdate( 'Y-m' ), 'manual' );
		wp_safe_redirect( admin_url( 'admin.php?page=ttseo-kpi&snapshotted=1' ) );
		exit;
	}
} );

/* =========================================================================
 * TIỆN ÍCH ĐỐI CHIẾU
 * ========================================================================= */
/** Tháng thứ mấy trong dự án (1 = tháng bắt đầu), theo start_month đã cấu hình. */
function ttseo_kpi_month_index( $start_month, $period = null ) {
	if ( ! $start_month || ! preg_match( '/^\d{4}-\d{2}$/', $start_month ) ) {
		return null;
	}
	$period = $period ?: gmdate( 'Y-m' );
	if ( ! preg_match( '/^\d{4}-\d{2}$/', $period ) ) {
		return null;
	}
	list( $sy, $sm ) = array_map( 'intval', explode( '-', $start_month ) );
	list( $py, $pm ) = array_map( 'intval', explode( '-', $period ) );
	$idx = ( $py - $sy ) * 12 + ( $pm - $sm ) + 1;
	return $idx >= 1 ? $idx : null;
}
/** Mục tiêu tháng, kẹp về mốc 7-8 (ổn định) nếu vượt tháng 8. */
function ttseo_kpi_target_for_index( $idx ) {
	$targets = ttseo_kpi_targets();
	$key     = max( 1, min( 8, (int) $idx ) );
	return $targets[ $key ] ?? $targets[8];
}
function ttseo_kpi_verdict_row( $b, $target, $traffic, $top ) {
	$traffic_goal = $b ? round( $b * $target[0] / 100 ) : null;
	$ok_traffic   = ( null !== $traffic_goal ) ? ( $traffic >= $traffic_goal ) : null;
	$ok_top20     = $top[20] >= $target[1];
	$ok_top10     = $top[10] >= $target[2];
	$ok_top5      = $top[5] >= $target[3];
	$ok_top3      = $top[3] >= $target[4];
	$checks       = array_filter( array( $ok_traffic, $ok_top20, $ok_top10, $ok_top5, $ok_top3 ), function ( $v ) { return null !== $v; } );
	if ( empty( $checks ) ) {
		return array( 'label' => ttseo_t( 'Chưa đủ dữ liệu', 'Not enough data' ), 'color' => '#8a8f94' );
	}
	$pass = count( array_filter( $checks ) );
	$total = count( $checks );
	if ( $pass === $total ) {
		return array( 'label' => ttseo_t( 'Đạt KPI', 'KPI met' ), 'color' => '#1a7f5a' );
	}
	if ( $pass > 0 ) {
		return array( 'label' => $pass . '/' . $total . ' ' . ttseo_t( 'tiêu chí đạt', 'criteria met' ), 'color' => '#c77d16' );
	}
	return array( 'label' => ttseo_t( 'Chưa đạt', 'Not met' ), 'color' => '#c0392b' );
}

/* =========================================================================
 * TIẾN ĐỘ SẢN XUẤT NỘI DUNG THEO THÁNG (nguồn: bài đã Xuất bản thật)
 * ========================================================================= */
function ttseo_kpi_content_progress( $months = 8 ) {
	global $wpdb;
	$table = ttseo_wf_table();
	$rows  = $wpdb->get_results( "SELECT period, status, post_id FROM $table WHERE type='content'" );
	$by_period = array();
	foreach ( $rows as $r ) {
		if ( ! isset( $by_period[ $r->period ] ) ) {
			$by_period[ $r->period ] = array( 'published' => 0, 'approved' => 0, 'submitted' => 0, 'total' => 0 );
		}
		$by_period[ $r->period ]['total']++;
		$status = $r->status;
		// Đối chiếu với post_status thật của WordPress — tránh lệch số liệu nếu ai đó
		// đổi trạng thái bài trực tiếp trong Trình soạn bài (Posts) mà không qua nút
		// Xuất bản/Duyệt của phân hệ Soạn & Duyệt bài SEO.
		if ( $r->post_id ) {
			$real = get_post_status( $r->post_id );
			if ( 'publish' === $real ) {
				$status = 'published';
			} elseif ( 'published' === $status && 'publish' !== $real ) {
				// Ghi nhận là published trong log nhưng bài thực tế không còn publish → không tính là bằng chứng đã xuất bản.
				$status = ( 'pending' === $real ) ? 'submitted' : ( 'draft' === $real ? 'draft' : $status );
			}
		}
		if ( in_array( $status, array( 'published', 'approved', 'submitted' ), true ) ) {
			$by_period[ $r->period ][ $status ]++;
		}
	}
	krsort( $by_period );
	return $by_period;
}

/* =========================================================================
 * RENDER — chèn thêm vào trang KPI (gọi từ ttseo_render_kpi() trong workflow.php)
 * ========================================================================= */
function ttseo_render_kpi_evidence() {
	global $wpdb;
	$kpi         = get_option( 'ttseo_kpi', array() );
	$b           = (float) ( $kpi['baseline_b'] ?? 0 );
	$start_month = $kpi['start_month'] ?? '';
	$cur_period  = gmdate( 'Y-m' );
	$cur_idx     = ttseo_kpi_month_index( $start_month, $cur_period );

	$snap_table = ttseo_kpi_snapshot_table();
	$snapshots  = $wpdb->get_results( "SELECT * FROM $snap_table ORDER BY period DESC" );

	/* ---------- Nút chụp + trạng thái tháng hiện tại ---------- */
	echo '<h2 class="ttseo-sec" style="--b:#1a7f5a;">📸 ' . esc_html( ttseo_t( 'Bằng chứng KPI theo mốc báo cáo', 'KPI evidence by report period' ) ) . '</h2>';
	echo '<p class="ttseo-subtle">' . esc_html( ttseo_t( 'Dữ liệu GSC/GA4/Bing được tự động chụp mỗi tuần và lưu lại theo từng tháng — dùng để đối chiếu nghiệm thu, không đánh giá bằng một lần tra cứu thủ công đơn lẻ.', 'GSC/GA4/Bing data is automatically captured every week and archived per month — used for sign-off, rather than relying on a single manual lookup.' ) ) . '</p>';
	$snap_url = wp_nonce_url( admin_url( 'admin.php?page=ttseo-kpi&ttseo_kpi_snapshot=1' ), 'ttseo_kpi_snapshot' );
	echo '<p><a href="' . esc_url( $snap_url ) . '" class="button">📸 ' . esc_html( ttseo_t( 'Chụp snapshot KPI ngay (tháng', 'Capture KPI snapshot now (month' ) ) . ' ' . esc_html( $cur_period ) . ')</a></p>';
	if ( isset( $_GET['snapshotted'] ) ) {
		echo '<div class="notice notice-success is-dismissible"><p>' . esc_html( ttseo_t( 'Đã chụp snapshot KPI cho tháng', 'KPI snapshot captured for' ) ) . ' ' . esc_html( $cur_period ) . '.</p></div>';
	}

	if ( null !== $cur_idx ) {
		$target = ttseo_kpi_target_for_index( $cur_idx );
		$cur    = current( array_filter( $snapshots, function ( $s ) use ( $cur_period ) { return $s->period === $cur_period; } ) );
		$top    = $cur ? array( 20 => (int) $cur->top20, 10 => (int) $cur->top10, 5 => (int) $cur->top5, 3 => (int) $cur->top3 ) : array( 20 => 0, 10 => 0, 5 => 0, 3 => 0 );
		$traffic = $cur ? (int) $cur->traffic_sessions : 0;
		$verdict = ttseo_kpi_verdict_row( $b, $target, $traffic, $top );
		echo '<div class="ttseo-strip">';
		ttseo_kpi( ttseo_t( 'Đang ở', 'Currently at' ), ttseo_t( 'Tháng', 'Month' ) . ' ' . $cur_idx . '/8', ttseo_t( 'theo mốc bắt đầu', 'from start month' ) . ' ' . esc_html( $start_month ?: '—' ), '#1f5c93' );
		ttseo_kpi( ttseo_t( 'Đánh giá tháng hiện tại', 'Current month assessment' ), $verdict['label'], $cur ? 'snapshot ' . esc_html( mysql2date( 'd/m H:i', $cur->captured_at ) ) : esc_html( ttseo_t( 'chưa có snapshot tháng này', 'no snapshot yet this month' ) ), $verdict['color'] );
		echo '</div>';
	} else {
		echo '<p class="ttseo-subtle">' . esc_html( ttseo_t( 'Chưa đặt "Tháng bắt đầu" ở khung cấu hình bên dưới nên chưa xác định được đang ở tháng thứ mấy trong kế hoạch.', '"Start month" hasn\'t been set in the configuration below, so the current month within the plan can\'t be determined yet.' ) ) . '</p>';
	}

	/* ---------- Nhật ký snapshot (dữ liệu chứng minh, không đổi ngược thời gian) ---------- */
	if ( $snapshots ) {
		echo '<h3>' . esc_html( ttseo_t( 'Nhật ký Snapshot KPI theo tháng', 'Monthly KPI snapshot log' ) ) . '</h3>';
		echo '<div class="ttseo-table"><table><thead><tr><th>' . esc_html( ttseo_t( 'Kỳ', 'Period' ) ) . '</th><th>' . esc_html( ttseo_t( 'Ngày chụp', 'Captured' ) ) . '</th><th>Traffic (GA4)</th><th>%B</th><th>GSC Clicks</th><th>' . esc_html( ttseo_t( 'Vị trí TB 20 từ khóa', 'Avg. position, 20 keywords' ) ) . '</th><th>Top20</th><th>Top10</th><th>Top5</th><th>Top3</th><th>Bing Clicks</th><th>' . esc_html( ttseo_t( 'Đánh giá', 'Assessment' ) ) . '</th><th>' . esc_html( ttseo_t( 'Nguồn', 'Source' ) ) . '</th></tr></thead><tbody>';
		foreach ( $snapshots as $s ) {
			$idx    = ttseo_kpi_month_index( $start_month, $s->period );
			$target = ttseo_kpi_target_for_index( $idx ?: 1 );
			$top    = array( 20 => (int) $s->top20, 10 => (int) $s->top10, 5 => (int) $s->top5, 3 => (int) $s->top3 );
			$verdict = ( null !== $idx ) ? ttseo_kpi_verdict_row( $b, $target, (int) $s->traffic_sessions, $top ) : array( 'label' => '—', 'color' => '#8a8f94' );
			$pct    = ( $b > 0 ) ? round( (int) $s->traffic_sessions / $b * 100 ) . '%' : '—';
			echo '<tr><td><b>' . esc_html( $s->period ) . '</b>' . ( null !== $idx ? '<br><span style="color:#8a8f94;font-size:11px;">' . esc_html( ttseo_t( 'Tháng', 'Month' ) ) . ' ' . (int) $idx . '</span>' : '' ) . '</td>';
			echo '<td style="font-size:11px;color:#8a8f94;">' . esc_html( mysql2date( 'd/m/Y H:i', $s->captured_at ) ) . '</td>';
			echo '<td>' . ttseo_num( $s->traffic_sessions ) . '</td>';
			echo '<td>' . esc_html( $pct ) . '</td>';
			echo '<td>' . ttseo_num( $s->gsc_clicks ) . '</td>';
			echo '<td>' . ( $s->avg_position > 0 ? number_format_i18n( (float) $s->avg_position, 1 ) : '—' ) . '</td>';
			echo '<td>' . (int) $s->top20 . '</td><td>' . (int) $s->top10 . '</td><td>' . (int) $s->top5 . '</td><td>' . (int) $s->top3 . '</td>';
			echo '<td>' . ttseo_num( $s->bing_clicks ) . '</td>';
			echo '<td><span style="color:' . esc_attr( $verdict['color'] ) . ';font-weight:700;font-size:12px;">' . esc_html( $verdict['label'] ) . '</span></td>';
			echo '<td style="font-size:11px;color:#8a8f94;">' . esc_html( 'manual' === $s->source ? ttseo_t( 'thủ công', 'manual' ) : ttseo_t( 'tự động', 'automatic' ) ) . '</td>';
			echo '</tr>';
		}
		echo '</tbody></table></div>';
	} else {
		echo '<p class="ttseo-subtle">' . esc_html( ttseo_t( 'Chưa có snapshot nào. Bấm nút "Chụp snapshot KPI ngay" ở trên, hoặc chờ tự động chụp vào tuần tới.', 'No snapshots yet. Click "Capture KPI snapshot now" above, or wait for the automatic capture next week.' ) ) . '</p>';
	}

	/* ---------- Tiến độ đăng bài SEO theo tháng (nguồn: bài đã publish thật) ---------- */
	echo '<h2 class="ttseo-sec" style="--b:#c77d16;">🗂️ ' . esc_html( ttseo_t( 'Tiến độ đăng bài SEO theo tháng (Content Production)', 'Monthly SEO content production progress' ) ) . '</h2>';
	echo '<p class="ttseo-subtle">' . esc_html( ttseo_t( 'Chỉ tiêu hợp đồng: 10 nội dung/tháng. Đếm bài có trạng thái "Đã xuất bản" (đã publish thật trên website) hoặc "Đã duyệt" (chờ xuất bản) trong phân hệ Soạn & Duyệt bài SEO.', 'Contracted quota: 10 pieces/month. Counts posts with status "Published" (actually live on the site) or "Approved" (pending publish) in the SEO Content & Approval module.' ) ) . '</p>';
	$prog = ttseo_kpi_content_progress();
	if ( $prog ) {
		echo '<div class="ttseo-table"><table><thead><tr><th>' . esc_html( ttseo_t( 'Kỳ', 'Period' ) ) . '</th><th>' . esc_html( ttseo_t( 'Đã xuất bản', 'Published' ) ) . '</th><th>' . esc_html( ttseo_t( 'Đã duyệt (chờ xuất bản)', 'Approved (pending publish)' ) ) . '</th><th>' . esc_html( ttseo_t( 'Chờ duyệt', 'Pending review' ) ) . '</th><th>' . esc_html( ttseo_t( 'Tổng đã lên kế hoạch', 'Total planned' ) ) . '</th><th>' . esc_html( ttseo_t( 'Đạt chỉ tiêu 10 bài?', 'Meets 10-post quota?' ) ) . '</th></tr></thead><tbody>';
		foreach ( $prog as $period => $p ) {
			$ok = $p['published'] >= 10;
			echo '<tr><td><b>' . esc_html( $period ) . '</b>' . ( $period === $cur_period ? ' <span style="color:#1f5c93;font-size:11px;">(' . esc_html( ttseo_t( 'tháng này', 'this month' ) ) . ')</span>' : '' ) . '</td>';
			echo '<td style="color:#1f5c93;font-weight:700;">' . (int) $p['published'] . '</td>';
			echo '<td>' . (int) $p['approved'] . '</td>';
			echo '<td>' . (int) $p['submitted'] . '</td>';
			echo '<td>' . (int) $p['total'] . '</td>';
			echo '<td><span style="color:' . ( $ok ? '#1a7f5a' : '#c77d16' ) . ';font-weight:700;">' . ( $ok ? '✔ ' . esc_html( ttseo_t( 'Đạt', 'Met' ) ) : $p['published'] . '/10' ) . '</span></td>';
			echo '</tr>';
		}
		echo '</tbody></table></div>';
	} else {
		echo '<p class="ttseo-subtle">' . esc_html( ttseo_t( 'Chưa có bài viết nào trong phân hệ Soạn & Duyệt bài SEO.', 'No posts yet in the SEO Content & Approval module.' ) ) . '</p>';
	}

	/* ---------- Nghiệm thu hạng mục khác (On-page / Indexation / Authority) ---------- */
	if ( function_exists( 'ttseo_wf_items' ) ) {
		echo '<h2 class="ttseo-sec" style="--b:#6b3fb5;">✅ ' . esc_html( ttseo_t( 'Nghiệm thu hạng mục khác tháng', 'Other categories sign-off — month' ) ) . ' ' . esc_html( gmdate( 'm/Y' ) ) . '</h2>';
		echo '<div class="ttseo-strip">';
		foreach ( array( 'onpage', 'authority' ) as $t ) {
			$types = ttseo_wf_types();
			$cfg   = $types[ $t ];
			$items = ttseo_wf_items( $t, $cur_period );
			$done  = 0;
			foreach ( $items as $it ) {
				if ( in_array( $it->status, $cfg['done'], true ) ) {
					$done++;
				}
			}
			ttseo_kpi( $cfg['label'], $done . '/' . $cfg['quota'], $cfg['unit'], $done >= $cfg['quota'] ? '#1a7f5a' : '#c77d16' );
		}
		echo '</div>';
		echo '<p class="ttseo-subtle">' . esc_html( ttseo_t( 'Chi tiết & cập nhật trạng thái tại', 'Details & status updates in' ) ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=ttseo-work' ) ) . '">' . esc_html( ttseo_t( 'Công việc SEO', 'SEO Work' ) ) . '</a>.</p>';
	}
}
