<?php
/**
 * Settings manager. Single wp_option store with versioned schema + SMTP password encryption.
 *
 * @package SuiteMkt3k
 */

namespace SuiteMkt3k\Modules\Settings;

use SuiteMkt3k\Security\Capabilities;
use SuiteMkt3k\Security\Encryption;
use SuiteMkt3k\Security\Nonces;
use SuiteMkt3k\Utils\I18n;
use SuiteMkt3k\Utils\Logger;
use SuiteMkt3k\Utils\Sanitizer;
use SuiteMkt3k\Utils\Validator;

defined( 'ABSPATH' ) || exit;

final class Settings_Manager {

	public const OPTION = 'suitemkt3k_settings';

	public static function register(): void {
		add_action( 'admin_post_suitemkt3k_save_settings', array( __CLASS__, 'handle_save' ) );
		add_action( 'admin_post_suitemkt3k_test_smtp', array( __CLASS__, 'handle_test_smtp' ) );
		add_action( 'admin_post_suitemkt3k_switch_language', array( __CLASS__, 'handle_switch_language' ) );
	}

	public static function get_locale(): string {
		return (string) self::get( 'language', 'default', 'es_ES' );
	}

	public static function handle_switch_language(): void {
		Capabilities::ensure( Capabilities::MANAGE );
		check_admin_referer( 'suitemkt3k_switch_language' );

		$locale = Sanitizer::post( 'locale', 'text' );
		if ( '' === $locale ) {
			$locale = 'es_ES';
		}
		if ( ! I18n::is_supported( $locale ) ) {
			$locale = 'es_ES';
		}

		$all = self::all();
		$all['language']            = is_array( $all['language'] ?? null ) ? $all['language'] : array();
		$all['language']['default'] = $locale;
		update_option( self::OPTION, $all, false );
		wp_cache_delete( self::OPTION, 'options' );
		wp_cache_delete( 'alloptions', 'options' );

		I18n::reset_runtime_cache();
		I18n::load_textdomain();

		Logger::info( 'settings', 'Language switched from sidebar', array( 'locale' => $locale ) );

		$fallback = admin_url( 'admin.php?page=suitemkt3k' );
		$referer  = wp_get_referer();
		$target   = $referer ? wp_validate_redirect( $referer, false ) : false;
		if ( $target ) {
			$path = (string) wp_parse_url( $target, PHP_URL_PATH );
			if ( false === strpos( $path, '/wp-admin' ) ) {
				$target = false;
			}
		}
		wp_safe_redirect( $target ?: $fallback );
		exit;
	}

	public static function get( string $section, string $key = '', $default = null ) {
		$all = (array) get_option( self::OPTION, array() );
		if ( ! isset( $all[ $section ] ) ) {
			return $default;
		}
		if ( '' === $key ) {
			return $all[ $section ];
		}
		return $all[ $section ][ $key ] ?? $default;
	}

	public static function all(): array {
		return (array) get_option( self::OPTION, array() );
	}

	/**
	 * Returns the settings array prepared for display (masking SMTP password).
	 */
	public static function all_for_display(): array {
		$all = self::all();
		if ( isset( $all['smtp']['password'] ) && '' !== $all['smtp']['password'] ) {
			$plain = Encryption::decrypt( (string) $all['smtp']['password'] );
			$all['smtp']['password'] = Encryption::mask( $plain );
			$all['smtp']['has_password'] = true;
		} else {
			$all['smtp']['has_password'] = false;
			$all['smtp']['password'] = '';
		}
		return $all;
	}

	public static function handle_save(): void {
		Capabilities::ensure( Capabilities::EDIT_SETTINGS );
		check_admin_referer( Nonces::ADMIN_ACTION, '_wpnonce' );
		$post = static function ( string $key, $default = '' ) {
			$value = Sanitizer::post( $key, 'text' );
			return '' !== $value ? $value : $default;
		};

		$tab = Sanitizer::post( 'tab', 'key' );
		if ( '' === $tab ) {
			$tab = 'company';
		}
		$current = self::all();

		switch ( $tab ) {
			case 'company':
				$current['company'] = array(
					'name'     => Sanitizer::text( $post( 'name', '' ), 190 ),
					'email'    => Sanitizer::email( $post( 'email', '' ) ),
					'reply_to' => Sanitizer::email( $post( 'reply_to', '' ) ),
					'logo_id'  => Sanitizer::int( $post( 'logo_id', 0 ), 0 ),
					'address'  => Sanitizer::textarea( $post( 'address', '' ), 500 ),
					'website'  => Sanitizer::url( $post( 'website', '' ) ),
					'phone'    => Sanitizer::text( $post( 'phone', '' ), 60 ),
				);
				break;
			case 'coupons':
				$current['coupons'] = array(
					'default_bg'   => Sanitizer::hex_color( $post( 'default_bg', '#2AB2E5' ) ) ?: '#2AB2E5',
					'default_text' => Sanitizer::hex_color( $post( 'default_text', '#FFFFFF' ) ) ?: '#FFFFFF',
					'popup_delay'  => Sanitizer::int( $post( 'popup_delay', 4 ), 0, 60 ),
					'cookie_days'  => Sanitizer::int( $post( 'cookie_days', 7 ), 1, 365 ),
				);
				break;
			case 'newsletter':
				$current['newsletter'] = array(
					'batch_size'     => Sanitizer::int( $post( 'batch_size', 50 ), 1, 500 ),
					'batch_interval' => Sanitizer::int( $post( 'batch_interval', 60 ), 30, 3600 ),
					'default_footer' => Sanitizer::textarea( $post( 'default_footer', '' ), 1000 ),
				);
				break;
			case 'subscribers':
				$current['subscribers'] = array(
					'unsubscribe_success' => Sanitizer::textarea( $post( 'unsubscribe_success', '' ), 2000 ),
					'unsubscribe_already' => Sanitizer::textarea( $post( 'unsubscribe_already', '' ), 2000 ),
				);
				break;
			case 'cart':
				// Preserve recovery_coupon_id (now edited from the template editor).
				$preserved_coupon = (int) ( $current['cart']['recovery_coupon_id'] ?? 0 );
				$current['cart'] = array(
					'auto_send_enabled'  => Sanitizer::bool( $post( 'auto_send_enabled', false ) ),
					'auto_send_hours'    => Sanitizer::int( $post( 'auto_send_hours', 1 ), 1, 168 ),
					'purge_days'         => Sanitizer::int( $post( 'purge_days', 30 ), 7, 365 ),
					'recovery_coupon_id' => $preserved_coupon,
				);
				break;
			case 'smtp':
				$encryption = Sanitizer::post( 'encryption', 'key' );
				if ( '' === $encryption ) {
					$encryption = 'tls';
				}
				if ( ! Validator::is_in( $encryption, array( 'none', 'ssl', 'tls' ) ) ) {
					$encryption = 'tls';
				}
				$new_password = (string) $post( 'password', '' );
				$existing_password = $current['smtp']['password'] ?? '';
				if ( '' === $new_password || self::is_mask( $new_password ) ) {
					$password_to_store = $existing_password;
				} else {
					$password_to_store = Encryption::encrypt( $new_password );
				}
				$current['smtp'] = array(
					'enabled'    => Sanitizer::bool( $post( 'enabled', false ) ),
					'host'       => Sanitizer::text( $post( 'host', '' ), 190 ),
					'port'       => Sanitizer::int( $post( 'port', 587 ), 1, 65535 ),
					'encryption' => $encryption,
					'auth'       => Sanitizer::bool( $post( 'auth', false ) ),
					'username'   => Sanitizer::text( $post( 'username', '' ), 190 ),
					'password'   => $password_to_store,
					'from_email' => Sanitizer::email( $post( 'from_email', '' ) ),
					'from_name'  => Sanitizer::text( $post( 'from_name', '' ), 190 ),
				);
				break;
			case 'language':
				$locale = Sanitizer::post( 'default_locale', 'text' );
				if ( '' === $locale ) {
					$locale = 'es_ES';
				}
				$current['language'] = array(
					'default' => I18n::is_supported( $locale ) ? $locale : 'es_ES',
				);
				break;
			case 'backup':
				$current['backup'] = array(
					'auto_enabled'  => Sanitizer::bool( $post( 'auto_enabled', false ) ),
					'interval_days' => Sanitizer::int( $post( 'interval_days', 7 ), 1, 90 ),
				);
				break;
			case 'advanced':
				$current['advanced'] = array(
					'enable_logs'             => Sanitizer::bool( $post( 'enable_logs', true ) ),
					'enable_pixel'            => Sanitizer::bool( $post( 'enable_pixel', true ) ),
					'enable_clicks'           => Sanitizer::bool( $post( 'enable_clicks', true ) ),
					'enable_cart_icon_count'  => Sanitizer::bool( $post( 'enable_cart_icon_count', false ) ),
				);
				break;
		}

		update_option( self::OPTION, $current, false );
		Logger::info( 'settings', 'Tab saved: ' . $tab );

		wp_safe_redirect( add_query_arg( array( 'tab' => $tab, 'updated' => '1' ), admin_url( 'admin.php?page=suitemkt3k-settings' ) ) );
		exit;
	}

	public static function handle_test_smtp(): void {
		Capabilities::ensure( Capabilities::EDIT_SETTINGS );
		check_admin_referer( Nonces::ADMIN_ACTION, '_wpnonce' );

		$to = Sanitizer::email( Sanitizer::post( 'test_email', 'email' ) );
		if ( '' === $to ) {
			$to = (string) ( self::get( 'company', 'email' ) ?: get_option( 'admin_email' ) );
		}
		if ( '' === $to ) {
			wp_safe_redirect( add_query_arg( array( 'tab' => 'smtp', 'test' => 'invalid' ), admin_url( 'admin.php?page=suitemkt3k-settings' ) ) );
			exit;
		}

		$mailer = new \SuiteMkt3k\Email\Mailer();
		$ok     = $mailer->send_test( $to );

		wp_safe_redirect( add_query_arg( array( 'tab' => 'smtp', 'test' => $ok ? 'sent' : 'failed' ), admin_url( 'admin.php?page=suitemkt3k-settings' ) ) );
		exit;
	}

	private static function is_mask( string $value ): bool {
		return (bool) preg_match( '/^\*+/', $value );
	}
}
