<?php
/**
 * This file is part of the Wisewand WordPress plugin.
 *
 * @package Wisewand
 * @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.
 */

/**
 * Migration 022: Fix Internal Links Status
 *
 * Fixes any existing "immediate" values in internal_links_wp_status settings
 * to the correct "publish" value.
 *
 * @package Wisewand
 * @subpackage Database\Migrations
 * @since 2.4.2
 */

namespace Wisewand\Database\Migrations;

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

/**
 * Migration 022 Class
 *
 * @since 2.4.2
 */
class Migration_022_Fix_Internal_Links_Status {

	/**
	 * Run the migration
	 *
	 * @param \wpdb $wpdb WordPress database instance.
	 * @return bool True on success, false on failure.
	 */
	public static function up( $wpdb ) {
		global $wpdb;

		// Fix the default internal links wp status setting
		$current_value = get_option( 'wisewand_default_internal_links_wp_status', array( 'publish' ) );

		// If it's not an array, convert to array
		if ( ! is_array( $current_value ) ) {
			$current_value = array( $current_value );
		}

		// Replace "immediate" with "publish"
		$fixed_value = array_map(
			function ( $status ) {
				return 'immediate' === $status ? 'publish' : $status;
			},
			$current_value
		);

		// Remove duplicates and reindex
		$fixed_value = array_values( array_unique( $fixed_value ) );

		// Validate against allowed statuses
		$allowed_statuses = array( 'publish', 'draft', 'future' );
		$fixed_value      = array_intersect( $fixed_value, $allowed_statuses );

		// If empty after validation, default to 'publish'
		if ( empty( $fixed_value ) ) {
			$fixed_value = array( 'publish' );
		}

		// Update the option
		update_option( 'wisewand_default_internal_links_wp_status', $fixed_value );

		// Log migration for options
		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
			error_log(
				sprintf(
					'Wisewand Migration 022: Fixed internal_links_wp_status option from %s to %s',
					wp_json_encode( $current_value ),
					wp_json_encode( $fixed_value )
				)
			);
		}

		// Fix calendar entry payloads (CRITICAL for Entry ID 1 and others)
		$calendar_table = $wpdb->prefix . 'wisewand_editorial_calendar';

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Custom plugin table query for migration
		$entries = $wpdb->get_results(
			"SELECT id, wisewand_payload FROM {$calendar_table} WHERE wisewand_payload IS NOT NULL",
			ARRAY_A
		);

		$payloads_fixed = 0;
		$wpdb->query( 'START TRANSACTION' );

		foreach ( $entries as $entry ) {
			$payload = json_decode( $entry['wisewand_payload'], true );

			if ( ! is_array( $payload ) ) {
				continue; // Skip invalid payloads
			}

			$needs_update = false;

			// Fix 1: Replace 'immediate' with 'publish' in internal_links_wp_status
			if ( isset( $payload['internal_links_wp_status'] ) && is_array( $payload['internal_links_wp_status'] ) ) {
				foreach ( $payload['internal_links_wp_status'] as $index => $status ) {
					if ( 'immediate' === $status ) {
						$payload['internal_links_wp_status'][ $index ] = 'publish';
						$needs_update                                   = true;
					}
				}
			}

			// Fix 2: Reset hardcoded false internal links flags
			// These were set to false in old code but should be omitted
			if ( isset( $payload['use_wp_internal_links'] ) && false === $payload['use_wp_internal_links'] ) {
				unset( $payload['use_wp_internal_links'] );
				$needs_update = true;
			}
			if ( isset( $payload['use_app_internal_links'] ) && false === $payload['use_app_internal_links'] ) {
				unset( $payload['use_app_internal_links'] );
				$needs_update = true;
			}
			if ( isset( $payload['use_list_internal_links'] ) && false === $payload['use_list_internal_links'] ) {
				unset( $payload['use_list_internal_links'] );
				$needs_update = true;
			}

			if ( $needs_update ) {
				// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Migration update
				$wpdb->update(
					$calendar_table,
					array( 'wisewand_payload' => wp_json_encode( $payload ) ),
					array( 'id' => $entry['id'] ),
					array( '%s' ),
					array( '%d' )
				);

				if ( $wpdb->last_error ) {
					$wpdb->query( 'ROLLBACK' );
					if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
						error_log( 'Wisewand Migration 022: ' . $wpdb->last_error );
					}
					return false;
				}

				++$payloads_fixed;
			}
		}

		$wpdb->query( 'COMMIT' );

		// Log calendar payload fixes
		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
			error_log(
				sprintf(
					'Wisewand Migration 022: Fixed %d calendar entry payloads (total entries checked: %d)',
					$payloads_fixed,
					count( $entries )
				)
			);
		}

		return true;
	}

	/**
	 * Rollback the migration
	 *
	 * This migration cannot be rolled back as we don't want to restore
	 * the invalid "immediate" value.
	 *
	 * @param \wpdb $wpdb WordPress database instance.
	 * @return bool Always returns true (no-op).
	 */
	public static function down( $wpdb ) {
		// Cannot roll back - fixing invalid data
		// Log that rollback was attempted
		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
			error_log( 'Wisewand Migration 022: Rollback skipped (data correction migration)' );
		}

		return true;
	}
}
