<?php
/**
 * This file is part of the Wisewand WordPress plugin.
 *
 * @package Wisewand
 * @since 1.0.0
 * @license GPL-2.0-or-later
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
namespace Wisewand\RSS;

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Wisewand\Logging\Logger;
use Wisewand\Utils\Options;
use Wisewand\Utils\Wisewand_API_Client;
use Wisewand\Content\Content_Manager;
use Wisewand\Calendar\Calendar_Entry_Manager;

// phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_error_log -- error_log() used within WP_DEBUG conditionals

class RSS_CRON {

	private $feed_manager;
	private $article_manager;
	private $sync_engine;
	private $logger;
	private $options;

	public function __construct(
		Options $options,
		Logger $logger,
		Content_Manager $content_manager,
		Calendar_Entry_Manager $calendar_manager
	) {
		$this->options = $options;
		$this->logger  = $logger;

		// Initialize API client
		$api_client = new Wisewand_API_Client( $this->options->get( 'wisewand_api_key' ), $logger );

		// Initialize managers
		$this->feed_manager    = new RSS_Feed_Manager( $logger );
		$this->article_manager = new RSS_Article_Manager( $logger );

		// Initialize RSS Calendar Bridge for calendar integration
		$calendar_bridge = new RSS_Calendar_Bridge(
			$calendar_manager,
			$this->article_manager,
			$this->feed_manager,
			$logger
		);

		// Initialize sync engine with calendar integration
		$this->sync_engine = new RSS_Sync_Engine(
			$api_client,
			$this->feed_manager,
			$this->article_manager,
			$content_manager,
			$calendar_manager,
			$calendar_bridge,
			$logger,
			$options
		);
	}

	/**
	 * Main CRON job: Sync all active feeds (v2.3.0 simplified)
	 * Runs according to global import frequency via WordPress CRON
	 *
	 * @since 1.0.0
	 */
	public function run() {
		if ( WP_DEBUG ) {
			error_log( '=== RSS_CRON: Starting RSS feeds sync (v2.3.0) ===' );
		}

		$this->logger->info( 'RSS CRON job started' );

		$summary = array(
			'feeds_checked'       => 0,
			'feeds_synced'        => 0,
			'articles_discovered' => 0,
			'articles_imported'   => 0,
			'articles_failed'     => 0,
			'start_time'          => current_time( 'mysql' ),
			'errors'              => array(),
		);

		try {
			// v2.3.0: Get ALL active feeds (ignore next_sync_at scheduling)
			$feeds_due = $this->feed_manager->get_all_active_feeds();

			$summary['feeds_checked'] = count( $feeds_due );

			if ( WP_DEBUG ) {
				error_log( "RSS_CRON: Found {$summary['feeds_checked']} feeds due for sync" );
			}

			if ( empty( $feeds_due ) ) {
				$this->logger->info( 'No feeds due for sync' );
				if ( WP_DEBUG ) {
					error_log( 'RSS_CRON: No feeds due for sync, exiting' );
				}
				return $summary;
			}

			// Process each feed
			foreach ( $feeds_due as $feed ) {
				if ( WP_DEBUG ) {
					error_log( "RSS_CRON: Processing feed '{$feed['feed_name']}' (ID: {$feed['id']})" );
				}

				// v2.3.0: No per-feed schedule checking - sync ALL active feeds every CRON run
				// Sync the feed
				$result = $this->sync_engine->sync_feed( $feed['id'], false );

				if ( is_wp_error( $result ) ) {
					$summary['errors'][] = sprintf(
						/* translators: 1: Feed name, 2: Error message */
						__( 'Feed "%1$s": %2$s', 'wisewand-ai-content-writer-seo-content-generator' ),
						$feed['feed_name'],
						$result->get_error_message()
					);
					continue;
				}

				++$summary['feeds_synced'];
				$summary['articles_discovered'] += $result['articles_discovered'] ?? 0;
				$summary['articles_imported']   += $result['articles_imported'] ?? 0;
				$summary['articles_failed']     += $result['articles_failed'] ?? 0;
			}

			$summary['end_time'] = current_time( 'mysql' );

			$this->logger->info( 'RSS CRON job completed', $summary );

			if ( WP_DEBUG ) {
				error_log( "RSS_CRON: Completed - {$summary['feeds_synced']} feeds synced, {$summary['articles_imported']} articles imported" );
			}
		} catch ( \Exception $e ) {
			$this->logger->error(
				'RSS CRON job failed',
				array(
					'error' => $e->getMessage(),
					'trace' => $e->getTraceAsString(),
				)
			);

			$summary['errors'][] = $e->getMessage();

			if ( WP_DEBUG ) {
				error_log( 'RSS_CRON: Exception - ' . $e->getMessage() );
			}
		}

		// Store summary in option for dashboard display
		update_option( 'wisewand_rss_last_cron_summary', wp_json_encode( $summary ) );

		return $summary;
	}

	/**
	 * Check if it's the right time to sync this feed based on schedule settings
	 *
	 * @deprecated 2.3.0 No longer used - unified sync system syncs all active feeds
	 * @param array $feed Feed data
	 * @return bool True if should sync now
	 */
	private function is_sync_time_for_feed( $feed ) {
		$schedule_type = $feed['import_schedule_type'] ?? 'every_6_hours';

		// Hourly and high-frequency schedules always sync when due (next_sync_at check already done)
		if ( in_array( $schedule_type, array( 'every_5_minutes', 'every_30_minutes', 'hourly', 'every_6_hours' ), true ) ) {
			return true;
		}

		// Daily: Check time and day of week
		if ( $schedule_type === 'daily' ) {
			return $this->check_daily_schedule( $feed );
		}

		// Custom: Always sync when due
		return true;
	}

	/**
	 * Check if current time matches daily schedule settings
	 *
	 * @deprecated 2.3.0 No longer used - unified sync system syncs all active feeds
	 * @param array $feed Feed data
	 * @return bool True if should sync now
	 */
	private function check_daily_schedule( $feed ) {
		$schedule_time = $feed['import_schedule_time'];
		$schedule_days = $feed['import_schedule_days'];

		$current_hour = (int) current_time( 'H' );
		$current_day  = (int) current_time( 'N' ); // 1=Monday, 7=Sunday

		// Check day of week
		if ( ! empty( $schedule_days ) ) {
			$allowed_days = array_map( 'intval', explode( ',', $schedule_days ) );
			if ( ! in_array( $current_day, $allowed_days, true ) ) {
				return false; // Wrong day
			}
		}

		// Check hour/minute matching
		// We rely primarily on next_sync_at in the database query (get_feeds_due_for_sync)
		// But as a secondary check, we ensure we haven't missed the window completely.
		// Since CRON runs hourly or faster, if next_sync_at is passed, we should run.
		
		// The previous logic checked for +/- 1 hour window. 
		// With precise scheduling, we just need to know if current time >= schedule time.
		// Detailed check is redundant if next_sync_at is calculated correctly.
		
		return true;
	}

	/**
	 * Manual sync trigger (for "Sync Now" button)
	 *
	 * @param int $feed_id Feed ID
	 * @return array|WP_Error Sync results
	 */
	public function manual_sync_feed( $feed_id ) {
		if ( WP_DEBUG ) {
			error_log( "RSS_CRON: Manual sync triggered for feed {$feed_id}" );
		}

		return $this->sync_engine->sync_feed( $feed_id, true );
	}

	/**
	 * Phase 1: Discover new articles for ALL enabled feeds
	 * REMOVED in v2.3.0 - Unified sync system
	 *
	 * @since 2.2.0
	 * @deprecated 2.3.0 Use run() instead
	 * @return array Summary of discovery phase
	 */
	public function run_article_discovery() {
		// v2.3.0: Redirect to unified sync method
		return $this->run();
	}

	/**
	 * Phase 2: Import discovered articles based on schedules
	 * REMOVED in v2.3.0 - Unified sync system
	 *
	 * @since 2.2.0
	 * @deprecated 2.3.0 Use run() instead
	 * @return array Summary of import phase
	 */
	public function run_article_import() {
		// v2.3.0: Redirect to unified sync method
		return $this->run();
	}

	/**
	 * Get all enabled feeds regardless of schedule
	 *
	 * @since 2.2.0
	 * @deprecated 2.3.0 No longer used - use feed_manager->get_all_active_feeds() instead
	 * @return array Array of feed data
	 */
	private function get_all_enabled_feeds() {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table query required.
		$feeds = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT id, feed_name, wisewand_feed_id FROM %i WHERE sync_status = %s",
				$wpdb->prefix . 'wisewand_rss_feeds',
				'active'
			),
			ARRAY_A
		);

		return $feeds ? $feeds : array();
	}

	/**
	 * Cleanup old failed articles (maintenance task)
	 * Should be called weekly
	 */
	public function cleanup_old_articles() {
		$this->logger->info( 'Starting RSS articles cleanup' );

		$cleanup_stats = $this->article_manager->cleanup_old_articles();

		// Log cleanup results for monitoring.
		if ( WP_DEBUG ) {
			error_log(
				sprintf(
					'RSS_CLEANUP: Daily cleanup completed - Failed: %d, Deleted: %d, Ungenerated: %d',
					$cleanup_stats['failed_deleted'],
					$cleanup_stats['deleted_removed'],
					$cleanup_stats['ungenerated_removed']
				)
			);
		}

		$this->logger->info(
			'RSS articles cleanup completed',
			array(
				'failed_deleted'      => $cleanup_stats['failed_deleted'],
				'deleted_removed'     => $cleanup_stats['deleted_removed'],
				'ungenerated_removed' => $cleanup_stats['ungenerated_removed'],
			)
		);

		return $cleanup_stats;
	}
}
