<?php
/**
 * WordPress Dashboard widget showing latest TTSWP changelog and news.
 *
 * Pulls a combined JSON feed from ttswp.com (cached 12h via transient).
 * Failures fall back to the cached payload when available; otherwise the
 * widget renders an empty-state with a link to ttswp.com so it never
 * breaks the dashboard.
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Mementor_TTS_Dashboard_Widget {

	const WIDGET_ID    = 'mementor_tts_news_widget';
	const TRANSIENT    = 'mementor_tts_dashboard_feed';
	const FEED_URL     = 'https://ttswp.com/api/plugin/dashboard';
	const CACHE_TTL    = 12 * HOUR_IN_SECONDS;
	const HTTP_TIMEOUT = 5;

	private static $instance = null;

	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	public function register() {
		add_action( 'wp_dashboard_setup', array( $this, 'add_widget' ) );
	}

	public function add_widget() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		wp_add_dashboard_widget(
			self::WIDGET_ID,
			__( 'Text to Speech &mdash; TTSWP Latest', 'text-to-speech-tts' ),
			array( $this, 'render' )
		);
	}

	public function render() {
		$feed = $this->get_feed();

		if ( empty( $feed ) ) {
			$this->render_empty_state();
			return;
		}

		$this->render_styles();
		?>
		<div class="mementor-tts-dash">
			<?php $this->render_changelog( $feed ); ?>
			<?php $this->render_news( $feed ); ?>
			<?php $this->render_footer( $feed ); ?>
		</div>
		<?php
	}

	private function render_changelog( array $feed ) {
		$changelog = isset( $feed['changelog'] ) ? $feed['changelog'] : null;
		if ( empty( $changelog ) || empty( $changelog['entries'] ) ) {
			return;
		}

		$version       = isset( $changelog['version'] ) ? $changelog['version'] : '';
		$released_at   = isset( $changelog['released_at'] ) ? $changelog['released_at'] : '';
		$changelog_url = isset( $feed['links']['changelog'] ) ? $feed['links']['changelog'] : 'https://ttswp.com/docs/changelog';
		?>
		<section class="mementor-tts-dash__section">
			<h3 class="mementor-tts-dash__heading">
				<?php esc_html_e( 'Latest release', 'text-to-speech-tts' ); ?>
				<?php if ( $version ) : ?>
					<a href="<?php echo esc_url( $changelog_url ); ?>" target="_blank" rel="noopener" class="mementor-tts-dash__version">
						v<?php echo esc_html( $version ); ?>
						<?php if ( $released_at ) : ?>
							<span class="mementor-tts-dash__date">&middot; <?php echo esc_html( $this->format_date( $released_at ) ); ?></span>
						<?php endif; ?>
					</a>
				<?php endif; ?>
			</h3>
			<ul class="mementor-tts-dash__changes">
				<?php foreach ( array_slice( $changelog['entries'], 0, 5 ) as $entry ) : ?>
					<?php $type = isset( $entry['type'] ) ? strtoupper( (string) $entry['type'] ) : 'IMPROVED'; ?>
					<li>
						<span class="mementor-tts-dash__tag mementor-tts-dash__tag--<?php echo esc_attr( strtolower( $type ) ); ?>">
							<?php echo esc_html( $type ); ?>
						</span>
						<span class="mementor-tts-dash__change-text">
							<?php echo esc_html( isset( $entry['description'] ) ? $entry['description'] : '' ); ?>
						</span>
					</li>
				<?php endforeach; ?>
			</ul>
		</section>
		<?php
	}

	private function render_news( array $feed ) {
		$news = isset( $feed['news'] ) ? $feed['news'] : array();
		if ( empty( $news ) ) {
			return;
		}
		?>
		<section class="mementor-tts-dash__section">
			<h3 class="mementor-tts-dash__heading"><?php esc_html_e( 'From the blog', 'text-to-speech-tts' ); ?></h3>
			<ul class="mementor-tts-dash__news">
				<?php foreach ( $news as $item ) : ?>
					<li class="mementor-tts-dash__news-item">
						<?php if ( ! empty( $item['image_url'] ) ) : ?>
							<a href="<?php echo esc_url( $item['url'] ); ?>" target="_blank" rel="noopener" class="mementor-tts-dash__news-thumb">
								<img src="<?php echo esc_url( $item['image_url'] ); ?>" alt="" loading="lazy" />
							</a>
						<?php endif; ?>
						<div class="mementor-tts-dash__news-body">
							<a href="<?php echo esc_url( $item['url'] ); ?>" target="_blank" rel="noopener" class="mementor-tts-dash__news-title">
								<?php echo esc_html( isset( $item['title'] ) ? $item['title'] : '' ); ?>
							</a>
							<?php if ( ! empty( $item['excerpt'] ) ) : ?>
								<p class="mementor-tts-dash__news-excerpt">
									<?php echo esc_html( $item['excerpt'] ); ?>
								</p>
							<?php endif; ?>
							<?php if ( ! empty( $item['published_at'] ) ) : ?>
								<span class="mementor-tts-dash__news-date">
									<?php echo esc_html( $this->format_date( $item['published_at'] ) ); ?>
								</span>
							<?php endif; ?>
						</div>
					</li>
				<?php endforeach; ?>
			</ul>
		</section>
		<?php
	}

	private function render_footer( array $feed ) {
		$blog_url      = isset( $feed['links']['blog'] ) ? $feed['links']['blog'] : 'https://ttswp.com/blog';
		$changelog_url = isset( $feed['links']['changelog'] ) ? $feed['links']['changelog'] : 'https://ttswp.com/docs/changelog';
		?>
		<div class="mementor-tts-dash__footer">
			<a href="<?php echo esc_url( $changelog_url ); ?>" target="_blank" rel="noopener">
				<?php esc_html_e( 'Full changelog', 'text-to-speech-tts' ); ?>
			</a>
			<span aria-hidden="true">&middot;</span>
			<a href="<?php echo esc_url( $blog_url ); ?>" target="_blank" rel="noopener">
				<?php esc_html_e( 'All news', 'text-to-speech-tts' ); ?>
			</a>
		</div>
		<?php
	}

	private function render_empty_state() {
		?>
		<p>
			<?php esc_html_e( 'Could not load the latest TTSWP updates right now.', 'text-to-speech-tts' ); ?>
			<a href="https://ttswp.com/blog" target="_blank" rel="noopener">
				<?php esc_html_e( 'Visit the blog', 'text-to-speech-tts' ); ?>
			</a>
		</p>
		<?php
	}

	private function get_feed() {
		$cached = get_transient( self::TRANSIENT );
		if ( is_array( $cached ) && ! empty( $cached ) ) {
			return $cached;
		}

		$response = wp_remote_get(
			self::FEED_URL,
			array(
				'timeout' => self::HTTP_TIMEOUT,
				'headers' => array(
					'Accept' => 'application/json',
				),
			)
		);

		if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) {
			// Cache an empty array briefly so we don't hammer ttswp.com on every dashboard load while it's down.
			set_transient( self::TRANSIENT, array(), 5 * MINUTE_IN_SECONDS );
			return array();
		}

		$body = wp_remote_retrieve_body( $response );
		$data = json_decode( $body, true );

		if ( ! is_array( $data ) ) {
			set_transient( self::TRANSIENT, array(), 5 * MINUTE_IN_SECONDS );
			return array();
		}

		set_transient( self::TRANSIENT, $data, self::CACHE_TTL );
		return $data;
	}

	private function format_date( $iso_date ) {
		$ts = strtotime( (string) $iso_date );
		if ( ! $ts ) {
			return (string) $iso_date;
		}
		return date_i18n( get_option( 'date_format', 'M j, Y' ), $ts );
	}

	private function render_styles() {
		static $printed = false;
		if ( $printed ) {
			return;
		}
		$printed = true;
		?>
		<style>
			.mementor-tts-dash { font-size: 13px; line-height: 1.5; }
			.mementor-tts-dash__section + .mementor-tts-dash__section { margin-top: 18px; padding-top: 16px; border-top: 1px solid #f0f0f1; }
			.mementor-tts-dash__heading {
				font-size: 12px;
				font-weight: 600;
				text-transform: uppercase;
				letter-spacing: 0.04em;
				color: #50575e;
				margin: 0 0 10px;
				display: flex;
				align-items: baseline;
				gap: 8px;
				flex-wrap: wrap;
			}
			.mementor-tts-dash__version { font-weight: 500; text-transform: none; letter-spacing: 0; color: #2271b1; text-decoration: none; font-size: 12px; }
			.mementor-tts-dash__version:hover { text-decoration: underline; }
			.mementor-tts-dash__date { color: #646970; font-weight: 400; }
			.mementor-tts-dash__changes { margin: 0; padding: 0; list-style: none; }
			.mementor-tts-dash__changes li { display: flex; gap: 8px; padding: 4px 0; align-items: flex-start; }
			.mementor-tts-dash__tag {
				flex: 0 0 auto;
				display: inline-block;
				font-size: 10px;
				font-weight: 700;
				letter-spacing: 0.04em;
				padding: 2px 6px;
				border-radius: 3px;
				background: #f0f0f1;
				color: #50575e;
				min-width: 64px;
				text-align: center;
			}
			.mementor-tts-dash__tag--new { background: #d1eddd; color: #14532d; }
			.mementor-tts-dash__tag--improved { background: #dbeafe; color: #1e3a8a; }
			.mementor-tts-dash__tag--fixed { background: #fde68a; color: #78350f; }
			.mementor-tts-dash__tag--developer { background: #ede9fe; color: #4c1d95; }
			.mementor-tts-dash__change-text { color: #1d2327; }
			.mementor-tts-dash__news { margin: 0; padding: 0; list-style: none; }
			.mementor-tts-dash__news-item { display: flex; gap: 12px; padding: 8px 0; }
			.mementor-tts-dash__news-item + .mementor-tts-dash__news-item { border-top: 1px solid #f6f7f7; }
			.mementor-tts-dash__news-thumb { flex: 0 0 72px; display: block; }
			.mementor-tts-dash__news-thumb img { width: 72px; height: 54px; object-fit: cover; border-radius: 4px; display: block; }
			.mementor-tts-dash__news-body { flex: 1 1 auto; min-width: 0; }
			.mementor-tts-dash__news-title { display: block; font-weight: 600; color: #1d2327; text-decoration: none; line-height: 1.35; }
			.mementor-tts-dash__news-title:hover { color: #2271b1; }
			.mementor-tts-dash__news-excerpt { margin: 4px 0 2px; color: #50575e; }
			.mementor-tts-dash__news-date { font-size: 11px; color: #646970; }
			.mementor-tts-dash__footer { margin-top: 14px; padding-top: 10px; border-top: 1px solid #f0f0f1; font-size: 12px; color: #646970; display: flex; gap: 8px; }
			.mementor-tts-dash__footer a { color: #2271b1; text-decoration: none; }
			.mementor-tts-dash__footer a:hover { text-decoration: underline; }
		</style>
		<?php
	}
}
